* gcc.dg/c11-complex-1.c: Use dg-add-options ieee.
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob44aecfbebf6a440b7b8325fa89c3e781399fa4b8
1 /* Translation of CLAST (CLooG AST) to Gimple.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
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"
23 #ifdef HAVE_cloog
24 #include <isl/set.h>
25 #include <isl/map.h>
26 #include <isl/union_map.h>
27 #include <isl/list.h>
28 #include <isl/constraint.h>
29 #include <isl/ilp.h>
30 #include <isl/aff.h>
31 #include <cloog/cloog.h>
32 #include <cloog/isl/domain.h>
33 #endif
35 #include "system.h"
36 #include "coretypes.h"
37 #include "diagnostic-core.h"
38 #include "tree.h"
39 #include "gimple.h"
40 #include "gimple-iterator.h"
41 #include "gimplify-me.h"
42 #include "gimple-ssa.h"
43 #include "tree-ssa-loop-manip.h"
44 #include "tree-ssa-loop.h"
45 #include "tree-into-ssa.h"
46 #include "tree-pass.h"
47 #include "cfgloop.h"
48 #include "tree-chrec.h"
49 #include "tree-data-ref.h"
50 #include "tree-scalar-evolution.h"
51 #include "sese.h"
53 #ifdef HAVE_cloog
54 #include "cloog/cloog.h"
55 #include "graphite-poly.h"
56 #include "graphite-clast-to-gimple.h"
57 #include "graphite-htab.h"
59 typedef const struct clast_expr *clast_name_p;
61 #ifndef CLOOG_LANGUAGE_C
62 #define CLOOG_LANGUAGE_C LANGUAGE_C
63 #endif
66 /* Converts a GMP constant VAL to a tree and returns it. */
68 static tree
69 gmp_cst_to_tree (tree type, mpz_t val)
71 tree t = type ? type : integer_type_node;
72 mpz_t tmp;
73 double_int di;
75 mpz_init (tmp);
76 mpz_set (tmp, val);
77 di = mpz_get_double_int (t, tmp, true);
78 mpz_clear (tmp);
80 return double_int_to_tree (t, di);
83 /* Sets RES to the min of V1 and V2. */
85 static void
86 value_min (mpz_t res, mpz_t v1, mpz_t v2)
88 if (mpz_cmp (v1, v2) < 0)
89 mpz_set (res, v1);
90 else
91 mpz_set (res, v2);
94 /* Sets RES to the max of V1 and V2. */
96 static void
97 value_max (mpz_t res, mpz_t v1, mpz_t v2)
99 if (mpz_cmp (v1, v2) < 0)
100 mpz_set (res, v2);
101 else
102 mpz_set (res, v1);
106 /* This flag is set when an error occurred during the translation of
107 CLAST to Gimple. */
108 static bool gloog_error;
110 /* Verifies properties that GRAPHITE should maintain during translation. */
112 static inline void
113 graphite_verify (void)
115 #ifdef ENABLE_CHECKING
116 verify_loop_structure ();
117 verify_loop_closed_ssa (true);
118 #endif
121 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
122 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
123 upper bounds that can be inferred from the polyhedral representation. */
125 typedef struct clast_name_index {
126 int index;
127 int level;
128 mpz_t bound_one, bound_two;
129 const char *name;
130 /* If free_name is set, the content of name was allocated by us and needs
131 to be freed. */
132 char *free_name;
133 } *clast_name_index_p;
135 /* Helper for hashing clast_name_index. */
137 struct clast_index_hasher
139 typedef clast_name_index value_type;
140 typedef clast_name_index compare_type;
141 static inline hashval_t hash (const value_type *);
142 static inline bool equal (const value_type *, const compare_type *);
143 static inline void remove (value_type *);
146 /* Computes a hash function for database element E. */
148 inline hashval_t
149 clast_index_hasher::hash (const value_type *e)
151 hashval_t hash = 0;
153 int length = strlen (e->name);
154 int i;
156 for (i = 0; i < length; ++i)
157 hash = hash | (e->name[i] << (i % 4));
159 return hash;
162 /* Compares database elements ELT1 and ELT2. */
164 inline bool
165 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
167 return strcmp (elt1->name, elt2->name) == 0;
170 /* Free the memory taken by a clast_name_index struct. */
172 inline void
173 clast_index_hasher::remove (value_type *c)
175 if (c->free_name)
176 free (c->free_name);
177 mpz_clear (c->bound_one);
178 mpz_clear (c->bound_two);
179 free (c);
182 typedef hash_table <clast_index_hasher> clast_index_htab_type;
184 /* Returns a pointer to a new element of type clast_name_index_p built
185 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
187 static inline clast_name_index_p
188 new_clast_name_index (const char *name, int index, int level,
189 mpz_t bound_one, mpz_t bound_two)
191 clast_name_index_p res = XNEW (struct clast_name_index);
192 char *new_name = XNEWVEC (char, strlen (name) + 1);
193 strcpy (new_name, name);
195 res->name = new_name;
196 res->free_name = new_name;
197 res->level = level;
198 res->index = index;
199 mpz_init (res->bound_one);
200 mpz_init (res->bound_two);
201 mpz_set (res->bound_one, bound_one);
202 mpz_set (res->bound_two, bound_two);
203 return res;
206 /* For a given clast NAME, returns -1 if NAME is not in the
207 INDEX_TABLE, otherwise returns the loop level for the induction
208 variable NAME, or if it is a parameter, the parameter number in the
209 vector of parameters. */
211 static inline int
212 clast_name_to_level (clast_name_p name, clast_index_htab_type index_table)
214 struct clast_name_index tmp;
215 clast_name_index **slot;
217 gcc_assert (name->type == clast_expr_name);
218 tmp.name = ((const struct clast_name *) name)->name;
219 tmp.free_name = NULL;
221 slot = index_table.find_slot (&tmp, NO_INSERT);
223 if (slot && *slot)
224 return ((struct clast_name_index *) *slot)->level;
226 return -1;
229 /* For a given clast NAME, returns -1 if it does not correspond to any
230 parameter, or otherwise, returns the index in the PARAMS or
231 SCATTERING_DIMENSIONS vector. */
233 static inline int
234 clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table)
236 struct clast_name_index tmp;
237 clast_name_index **slot;
239 tmp.name = ((const struct clast_name *) name)->name;
240 tmp.free_name = NULL;
242 slot = index_table.find_slot (&tmp, NO_INSERT);
244 if (slot && *slot)
245 return (*slot)->index;
247 return -1;
250 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
251 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
252 found in the INDEX_TABLE, false otherwise. */
254 static inline bool
255 clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table,
256 mpz_t bound_one, mpz_t bound_two)
258 struct clast_name_index tmp;
259 clast_name_index **slot;
261 tmp.name = name->name;
262 tmp.free_name = NULL;
264 slot = index_table.find_slot (&tmp, NO_INSERT);
266 if (slot && *slot)
268 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
269 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
270 return true;
273 return false;
276 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
278 static inline void
279 save_clast_name_index (clast_index_htab_type index_table, const char *name,
280 int index, int level, mpz_t bound_one, mpz_t bound_two)
282 struct clast_name_index tmp;
283 clast_name_index **slot;
285 tmp.name = name;
286 tmp.free_name = NULL;
287 slot = index_table.find_slot (&tmp, INSERT);
289 if (slot)
291 free (*slot);
293 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
298 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
299 induction variable in NEWIVS.
301 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
302 parameter in PARAMS. */
304 typedef struct ivs_params {
305 vec<tree> params, *newivs;
306 clast_index_htab_type newivs_index, params_index;
307 sese region;
308 } *ivs_params_p;
310 /* Returns the tree variable from the name NAME that was given in
311 Cloog representation. */
313 static tree
314 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
316 int index;
318 if (ip->params.exists () && ip->params_index.is_created ())
320 index = clast_name_to_index (name, ip->params_index);
322 if (index >= 0)
323 return ip->params[index];
326 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
327 index = clast_name_to_index (name, ip->newivs_index);
328 gcc_assert (index >= 0);
330 return (*ip->newivs)[index];
333 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
335 static tree
336 max_precision_type (tree type1, tree type2)
338 enum machine_mode mode;
339 int p1, p2, precision;
340 tree type;
342 if (POINTER_TYPE_P (type1))
343 return type1;
345 if (POINTER_TYPE_P (type2))
346 return type2;
348 if (TYPE_UNSIGNED (type1)
349 && TYPE_UNSIGNED (type2))
350 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
352 p1 = TYPE_PRECISION (type1);
353 p2 = TYPE_PRECISION (type2);
355 if (p1 > p2)
356 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
357 else
358 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
360 if (precision > BITS_PER_WORD)
362 gloog_error = true;
363 return integer_type_node;
366 mode = smallest_mode_for_size (precision, MODE_INT);
367 precision = GET_MODE_PRECISION (mode);
368 type = build_nonstandard_integer_type (precision, false);
370 if (!type)
372 gloog_error = true;
373 return integer_type_node;
376 return type;
379 static tree
380 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
382 /* Converts a Cloog reduction expression R with reduction operation OP
383 to a GCC expression tree of type TYPE. */
385 static tree
386 clast_to_gcc_expression_red (tree type, enum tree_code op,
387 struct clast_reduction *r, ivs_params_p ip)
389 int i;
390 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
391 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
393 for (i = 1; i < r->n; i++)
395 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
396 res = fold_build2 (op, type, res, t);
399 return res;
402 /* Converts a Cloog AST expression E back to a GCC expression tree of
403 type TYPE. */
405 static tree
406 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
408 switch (e->type)
410 case clast_expr_name:
412 return clast_name_to_gcc ((struct clast_name *) e, ip);
414 case clast_expr_term:
416 struct clast_term *t = (struct clast_term *) e;
418 if (t->var)
420 if (mpz_cmp_si (t->val, 1) == 0)
422 tree name = clast_to_gcc_expression (type, t->var, ip);
424 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
425 name = convert_to_ptrofftype (name);
427 name = fold_convert (type, name);
428 return name;
431 else if (mpz_cmp_si (t->val, -1) == 0)
433 tree name = clast_to_gcc_expression (type, t->var, ip);
435 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
436 name = convert_to_ptrofftype (name);
438 name = fold_convert (type, name);
440 return fold_build1 (NEGATE_EXPR, type, name);
442 else
444 tree name = clast_to_gcc_expression (type, t->var, ip);
445 tree cst = gmp_cst_to_tree (type, t->val);
447 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
448 name = convert_to_ptrofftype (name);
450 name = fold_convert (type, name);
452 if (!POINTER_TYPE_P (type))
453 return fold_build2 (MULT_EXPR, type, cst, name);
455 gloog_error = true;
456 return cst;
459 else
460 return gmp_cst_to_tree (type, t->val);
463 case clast_expr_red:
465 struct clast_reduction *r = (struct clast_reduction *) e;
467 switch (r->type)
469 case clast_red_sum:
470 return clast_to_gcc_expression_red
471 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
472 r, ip);
474 case clast_red_min:
475 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
477 case clast_red_max:
478 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
480 default:
481 gcc_unreachable ();
483 break;
486 case clast_expr_bin:
488 struct clast_binary *b = (struct clast_binary *) e;
489 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
490 tree tl = clast_to_gcc_expression (type, lhs, ip);
491 tree tr = gmp_cst_to_tree (type, b->RHS);
493 switch (b->type)
495 case clast_bin_fdiv:
496 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
498 case clast_bin_cdiv:
499 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
501 case clast_bin_div:
502 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
504 case clast_bin_mod:
505 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
507 default:
508 gcc_unreachable ();
512 default:
513 gcc_unreachable ();
516 return NULL_TREE;
519 /* Return a type that could represent the values between BOUND_ONE and
520 BOUND_TWO. */
522 static tree
523 type_for_interval (mpz_t bound_one, mpz_t bound_two)
525 bool unsigned_p;
526 tree type;
527 enum machine_mode mode;
528 int wider_precision;
529 int precision = MAX (mpz_sizeinbase (bound_one, 2),
530 mpz_sizeinbase (bound_two, 2));
532 if (precision > BITS_PER_WORD)
534 gloog_error = true;
535 return integer_type_node;
538 if (mpz_cmp (bound_one, bound_two) <= 0)
539 unsigned_p = (mpz_sgn (bound_one) >= 0);
540 else
541 unsigned_p = (mpz_sgn (bound_two) >= 0);
543 mode = smallest_mode_for_size (precision, MODE_INT);
544 wider_precision = GET_MODE_PRECISION (mode);
546 /* As we want to generate signed types as much as possible, try to
547 fit the interval [bound_one, bound_two] in a signed type. For example,
548 supposing that we have the interval [0, 100], instead of
549 generating unsigned char, we want to generate a signed char. */
550 if (unsigned_p && precision < wider_precision)
551 unsigned_p = false;
553 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
555 if (!type)
557 gloog_error = true;
558 return integer_type_node;
561 return type;
564 /* Return a type that could represent the integer value VAL, or
565 otherwise return NULL_TREE. */
567 static tree
568 type_for_value (mpz_t val)
570 return type_for_interval (val, val);
573 static tree
574 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
576 /* Return the type for the clast_term T. Initializes BOUND_ONE and
577 BOUND_TWO to the bounds of the term. */
579 static tree
580 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
581 mpz_t bound_two)
583 tree type;
584 gcc_assert (t->expr.type == clast_expr_term);
586 if (!t->var)
588 mpz_set (bound_one, t->val);
589 mpz_set (bound_two, t->val);
590 return type_for_value (t->val);
593 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
595 mpz_mul (bound_one, bound_one, t->val);
596 mpz_mul (bound_two, bound_two, t->val);
598 return max_precision_type (type, type_for_interval (bound_one, bound_two));
601 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
602 and BOUND_TWO to the bounds of the reduction expression. */
604 static tree
605 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
606 mpz_t bound_one, mpz_t bound_two)
608 int i;
609 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
610 mpz_t b1, b2, m1, m2;
612 if (r->n == 1)
613 return type;
615 mpz_init (b1);
616 mpz_init (b2);
617 mpz_init (m1);
618 mpz_init (m2);
620 for (i = 1; i < r->n; i++)
622 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
623 type = max_precision_type (type, t);
625 switch (r->type)
627 case clast_red_sum:
628 value_min (m1, bound_one, bound_two);
629 value_min (m2, b1, b2);
630 mpz_add (bound_one, m1, m2);
632 value_max (m1, bound_one, bound_two);
633 value_max (m2, b1, b2);
634 mpz_add (bound_two, m1, m2);
635 break;
637 case clast_red_min:
638 value_min (bound_one, bound_one, bound_two);
639 value_min (bound_two, b1, b2);
640 break;
642 case clast_red_max:
643 value_max (bound_one, bound_one, bound_two);
644 value_max (bound_two, b1, b2);
645 break;
647 default:
648 gcc_unreachable ();
649 break;
653 mpz_clear (b1);
654 mpz_clear (b2);
655 mpz_clear (m1);
656 mpz_clear (m2);
658 /* Return a type that can represent the result of the reduction. */
659 return max_precision_type (type, type_for_interval (bound_one, bound_two));
662 /* Return the type for the clast_binary B used in STMT. */
664 static tree
665 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
666 mpz_t bound_two)
668 mpz_t one;
669 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
670 bound_one, bound_two);
671 tree r = type_for_value (b->RHS);
672 tree type = max_precision_type (l, r);
674 switch (b->type)
676 case clast_bin_fdiv:
677 mpz_mdiv (bound_one, bound_one, b->RHS);
678 mpz_mdiv (bound_two, bound_two, b->RHS);
679 break;
681 case clast_bin_cdiv:
682 mpz_mdiv (bound_one, bound_one, b->RHS);
683 mpz_mdiv (bound_two, bound_two, b->RHS);
684 mpz_init (one);
685 mpz_add (bound_one, bound_one, one);
686 mpz_add (bound_two, bound_two, one);
687 mpz_clear (one);
688 break;
690 case clast_bin_div:
691 mpz_div (bound_one, bound_one, b->RHS);
692 mpz_div (bound_two, bound_two, b->RHS);
693 break;
695 case clast_bin_mod:
696 mpz_mod (bound_one, bound_one, b->RHS);
697 mpz_mod (bound_two, bound_two, b->RHS);
698 break;
700 default:
701 gcc_unreachable ();
704 /* Return a type that can represent the result of the reduction. */
705 return max_precision_type (type, type_for_interval (bound_one, bound_two));
708 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
709 BOUND_TWO to the bounds of the term. */
711 static tree
712 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
713 mpz_t bound_two)
715 bool found = false;
717 if (ip->params.exists () && ip->params_index.is_created ())
718 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
720 if (!found)
722 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
723 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
724 bound_two);
725 gcc_assert (found);
728 return TREE_TYPE (clast_name_to_gcc (name, ip));
731 /* Returns the type for the CLAST expression E when used in statement
732 STMT. */
734 static tree
735 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
736 mpz_t bound_two)
738 switch (e->type)
740 case clast_expr_term:
741 return type_for_clast_term ((struct clast_term *) e, ip,
742 bound_one, bound_two);
744 case clast_expr_red:
745 return type_for_clast_red ((struct clast_reduction *) e, ip,
746 bound_one, bound_two);
748 case clast_expr_bin:
749 return type_for_clast_bin ((struct clast_binary *) e, ip,
750 bound_one, bound_two);
752 case clast_expr_name:
753 return type_for_clast_name ((struct clast_name *) e, ip,
754 bound_one, bound_two);
756 default:
757 gcc_unreachable ();
760 return NULL_TREE;
763 /* Returns true if the clast expression E is a constant with VALUE. */
765 static bool
766 clast_expr_const_value_p (struct clast_expr *e, int value)
768 struct clast_term *t;
769 if (e->type != clast_expr_term)
770 return false;
771 t = (struct clast_term *)e;
772 if (t->var)
773 return false;
774 return 0 == mpz_cmp_si (t->val, value);
777 /* Translates a clast equation CLEQ to a tree. */
779 static tree
780 graphite_translate_clast_equation (struct clast_equation *cleq,
781 ivs_params_p ip)
783 enum tree_code comp;
784 tree type, lhs, rhs, ltype, rtype;
785 mpz_t bound_one, bound_two;
786 struct clast_expr *clhs, *crhs;
788 clhs = cleq->LHS;
789 crhs = cleq->RHS;
790 if (cleq->sign == 0)
791 comp = EQ_EXPR;
792 else if (cleq->sign > 0)
793 comp = GE_EXPR;
794 else
795 comp = LE_EXPR;
797 /* Special cases to reduce range of arguments to hopefully
798 don't need types with larger precision than the input. */
799 if (crhs->type == clast_expr_red
800 && comp != EQ_EXPR)
802 struct clast_reduction *r = (struct clast_reduction *) crhs;
803 /* X >= A+1 --> X > A and
804 X <= A-1 --> X < A */
805 if (r->n == 2
806 && r->type == clast_red_sum
807 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
809 crhs = r->elts[0];
810 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
814 mpz_init (bound_one);
815 mpz_init (bound_two);
817 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
818 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
820 mpz_clear (bound_one);
821 mpz_clear (bound_two);
822 type = max_precision_type (ltype, rtype);
824 lhs = clast_to_gcc_expression (type, clhs, ip);
825 rhs = clast_to_gcc_expression (type, crhs, ip);
827 return fold_build2 (comp, boolean_type_node, lhs, rhs);
830 /* Creates the test for the condition in STMT. */
832 static tree
833 graphite_create_guard_cond_expr (struct clast_guard *stmt,
834 ivs_params_p ip)
836 tree cond = NULL;
837 int i;
839 for (i = 0; i < stmt->n; i++)
841 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
843 if (cond)
844 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
845 else
846 cond = eq;
849 return cond;
852 /* Creates a new if region corresponding to Cloog's guard. */
854 static edge
855 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
856 ivs_params_p ip)
858 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
859 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
860 return exit_edge;
863 /* Compute the lower bound LOW and upper bound UP for the parameter
864 PARAM in scop SCOP based on the constraints in the context. */
866 static void
867 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
869 isl_int v;
870 isl_aff *aff = isl_aff_zero_on_domain
871 (isl_local_space_from_space (isl_set_get_space (scop->context)));
873 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
875 isl_int_init (v);
876 isl_set_min (scop->context, aff, &v);
877 isl_int_get_gmp (v, low);
878 isl_set_max (scop->context, aff, &v);
879 isl_int_get_gmp (v, up);
880 isl_int_clear (v);
881 isl_aff_free (aff);
884 /* Compute the lower bound LOW and upper bound UP for the induction
885 variable of loop LOOP.
887 FIXME: This one is not entirely correct, as min/max expressions in the
888 calculation can yield to incorrect results. To be completely
889 correct, we need to evaluate each subexpression generated by
890 CLooG. CLooG does not yet support this, so this is as good as
891 it can be. */
893 static void
894 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
896 isl_set *domain;
897 isl_aff *dimension;
898 isl_local_space *local_space;
899 isl_int isl_value;
900 enum isl_lp_result lp_result;
902 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
903 local_space = isl_local_space_from_space (isl_set_get_space (domain));
904 dimension = isl_aff_zero_on_domain (local_space);
905 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
906 isl_set_dim (domain, isl_dim_set) - 1,
909 isl_int_init (isl_value);
911 lp_result = isl_set_min (domain, dimension, &isl_value);
912 assert (lp_result == isl_lp_ok);
913 isl_int_get_gmp (isl_value, low);
915 lp_result = isl_set_max (domain, dimension, &isl_value);
916 assert (lp_result == isl_lp_ok);
917 isl_int_get_gmp (isl_value, up);
919 isl_int_clear (isl_value);
920 isl_set_free (domain);
921 isl_aff_free (dimension);
924 /* Returns the type for the induction variable for the loop translated
925 from STMT_FOR. */
927 static tree
928 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
930 mpz_t bound_one, bound_two;
931 tree lb_type, ub_type;
933 mpz_init (bound_one);
934 mpz_init (bound_two);
936 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
937 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
939 mpz_clear (bound_one);
940 mpz_clear (bound_two);
942 return max_precision_type (lb_type, ub_type);
945 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
946 induction variable for the new LOOP. New LOOP is attached to CFG
947 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
948 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
949 CLooG's scattering name to the induction variable created for the
950 loop of STMT. The new induction variable is inserted in the NEWIVS
951 vector and is of type TYPE. */
953 static struct loop *
954 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
955 loop_p outer, tree type, tree lb, tree ub,
956 int level, ivs_params_p ip)
958 mpz_t low, up;
960 tree stride = gmp_cst_to_tree (type, stmt->stride);
961 tree ivvar = create_tmp_var (type, "graphite_IV");
962 tree iv, iv_after_increment;
963 loop_p loop = create_empty_loop_on_edge
964 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
965 outer ? outer : entry_edge->src->loop_father);
967 mpz_init (low);
968 mpz_init (up);
969 compute_bounds_for_loop (stmt, low, up);
970 save_clast_name_index (ip->newivs_index, stmt->iterator,
971 (*ip->newivs).length (), level, low, up);
972 mpz_clear (low);
973 mpz_clear (up);
974 (*ip->newivs).safe_push (iv);
975 return loop;
978 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
979 induction variables of the loops around GBB in SESE. */
981 static void
982 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
983 ivs_params_p ip)
985 struct clast_stmt *t;
986 int depth = 0;
987 CloogStatement *cs = user_stmt->statement;
988 poly_bb_p pbb = (poly_bb_p) cs->usr;
989 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
990 mpz_t bound_one, bound_two;
992 mpz_init (bound_one);
993 mpz_init (bound_two);
995 for (t = user_stmt->substitutions; t; t = t->next, depth++)
997 struct clast_expr *expr = (struct clast_expr *)
998 ((struct clast_assignment *)t)->RHS;
999 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1000 tree new_name = clast_to_gcc_expression (type, expr, ip);
1001 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1003 iv_map[old_loop->num] = new_name;
1006 mpz_clear (bound_one);
1007 mpz_clear (bound_two);
1010 /* Construct bb_pbb_def with BB and PBB. */
1012 static bb_pbb_def *
1013 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
1015 bb_pbb_def *bb_pbb_p;
1017 bb_pbb_p = XNEW (bb_pbb_def);
1018 bb_pbb_p->bb = bb;
1019 bb_pbb_p->pbb = pbb;
1021 return bb_pbb_p;
1024 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1026 static void
1027 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1028 bb_pbb_htab_type bb_pbb_mapping)
1030 bb_pbb_def tmp;
1031 bb_pbb_def **x;
1033 tmp.bb = bb;
1034 x = bb_pbb_mapping.find_slot (&tmp, INSERT);
1036 if (x && !*x)
1037 *x = new_bb_pbb_def (bb, pbb);
1040 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1042 poly_bb_p
1043 find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb)
1045 bb_pbb_def tmp;
1046 bb_pbb_def **slot;
1048 tmp.bb = bb;
1049 slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT);
1051 if (slot && *slot)
1052 return ((bb_pbb_def *) *slot)->pbb;
1054 return NULL;
1057 /* Return the scop of the loop and initialize PBBS the set of
1058 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1059 by the CLAST code generator between a generated basic_block and its
1060 related poly_bb_p. */
1062 scop_p
1063 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping,
1064 vec<poly_bb_p> *pbbs)
1066 unsigned i;
1067 basic_block *bbs = get_loop_body_in_dom_order (loop);
1068 scop_p scop = NULL;
1070 for (i = 0; i < loop->num_nodes; i++)
1072 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1074 if (pbb == NULL)
1075 continue;
1077 scop = PBB_SCOP (pbb);
1078 (*pbbs).safe_push (pbb);
1081 free (bbs);
1082 return scop;
1085 /* Translates a clast user statement STMT to gimple.
1087 - NEXT_E is the edge where new generated code should be attached.
1088 - CONTEXT_LOOP is the loop in which the generated code will be placed
1089 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1091 static edge
1092 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1093 bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip)
1095 int i, nb_loops;
1096 basic_block new_bb;
1097 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1098 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1099 vec<tree> iv_map;
1101 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
1102 return next_e;
1104 nb_loops = number_of_loops (cfun);
1105 iv_map.create (nb_loops);
1106 for (i = 0; i < nb_loops; i++)
1107 iv_map.quick_push (NULL_TREE);
1109 build_iv_mapping (iv_map, stmt, ip);
1110 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1111 next_e, iv_map, &gloog_error);
1112 iv_map.release ();
1114 new_bb = next_e->src;
1115 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1116 mark_virtual_operands_for_renaming (cfun);
1117 update_ssa (TODO_update_ssa);
1119 return next_e;
1122 /* Creates a new if region protecting the loop to be executed, if the execution
1123 count is zero (lb > ub). */
1125 static edge
1126 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1127 tree *type, tree *lb, tree *ub,
1128 ivs_params_p ip)
1130 tree cond_expr;
1131 edge exit_edge;
1133 *type = type_for_clast_for (stmt, ip);
1134 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1135 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1137 /* When ub is simply a constant or a parameter, use lb <= ub. */
1138 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1139 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1140 else
1142 tree one = (POINTER_TYPE_P (*type)
1143 ? convert_to_ptrofftype (integer_one_node)
1144 : fold_convert (*type, integer_one_node));
1145 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1146 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1147 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1148 even if we do not want this. However lb < ub + 1 is false, as
1149 expected. */
1150 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1151 : PLUS_EXPR, *type, *ub, one);
1153 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1156 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1158 return exit_edge;
1161 static edge
1162 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type,
1163 int, ivs_params_p);
1165 /* Create the loop for a clast for statement.
1167 - NEXT_E is the edge where new generated code should be attached.
1168 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1170 static edge
1171 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1172 edge next_e, bb_pbb_htab_type bb_pbb_mapping,
1173 int level, tree type, tree lb, tree ub,
1174 ivs_params_p ip)
1176 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1177 type, lb, ub, level, ip);
1178 edge last_e = single_exit (loop);
1179 edge to_body = single_succ_edge (loop->header);
1180 basic_block after = to_body->dest;
1182 /* Create a basic block for loop close phi nodes. */
1183 last_e = single_succ_edge (split_edge (last_e));
1185 /* Translate the body of the loop. */
1186 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1187 level + 1, ip);
1188 redirect_edge_succ_nodup (next_e, after);
1189 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1191 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1192 int scheduling_dim = isl_set_n_dim (domain);
1194 if (flag_loop_parallelize_all
1195 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1196 loop->can_be_parallel = true;
1198 return last_e;
1201 /* Translates a clast for statement STMT to gimple. First a guard is created
1202 protecting the loop, if it is executed zero times. In this guard we create
1203 the real loop structure.
1205 - NEXT_E is the edge where new generated code should be attached.
1206 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1208 static edge
1209 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1210 bb_pbb_htab_type bb_pbb_mapping, int level,
1211 ivs_params_p ip)
1213 tree type, lb, ub;
1214 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1215 &lb, &ub, ip);
1216 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1218 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1219 type, lb, ub, ip);
1220 return last_e;
1223 /* Translates a clast assignment STMT to gimple.
1225 - NEXT_E is the edge where new generated code should be attached.
1226 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1228 static edge
1229 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1230 int level, ivs_params_p ip)
1232 gimple_seq stmts;
1233 mpz_t bound_one, bound_two;
1234 tree type, new_name, var;
1235 edge res = single_succ_edge (split_edge (next_e));
1236 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1238 mpz_init (bound_one);
1239 mpz_init (bound_two);
1240 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1241 var = create_tmp_var (type, "graphite_var");
1242 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1243 &stmts, true, var);
1244 if (stmts)
1246 gsi_insert_seq_on_edge (next_e, stmts);
1247 gsi_commit_edge_inserts ();
1250 save_clast_name_index (ip->newivs_index, stmt->LHS,
1251 (*ip->newivs).length (), level,
1252 bound_one, bound_two);
1253 (*ip->newivs).safe_push (new_name);
1255 mpz_clear (bound_one);
1256 mpz_clear (bound_two);
1258 return res;
1261 /* Translates a clast guard statement STMT to gimple.
1263 - NEXT_E is the edge where new generated code should be attached.
1264 - CONTEXT_LOOP is the loop in which the generated code will be placed
1265 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1267 static edge
1268 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1269 edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level,
1270 ivs_params_p ip)
1272 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1273 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1275 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1276 return last_e;
1279 /* Translates a CLAST statement STMT to GCC representation in the
1280 context of a SESE.
1282 - NEXT_E is the edge where new generated code should be attached.
1283 - CONTEXT_LOOP is the loop in which the generated code will be placed
1284 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1286 static edge
1287 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1288 bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip)
1290 if (!stmt)
1291 return next_e;
1293 if (CLAST_STMT_IS_A (stmt, stmt_root))
1294 ; /* Do nothing. */
1296 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1297 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1298 next_e, bb_pbb_mapping, ip);
1300 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1301 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1302 next_e, bb_pbb_mapping, level, ip);
1304 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1305 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1306 next_e, bb_pbb_mapping, level, ip);
1308 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1309 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1310 next_e, bb_pbb_mapping, level, ip);
1312 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1313 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1314 next_e, level, ip);
1315 else
1316 gcc_unreachable ();
1318 recompute_all_dominators ();
1319 graphite_verify ();
1321 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1322 level, ip);
1325 /* Add parameter and iterator names to the CloogUnionDomain. */
1327 static CloogUnionDomain *
1328 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1329 int nb_scattering_dims,
1330 clast_index_htab_type params_index)
1332 sese region = SCOP_REGION (scop);
1333 int i;
1334 int nb_iterators = scop_max_loop_depth (scop);
1335 int nb_parameters = SESE_PARAMS (region).length ();
1336 mpz_t bound_one, bound_two;
1338 mpz_init (bound_one);
1339 mpz_init (bound_two);
1341 for (i = 0; i < nb_parameters; i++)
1343 tree param = SESE_PARAMS (region)[i];
1344 const char *name = get_name (param);
1345 int len;
1346 char *parameter;
1348 if (!name)
1349 name = "T";
1351 len = strlen (name);
1352 len += 17;
1353 parameter = XNEWVEC (char, len + 1);
1354 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1355 save_clast_name_index (params_index, parameter, i, i, bound_one,
1356 bound_two);
1357 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1358 parameter);
1359 compute_bounds_for_param (scop, i, bound_one, bound_two);
1360 free (parameter);
1363 mpz_clear (bound_one);
1364 mpz_clear (bound_two);
1366 for (i = 0; i < nb_iterators; i++)
1368 int len = 4 + 16;
1369 char *iterator;
1370 iterator = XNEWVEC (char, len);
1371 snprintf (iterator, len, "git_%d", i);
1372 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1373 iterator);
1374 free (iterator);
1377 for (i = 0; i < nb_scattering_dims; i++)
1379 int len = 5 + 16;
1380 char *scattering;
1381 scattering = XNEWVEC (char, len);
1382 snprintf (scattering, len, "scat_%d", i);
1383 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1384 scattering);
1385 free (scattering);
1388 return union_domain;
1391 /* Initialize a CLooG input file. */
1393 static FILE *
1394 init_cloog_input_file (int scop_number)
1396 FILE *graphite_out_file;
1397 int len = strlen (dump_base_name);
1398 char *dumpname = XNEWVEC (char, len + 25);
1399 char *s_scop_number = XNEWVEC (char, 15);
1401 memcpy (dumpname, dump_base_name, len + 1);
1402 strip_off_ending (dumpname, len);
1403 sprintf (s_scop_number, ".%d", scop_number);
1404 strcat (dumpname, s_scop_number);
1405 strcat (dumpname, ".cloog");
1406 graphite_out_file = fopen (dumpname, "w+b");
1408 if (graphite_out_file == 0)
1409 fatal_error ("can%'t open %s for writing: %m", dumpname);
1411 free (dumpname);
1413 return graphite_out_file;
1416 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1418 static
1419 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1421 int old_dims, i;
1422 isl_space *space;
1423 isl_basic_map *change_scattering;
1424 isl_map *change_scattering_map;
1426 old_dims = isl_map_dim (scattering, isl_dim_out);
1428 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1429 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1431 for (i = 0; i < old_dims; i++)
1433 isl_constraint *c;
1434 c = isl_equality_alloc
1435 (isl_local_space_from_space (isl_space_copy (space)));
1436 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1437 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1438 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1441 for (i = old_dims; i < new_dims; i++)
1443 isl_constraint *c;
1444 c = isl_equality_alloc
1445 (isl_local_space_from_space (isl_space_copy (space)));
1446 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1447 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1450 change_scattering_map = isl_map_from_basic_map (change_scattering);
1451 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1452 return isl_map_apply_range (scattering, change_scattering_map);
1455 /* Build cloog union domain for SCoP. */
1457 static CloogUnionDomain *
1458 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1460 int i;
1461 poly_bb_p pbb;
1462 CloogUnionDomain *union_domain =
1463 cloog_union_domain_alloc (scop_nb_params (scop));
1465 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1467 CloogDomain *domain;
1468 CloogScattering *scattering;
1470 /* Dead code elimination: when the domain of a PBB is empty,
1471 don't generate code for the PBB. */
1472 if (isl_set_is_empty (pbb->domain))
1473 continue;
1475 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1476 scattering = cloog_scattering_from_isl_map
1477 (extend_scattering (isl_map_copy (pbb->transformed),
1478 nb_scattering_dims));
1480 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1481 scattering, pbb);
1484 return union_domain;
1487 /* Return the options that will be used in GLOOG. */
1489 static CloogOptions *
1490 set_cloog_options (void)
1492 CloogOptions *options = cloog_options_malloc (cloog_state);
1494 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1495 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1496 we pass an incomplete program to cloog. */
1497 options->language = CLOOG_LANGUAGE_C;
1499 /* Enable complex equality spreading: removes dummy statements
1500 (assignments) in the generated code which repeats the
1501 substitution equations for statements. This is useless for
1502 GLooG. */
1503 options->esp = 1;
1505 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1506 options->quiet = 1;
1508 /* Allow cloog to build strides with a stride width different to one.
1509 This example has stride = 4:
1511 for (i = 0; i < 20; i += 4)
1512 A */
1513 options->strides = 1;
1515 /* We want the clast to provide the iteration domains of the executed loops.
1516 This allows us to derive minimal/maximal values for the induction
1517 variables. */
1518 options->save_domains = 1;
1520 /* Disable optimizations and make cloog generate source code closer to the
1521 input. This is useful for debugging, but later we want the optimized
1522 code.
1524 XXX: We can not disable optimizations, as loop blocking is not working
1525 without them. */
1526 if (0)
1528 options->f = -1;
1529 options->l = INT_MAX;
1532 return options;
1535 /* Prints STMT to STDERR. */
1537 void
1538 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1540 CloogOptions *options = set_cloog_options ();
1542 clast_pprint (file, stmt, 0, options);
1543 cloog_options_free (options);
1546 /* Prints STMT to STDERR. */
1548 DEBUG_FUNCTION void
1549 debug_clast_stmt (struct clast_stmt *stmt)
1551 print_clast_stmt (stderr, stmt);
1554 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1556 static
1557 int get_max_scattering_dimensions (scop_p scop)
1559 int i;
1560 poly_bb_p pbb;
1561 int scattering_dims = 0;
1563 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1565 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1566 if (pbb_scatt_dims > scattering_dims)
1567 scattering_dims = pbb_scatt_dims;
1570 return scattering_dims;
1573 static CloogInput *
1574 generate_cloog_input (scop_p scop, clast_index_htab_type params_index)
1576 CloogUnionDomain *union_domain;
1577 CloogInput *cloog_input;
1578 CloogDomain *context;
1579 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1581 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1582 union_domain = add_names_to_union_domain (scop, union_domain,
1583 nb_scattering_dims,
1584 params_index);
1585 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1587 cloog_input = cloog_input_alloc (context, union_domain);
1589 return cloog_input;
1592 /* Translate SCOP to a CLooG program and clast. These two
1593 representations should be freed together: a clast cannot be used
1594 without a program. */
1596 static struct clast_stmt *
1597 scop_to_clast (scop_p scop, clast_index_htab_type params_index)
1599 CloogInput *cloog_input;
1600 struct clast_stmt *clast;
1601 CloogOptions *options = set_cloog_options ();
1603 cloog_input = generate_cloog_input (scop, params_index);
1605 /* Dump a .cloog input file, if requested. This feature is only
1606 enabled in the Graphite branch. */
1607 if (0)
1609 static size_t file_scop_number = 0;
1610 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1611 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1614 clast = cloog_clast_create_from_input (cloog_input, options);
1616 cloog_options_free (options);
1617 return clast;
1620 /* Prints to FILE the code generated by CLooG for SCOP. */
1622 void
1623 print_generated_program (FILE *file, scop_p scop)
1625 CloogOptions *options = set_cloog_options ();
1626 clast_index_htab_type params_index;
1627 struct clast_stmt *clast;
1629 params_index.create (10);
1631 clast = scop_to_clast (scop, params_index);
1633 fprintf (file, " (clast: \n");
1634 clast_pprint (file, clast, 0, options);
1635 fprintf (file, " )\n");
1637 cloog_options_free (options);
1638 cloog_clast_free (clast);
1641 /* Prints to STDERR the code generated by CLooG for SCOP. */
1643 DEBUG_FUNCTION void
1644 debug_generated_program (scop_p scop)
1646 print_generated_program (stderr, scop);
1649 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1650 the given SCOP. Return true if code generation succeeded.
1651 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1654 bool
1655 gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping)
1657 stack_vec<tree, 10> newivs;
1658 loop_p context_loop;
1659 sese region = SCOP_REGION (scop);
1660 ifsese if_region = NULL;
1661 clast_index_htab_type newivs_index, params_index;
1662 struct clast_stmt *clast;
1663 struct ivs_params ip;
1665 timevar_push (TV_GRAPHITE_CODE_GEN);
1666 gloog_error = false;
1668 params_index.create (10);
1670 clast = scop_to_clast (scop, params_index);
1672 if (dump_file && (dump_flags & TDF_DETAILS))
1674 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1675 print_clast_stmt (dump_file, clast);
1676 fprintf (dump_file, "\n");
1679 recompute_all_dominators ();
1680 graphite_verify ();
1682 if_region = move_sese_in_condition (region);
1683 sese_insert_phis_for_liveouts (region,
1684 if_region->region->exit->src,
1685 if_region->false_region->exit,
1686 if_region->true_region->exit);
1687 recompute_all_dominators ();
1688 graphite_verify ();
1690 context_loop = SESE_ENTRY (region)->src->loop_father;
1691 newivs_index.create (10);
1693 ip.newivs = &newivs;
1694 ip.newivs_index = newivs_index;
1695 ip.params = SESE_PARAMS (region);
1696 ip.params_index = params_index;
1697 ip.region = region;
1699 translate_clast (context_loop, clast, if_region->true_region->entry,
1700 bb_pbb_mapping, 0, &ip);
1701 graphite_verify ();
1702 scev_reset ();
1703 recompute_all_dominators ();
1704 graphite_verify ();
1706 if (gloog_error)
1707 set_ifsese_condition (if_region, integer_zero_node);
1709 free (if_region->true_region);
1710 free (if_region->region);
1711 free (if_region);
1713 newivs_index.dispose ();
1714 params_index.dispose ();
1715 cloog_clast_free (clast);
1716 timevar_pop (TV_GRAPHITE_CODE_GEN);
1718 if (dump_file && (dump_flags & TDF_DETAILS))
1720 loop_p loop;
1721 loop_iterator li;
1722 int num_no_dependency = 0;
1724 FOR_EACH_LOOP (li, loop, 0)
1725 if (loop->can_be_parallel)
1726 num_no_dependency++;
1728 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1729 num_no_dependency);
1732 return !gloog_error;
1734 #endif