gcc-defs.exp (dg-additional-files-options): Extend regsub for dg-additional-files...
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blobec4c1d1f461fc1480ae545f0429174577943c8b1
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-ssa.h"
41 #include "tree-ssa-loop-manip.h"
42 #include "tree-ssa-loop.h"
43 #include "tree-into-ssa.h"
44 #include "tree-pass.h"
45 #include "cfgloop.h"
46 #include "tree-chrec.h"
47 #include "tree-data-ref.h"
48 #include "tree-scalar-evolution.h"
49 #include "sese.h"
51 #ifdef HAVE_cloog
52 #include "cloog/cloog.h"
53 #include "graphite-poly.h"
54 #include "graphite-clast-to-gimple.h"
55 #include "graphite-htab.h"
57 typedef const struct clast_expr *clast_name_p;
59 #ifndef CLOOG_LANGUAGE_C
60 #define CLOOG_LANGUAGE_C LANGUAGE_C
61 #endif
64 /* Converts a GMP constant VAL to a tree and returns it. */
66 static tree
67 gmp_cst_to_tree (tree type, mpz_t val)
69 tree t = type ? type : integer_type_node;
70 mpz_t tmp;
71 double_int di;
73 mpz_init (tmp);
74 mpz_set (tmp, val);
75 di = mpz_get_double_int (t, tmp, true);
76 mpz_clear (tmp);
78 return double_int_to_tree (t, di);
81 /* Sets RES to the min of V1 and V2. */
83 static void
84 value_min (mpz_t res, mpz_t v1, mpz_t v2)
86 if (mpz_cmp (v1, v2) < 0)
87 mpz_set (res, v1);
88 else
89 mpz_set (res, v2);
92 /* Sets RES to the max of V1 and V2. */
94 static void
95 value_max (mpz_t res, mpz_t v1, mpz_t v2)
97 if (mpz_cmp (v1, v2) < 0)
98 mpz_set (res, v2);
99 else
100 mpz_set (res, v1);
104 /* This flag is set when an error occurred during the translation of
105 CLAST to Gimple. */
106 static bool gloog_error;
108 /* Verifies properties that GRAPHITE should maintain during translation. */
110 static inline void
111 graphite_verify (void)
113 #ifdef ENABLE_CHECKING
114 verify_loop_structure ();
115 verify_loop_closed_ssa (true);
116 #endif
119 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
120 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
121 upper bounds that can be inferred from the polyhedral representation. */
123 typedef struct clast_name_index {
124 int index;
125 int level;
126 mpz_t bound_one, bound_two;
127 const char *name;
128 /* If free_name is set, the content of name was allocated by us and needs
129 to be freed. */
130 char *free_name;
131 } *clast_name_index_p;
133 /* Helper for hashing clast_name_index. */
135 struct clast_index_hasher
137 typedef clast_name_index value_type;
138 typedef clast_name_index compare_type;
139 static inline hashval_t hash (const value_type *);
140 static inline bool equal (const value_type *, const compare_type *);
141 static inline void remove (value_type *);
144 /* Computes a hash function for database element E. */
146 inline hashval_t
147 clast_index_hasher::hash (const value_type *e)
149 hashval_t hash = 0;
151 int length = strlen (e->name);
152 int i;
154 for (i = 0; i < length; ++i)
155 hash = hash | (e->name[i] << (i % 4));
157 return hash;
160 /* Compares database elements ELT1 and ELT2. */
162 inline bool
163 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
165 return strcmp (elt1->name, elt2->name) == 0;
168 /* Free the memory taken by a clast_name_index struct. */
170 inline void
171 clast_index_hasher::remove (value_type *c)
173 if (c->free_name)
174 free (c->free_name);
175 mpz_clear (c->bound_one);
176 mpz_clear (c->bound_two);
177 free (c);
180 typedef hash_table <clast_index_hasher> clast_index_htab_type;
182 /* Returns a pointer to a new element of type clast_name_index_p built
183 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
185 static inline clast_name_index_p
186 new_clast_name_index (const char *name, int index, int level,
187 mpz_t bound_one, mpz_t bound_two)
189 clast_name_index_p res = XNEW (struct clast_name_index);
190 char *new_name = XNEWVEC (char, strlen (name) + 1);
191 strcpy (new_name, name);
193 res->name = new_name;
194 res->free_name = new_name;
195 res->level = level;
196 res->index = index;
197 mpz_init (res->bound_one);
198 mpz_init (res->bound_two);
199 mpz_set (res->bound_one, bound_one);
200 mpz_set (res->bound_two, bound_two);
201 return res;
204 /* For a given clast NAME, returns -1 if NAME is not in the
205 INDEX_TABLE, otherwise returns the loop level for the induction
206 variable NAME, or if it is a parameter, the parameter number in the
207 vector of parameters. */
209 static inline int
210 clast_name_to_level (clast_name_p name, clast_index_htab_type index_table)
212 struct clast_name_index tmp;
213 clast_name_index **slot;
215 gcc_assert (name->type == clast_expr_name);
216 tmp.name = ((const struct clast_name *) name)->name;
217 tmp.free_name = NULL;
219 slot = index_table.find_slot (&tmp, NO_INSERT);
221 if (slot && *slot)
222 return ((struct clast_name_index *) *slot)->level;
224 return -1;
227 /* For a given clast NAME, returns -1 if it does not correspond to any
228 parameter, or otherwise, returns the index in the PARAMS or
229 SCATTERING_DIMENSIONS vector. */
231 static inline int
232 clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table)
234 struct clast_name_index tmp;
235 clast_name_index **slot;
237 tmp.name = ((const struct clast_name *) name)->name;
238 tmp.free_name = NULL;
240 slot = index_table.find_slot (&tmp, NO_INSERT);
242 if (slot && *slot)
243 return (*slot)->index;
245 return -1;
248 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
249 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
250 found in the INDEX_TABLE, false otherwise. */
252 static inline bool
253 clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table,
254 mpz_t bound_one, mpz_t bound_two)
256 struct clast_name_index tmp;
257 clast_name_index **slot;
259 tmp.name = name->name;
260 tmp.free_name = NULL;
262 slot = index_table.find_slot (&tmp, NO_INSERT);
264 if (slot && *slot)
266 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
267 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
268 return true;
271 return false;
274 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
276 static inline void
277 save_clast_name_index (clast_index_htab_type index_table, const char *name,
278 int index, int level, mpz_t bound_one, mpz_t bound_two)
280 struct clast_name_index tmp;
281 clast_name_index **slot;
283 tmp.name = name;
284 tmp.free_name = NULL;
285 slot = index_table.find_slot (&tmp, INSERT);
287 if (slot)
289 free (*slot);
291 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
296 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
297 induction variable in NEWIVS.
299 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
300 parameter in PARAMS. */
302 typedef struct ivs_params {
303 vec<tree> params, *newivs;
304 clast_index_htab_type newivs_index, params_index;
305 sese region;
306 } *ivs_params_p;
308 /* Returns the tree variable from the name NAME that was given in
309 Cloog representation. */
311 static tree
312 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
314 int index;
316 if (ip->params.exists () && ip->params_index.is_created ())
318 index = clast_name_to_index (name, ip->params_index);
320 if (index >= 0)
321 return ip->params[index];
324 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
325 index = clast_name_to_index (name, ip->newivs_index);
326 gcc_assert (index >= 0);
328 return (*ip->newivs)[index];
331 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
333 static tree
334 max_precision_type (tree type1, tree type2)
336 enum machine_mode mode;
337 int p1, p2, precision;
338 tree type;
340 if (POINTER_TYPE_P (type1))
341 return type1;
343 if (POINTER_TYPE_P (type2))
344 return type2;
346 if (TYPE_UNSIGNED (type1)
347 && TYPE_UNSIGNED (type2))
348 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
350 p1 = TYPE_PRECISION (type1);
351 p2 = TYPE_PRECISION (type2);
353 if (p1 > p2)
354 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
355 else
356 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
358 if (precision > BITS_PER_WORD)
360 gloog_error = true;
361 return integer_type_node;
364 mode = smallest_mode_for_size (precision, MODE_INT);
365 precision = GET_MODE_PRECISION (mode);
366 type = build_nonstandard_integer_type (precision, false);
368 if (!type)
370 gloog_error = true;
371 return integer_type_node;
374 return type;
377 static tree
378 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
380 /* Converts a Cloog reduction expression R with reduction operation OP
381 to a GCC expression tree of type TYPE. */
383 static tree
384 clast_to_gcc_expression_red (tree type, enum tree_code op,
385 struct clast_reduction *r, ivs_params_p ip)
387 int i;
388 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
389 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
391 for (i = 1; i < r->n; i++)
393 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
394 res = fold_build2 (op, type, res, t);
397 return res;
400 /* Converts a Cloog AST expression E back to a GCC expression tree of
401 type TYPE. */
403 static tree
404 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
406 switch (e->type)
408 case clast_expr_name:
410 return clast_name_to_gcc ((struct clast_name *) e, ip);
412 case clast_expr_term:
414 struct clast_term *t = (struct clast_term *) e;
416 if (t->var)
418 if (mpz_cmp_si (t->val, 1) == 0)
420 tree name = clast_to_gcc_expression (type, t->var, ip);
422 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
423 name = convert_to_ptrofftype (name);
425 name = fold_convert (type, name);
426 return name;
429 else if (mpz_cmp_si (t->val, -1) == 0)
431 tree name = clast_to_gcc_expression (type, t->var, ip);
433 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
434 name = convert_to_ptrofftype (name);
436 name = fold_convert (type, name);
438 return fold_build1 (NEGATE_EXPR, type, name);
440 else
442 tree name = clast_to_gcc_expression (type, t->var, ip);
443 tree cst = gmp_cst_to_tree (type, t->val);
445 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
446 name = convert_to_ptrofftype (name);
448 name = fold_convert (type, name);
450 if (!POINTER_TYPE_P (type))
451 return fold_build2 (MULT_EXPR, type, cst, name);
453 gloog_error = true;
454 return cst;
457 else
458 return gmp_cst_to_tree (type, t->val);
461 case clast_expr_red:
463 struct clast_reduction *r = (struct clast_reduction *) e;
465 switch (r->type)
467 case clast_red_sum:
468 return clast_to_gcc_expression_red
469 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
470 r, ip);
472 case clast_red_min:
473 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
475 case clast_red_max:
476 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
478 default:
479 gcc_unreachable ();
481 break;
484 case clast_expr_bin:
486 struct clast_binary *b = (struct clast_binary *) e;
487 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
488 tree tl = clast_to_gcc_expression (type, lhs, ip);
489 tree tr = gmp_cst_to_tree (type, b->RHS);
491 switch (b->type)
493 case clast_bin_fdiv:
494 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
496 case clast_bin_cdiv:
497 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
499 case clast_bin_div:
500 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
502 case clast_bin_mod:
503 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
505 default:
506 gcc_unreachable ();
510 default:
511 gcc_unreachable ();
514 return NULL_TREE;
517 /* Return a type that could represent the values between BOUND_ONE and
518 BOUND_TWO. */
520 static tree
521 type_for_interval (mpz_t bound_one, mpz_t bound_two)
523 bool unsigned_p;
524 tree type;
525 enum machine_mode mode;
526 int wider_precision;
527 int precision = MAX (mpz_sizeinbase (bound_one, 2),
528 mpz_sizeinbase (bound_two, 2));
530 if (precision > BITS_PER_WORD)
532 gloog_error = true;
533 return integer_type_node;
536 if (mpz_cmp (bound_one, bound_two) <= 0)
537 unsigned_p = (mpz_sgn (bound_one) >= 0);
538 else
539 unsigned_p = (mpz_sgn (bound_two) >= 0);
541 mode = smallest_mode_for_size (precision, MODE_INT);
542 wider_precision = GET_MODE_PRECISION (mode);
544 /* As we want to generate signed types as much as possible, try to
545 fit the interval [bound_one, bound_two] in a signed type. For example,
546 supposing that we have the interval [0, 100], instead of
547 generating unsigned char, we want to generate a signed char. */
548 if (unsigned_p && precision < wider_precision)
549 unsigned_p = false;
551 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
553 if (!type)
555 gloog_error = true;
556 return integer_type_node;
559 return type;
562 /* Return a type that could represent the integer value VAL, or
563 otherwise return NULL_TREE. */
565 static tree
566 type_for_value (mpz_t val)
568 return type_for_interval (val, val);
571 static tree
572 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
574 /* Return the type for the clast_term T. Initializes BOUND_ONE and
575 BOUND_TWO to the bounds of the term. */
577 static tree
578 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
579 mpz_t bound_two)
581 tree type;
582 gcc_assert (t->expr.type == clast_expr_term);
584 if (!t->var)
586 mpz_set (bound_one, t->val);
587 mpz_set (bound_two, t->val);
588 return type_for_value (t->val);
591 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
593 mpz_mul (bound_one, bound_one, t->val);
594 mpz_mul (bound_two, bound_two, t->val);
596 return max_precision_type (type, type_for_interval (bound_one, bound_two));
599 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
600 and BOUND_TWO to the bounds of the reduction expression. */
602 static tree
603 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
604 mpz_t bound_one, mpz_t bound_two)
606 int i;
607 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
608 mpz_t b1, b2, m1, m2;
610 if (r->n == 1)
611 return type;
613 mpz_init (b1);
614 mpz_init (b2);
615 mpz_init (m1);
616 mpz_init (m2);
618 for (i = 1; i < r->n; i++)
620 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
621 type = max_precision_type (type, t);
623 switch (r->type)
625 case clast_red_sum:
626 value_min (m1, bound_one, bound_two);
627 value_min (m2, b1, b2);
628 mpz_add (bound_one, m1, m2);
630 value_max (m1, bound_one, bound_two);
631 value_max (m2, b1, b2);
632 mpz_add (bound_two, m1, m2);
633 break;
635 case clast_red_min:
636 value_min (bound_one, bound_one, bound_two);
637 value_min (bound_two, b1, b2);
638 break;
640 case clast_red_max:
641 value_max (bound_one, bound_one, bound_two);
642 value_max (bound_two, b1, b2);
643 break;
645 default:
646 gcc_unreachable ();
647 break;
651 mpz_clear (b1);
652 mpz_clear (b2);
653 mpz_clear (m1);
654 mpz_clear (m2);
656 /* Return a type that can represent the result of the reduction. */
657 return max_precision_type (type, type_for_interval (bound_one, bound_two));
660 /* Return the type for the clast_binary B used in STMT. */
662 static tree
663 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
664 mpz_t bound_two)
666 mpz_t one;
667 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
668 bound_one, bound_two);
669 tree r = type_for_value (b->RHS);
670 tree type = max_precision_type (l, r);
672 switch (b->type)
674 case clast_bin_fdiv:
675 mpz_mdiv (bound_one, bound_one, b->RHS);
676 mpz_mdiv (bound_two, bound_two, b->RHS);
677 break;
679 case clast_bin_cdiv:
680 mpz_mdiv (bound_one, bound_one, b->RHS);
681 mpz_mdiv (bound_two, bound_two, b->RHS);
682 mpz_init (one);
683 mpz_add (bound_one, bound_one, one);
684 mpz_add (bound_two, bound_two, one);
685 mpz_clear (one);
686 break;
688 case clast_bin_div:
689 mpz_div (bound_one, bound_one, b->RHS);
690 mpz_div (bound_two, bound_two, b->RHS);
691 break;
693 case clast_bin_mod:
694 mpz_mod (bound_one, bound_one, b->RHS);
695 mpz_mod (bound_two, bound_two, b->RHS);
696 break;
698 default:
699 gcc_unreachable ();
702 /* Return a type that can represent the result of the reduction. */
703 return max_precision_type (type, type_for_interval (bound_one, bound_two));
706 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
707 BOUND_TWO to the bounds of the term. */
709 static tree
710 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
711 mpz_t bound_two)
713 bool found = false;
715 if (ip->params.exists () && ip->params_index.is_created ())
716 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
718 if (!found)
720 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
721 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
722 bound_two);
723 gcc_assert (found);
726 return TREE_TYPE (clast_name_to_gcc (name, ip));
729 /* Returns the type for the CLAST expression E when used in statement
730 STMT. */
732 static tree
733 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
734 mpz_t bound_two)
736 switch (e->type)
738 case clast_expr_term:
739 return type_for_clast_term ((struct clast_term *) e, ip,
740 bound_one, bound_two);
742 case clast_expr_red:
743 return type_for_clast_red ((struct clast_reduction *) e, ip,
744 bound_one, bound_two);
746 case clast_expr_bin:
747 return type_for_clast_bin ((struct clast_binary *) e, ip,
748 bound_one, bound_two);
750 case clast_expr_name:
751 return type_for_clast_name ((struct clast_name *) e, ip,
752 bound_one, bound_two);
754 default:
755 gcc_unreachable ();
758 return NULL_TREE;
761 /* Returns true if the clast expression E is a constant with VALUE. */
763 static bool
764 clast_expr_const_value_p (struct clast_expr *e, int value)
766 struct clast_term *t;
767 if (e->type != clast_expr_term)
768 return false;
769 t = (struct clast_term *)e;
770 if (t->var)
771 return false;
772 return 0 == mpz_cmp_si (t->val, value);
775 /* Translates a clast equation CLEQ to a tree. */
777 static tree
778 graphite_translate_clast_equation (struct clast_equation *cleq,
779 ivs_params_p ip)
781 enum tree_code comp;
782 tree type, lhs, rhs, ltype, rtype;
783 mpz_t bound_one, bound_two;
784 struct clast_expr *clhs, *crhs;
786 clhs = cleq->LHS;
787 crhs = cleq->RHS;
788 if (cleq->sign == 0)
789 comp = EQ_EXPR;
790 else if (cleq->sign > 0)
791 comp = GE_EXPR;
792 else
793 comp = LE_EXPR;
795 /* Special cases to reduce range of arguments to hopefully
796 don't need types with larger precision than the input. */
797 if (crhs->type == clast_expr_red
798 && comp != EQ_EXPR)
800 struct clast_reduction *r = (struct clast_reduction *) crhs;
801 /* X >= A+1 --> X > A and
802 X <= A-1 --> X < A */
803 if (r->n == 2
804 && r->type == clast_red_sum
805 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
807 crhs = r->elts[0];
808 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
812 mpz_init (bound_one);
813 mpz_init (bound_two);
815 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
816 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
818 mpz_clear (bound_one);
819 mpz_clear (bound_two);
820 type = max_precision_type (ltype, rtype);
822 lhs = clast_to_gcc_expression (type, clhs, ip);
823 rhs = clast_to_gcc_expression (type, crhs, ip);
825 return fold_build2 (comp, boolean_type_node, lhs, rhs);
828 /* Creates the test for the condition in STMT. */
830 static tree
831 graphite_create_guard_cond_expr (struct clast_guard *stmt,
832 ivs_params_p ip)
834 tree cond = NULL;
835 int i;
837 for (i = 0; i < stmt->n; i++)
839 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
841 if (cond)
842 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
843 else
844 cond = eq;
847 return cond;
850 /* Creates a new if region corresponding to Cloog's guard. */
852 static edge
853 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
854 ivs_params_p ip)
856 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
857 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
858 return exit_edge;
861 /* Compute the lower bound LOW and upper bound UP for the parameter
862 PARAM in scop SCOP based on the constraints in the context. */
864 static void
865 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
867 isl_int v;
868 isl_aff *aff = isl_aff_zero_on_domain
869 (isl_local_space_from_space (isl_set_get_space (scop->context)));
871 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
873 isl_int_init (v);
874 isl_set_min (scop->context, aff, &v);
875 isl_int_get_gmp (v, low);
876 isl_set_max (scop->context, aff, &v);
877 isl_int_get_gmp (v, up);
878 isl_int_clear (v);
879 isl_aff_free (aff);
882 /* Compute the lower bound LOW and upper bound UP for the induction
883 variable of loop LOOP.
885 FIXME: This one is not entirely correct, as min/max expressions in the
886 calculation can yield to incorrect results. To be completely
887 correct, we need to evaluate each subexpression generated by
888 CLooG. CLooG does not yet support this, so this is as good as
889 it can be. */
891 static void
892 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
894 isl_set *domain;
895 isl_aff *dimension;
896 isl_local_space *local_space;
897 isl_int isl_value;
898 enum isl_lp_result lp_result;
900 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
901 local_space = isl_local_space_from_space (isl_set_get_space (domain));
902 dimension = isl_aff_zero_on_domain (local_space);
903 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
904 isl_set_dim (domain, isl_dim_set) - 1,
907 isl_int_init (isl_value);
909 lp_result = isl_set_min (domain, dimension, &isl_value);
910 assert (lp_result == isl_lp_ok);
911 isl_int_get_gmp (isl_value, low);
913 lp_result = isl_set_max (domain, dimension, &isl_value);
914 assert (lp_result == isl_lp_ok);
915 isl_int_get_gmp (isl_value, up);
917 isl_int_clear (isl_value);
918 isl_set_free (domain);
919 isl_aff_free (dimension);
922 /* Returns the type for the induction variable for the loop translated
923 from STMT_FOR. */
925 static tree
926 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
928 mpz_t bound_one, bound_two;
929 tree lb_type, ub_type;
931 mpz_init (bound_one);
932 mpz_init (bound_two);
934 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
935 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
937 mpz_clear (bound_one);
938 mpz_clear (bound_two);
940 return max_precision_type (lb_type, ub_type);
943 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
944 induction variable for the new LOOP. New LOOP is attached to CFG
945 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
946 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
947 CLooG's scattering name to the induction variable created for the
948 loop of STMT. The new induction variable is inserted in the NEWIVS
949 vector and is of type TYPE. */
951 static struct loop *
952 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
953 loop_p outer, tree type, tree lb, tree ub,
954 int level, ivs_params_p ip)
956 mpz_t low, up;
958 tree stride = gmp_cst_to_tree (type, stmt->stride);
959 tree ivvar = create_tmp_var (type, "graphite_IV");
960 tree iv, iv_after_increment;
961 loop_p loop = create_empty_loop_on_edge
962 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
963 outer ? outer : entry_edge->src->loop_father);
965 mpz_init (low);
966 mpz_init (up);
967 compute_bounds_for_loop (stmt, low, up);
968 save_clast_name_index (ip->newivs_index, stmt->iterator,
969 (*ip->newivs).length (), level, low, up);
970 mpz_clear (low);
971 mpz_clear (up);
972 (*ip->newivs).safe_push (iv);
973 return loop;
976 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
977 induction variables of the loops around GBB in SESE. */
979 static void
980 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
981 ivs_params_p ip)
983 struct clast_stmt *t;
984 int depth = 0;
985 CloogStatement *cs = user_stmt->statement;
986 poly_bb_p pbb = (poly_bb_p) cs->usr;
987 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
988 mpz_t bound_one, bound_two;
990 mpz_init (bound_one);
991 mpz_init (bound_two);
993 for (t = user_stmt->substitutions; t; t = t->next, depth++)
995 struct clast_expr *expr = (struct clast_expr *)
996 ((struct clast_assignment *)t)->RHS;
997 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
998 tree new_name = clast_to_gcc_expression (type, expr, ip);
999 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1001 iv_map[old_loop->num] = new_name;
1004 mpz_clear (bound_one);
1005 mpz_clear (bound_two);
1008 /* Construct bb_pbb_def with BB and PBB. */
1010 static bb_pbb_def *
1011 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
1013 bb_pbb_def *bb_pbb_p;
1015 bb_pbb_p = XNEW (bb_pbb_def);
1016 bb_pbb_p->bb = bb;
1017 bb_pbb_p->pbb = pbb;
1019 return bb_pbb_p;
1022 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1024 static void
1025 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1026 bb_pbb_htab_type bb_pbb_mapping)
1028 bb_pbb_def tmp;
1029 bb_pbb_def **x;
1031 tmp.bb = bb;
1032 x = bb_pbb_mapping.find_slot (&tmp, INSERT);
1034 if (x && !*x)
1035 *x = new_bb_pbb_def (bb, pbb);
1038 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1040 poly_bb_p
1041 find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb)
1043 bb_pbb_def tmp;
1044 bb_pbb_def **slot;
1046 tmp.bb = bb;
1047 slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT);
1049 if (slot && *slot)
1050 return ((bb_pbb_def *) *slot)->pbb;
1052 return NULL;
1055 /* Return the scop of the loop and initialize PBBS the set of
1056 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1057 by the CLAST code generator between a generated basic_block and its
1058 related poly_bb_p. */
1060 scop_p
1061 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping,
1062 vec<poly_bb_p> *pbbs)
1064 unsigned i;
1065 basic_block *bbs = get_loop_body_in_dom_order (loop);
1066 scop_p scop = NULL;
1068 for (i = 0; i < loop->num_nodes; i++)
1070 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1072 if (pbb == NULL)
1073 continue;
1075 scop = PBB_SCOP (pbb);
1076 (*pbbs).safe_push (pbb);
1079 free (bbs);
1080 return scop;
1083 /* Translates a clast user statement STMT to gimple.
1085 - NEXT_E is the edge where new generated code should be attached.
1086 - CONTEXT_LOOP is the loop in which the generated code will be placed
1087 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1089 static edge
1090 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1091 bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip)
1093 int i, nb_loops;
1094 basic_block new_bb;
1095 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1096 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1097 vec<tree> iv_map;
1099 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
1100 return next_e;
1102 nb_loops = number_of_loops (cfun);
1103 iv_map.create (nb_loops);
1104 for (i = 0; i < nb_loops; i++)
1105 iv_map.quick_push (NULL_TREE);
1107 build_iv_mapping (iv_map, stmt, ip);
1108 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1109 next_e, iv_map, &gloog_error);
1110 iv_map.release ();
1112 new_bb = next_e->src;
1113 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1114 mark_virtual_operands_for_renaming (cfun);
1115 update_ssa (TODO_update_ssa);
1117 return next_e;
1120 /* Creates a new if region protecting the loop to be executed, if the execution
1121 count is zero (lb > ub). */
1123 static edge
1124 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1125 tree *type, tree *lb, tree *ub,
1126 ivs_params_p ip)
1128 tree cond_expr;
1129 edge exit_edge;
1131 *type = type_for_clast_for (stmt, ip);
1132 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1133 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1135 /* When ub is simply a constant or a parameter, use lb <= ub. */
1136 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1137 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1138 else
1140 tree one = (POINTER_TYPE_P (*type)
1141 ? convert_to_ptrofftype (integer_one_node)
1142 : fold_convert (*type, integer_one_node));
1143 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1144 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1145 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1146 even if we do not want this. However lb < ub + 1 is false, as
1147 expected. */
1148 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1149 : PLUS_EXPR, *type, *ub, one);
1151 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1154 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1156 return exit_edge;
1159 static edge
1160 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type,
1161 int, ivs_params_p);
1163 /* Create the loop for a clast for statement.
1165 - NEXT_E is the edge where new generated code should be attached.
1166 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1168 static edge
1169 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1170 edge next_e, bb_pbb_htab_type bb_pbb_mapping,
1171 int level, tree type, tree lb, tree ub,
1172 ivs_params_p ip)
1174 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1175 type, lb, ub, level, ip);
1176 edge last_e = single_exit (loop);
1177 edge to_body = single_succ_edge (loop->header);
1178 basic_block after = to_body->dest;
1180 /* Create a basic block for loop close phi nodes. */
1181 last_e = single_succ_edge (split_edge (last_e));
1183 /* Translate the body of the loop. */
1184 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1185 level + 1, ip);
1186 redirect_edge_succ_nodup (next_e, after);
1187 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1189 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1190 int scheduling_dim = isl_set_n_dim (domain);
1192 if (flag_loop_parallelize_all
1193 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1194 loop->can_be_parallel = true;
1196 return last_e;
1199 /* Translates a clast for statement STMT to gimple. First a guard is created
1200 protecting the loop, if it is executed zero times. In this guard we create
1201 the real loop structure.
1203 - NEXT_E is the edge where new generated code should be attached.
1204 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1206 static edge
1207 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1208 bb_pbb_htab_type bb_pbb_mapping, int level,
1209 ivs_params_p ip)
1211 tree type, lb, ub;
1212 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1213 &lb, &ub, ip);
1214 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1216 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1217 type, lb, ub, ip);
1218 return last_e;
1221 /* Translates a clast assignment STMT to gimple.
1223 - NEXT_E is the edge where new generated code should be attached.
1224 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1226 static edge
1227 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1228 int level, ivs_params_p ip)
1230 gimple_seq stmts;
1231 mpz_t bound_one, bound_two;
1232 tree type, new_name, var;
1233 edge res = single_succ_edge (split_edge (next_e));
1234 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1236 mpz_init (bound_one);
1237 mpz_init (bound_two);
1238 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1239 var = create_tmp_var (type, "graphite_var");
1240 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1241 &stmts, true, var);
1242 if (stmts)
1244 gsi_insert_seq_on_edge (next_e, stmts);
1245 gsi_commit_edge_inserts ();
1248 save_clast_name_index (ip->newivs_index, stmt->LHS,
1249 (*ip->newivs).length (), level,
1250 bound_one, bound_two);
1251 (*ip->newivs).safe_push (new_name);
1253 mpz_clear (bound_one);
1254 mpz_clear (bound_two);
1256 return res;
1259 /* Translates a clast guard statement STMT to gimple.
1261 - NEXT_E is the edge where new generated code should be attached.
1262 - CONTEXT_LOOP is the loop in which the generated code will be placed
1263 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1265 static edge
1266 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1267 edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level,
1268 ivs_params_p ip)
1270 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1271 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1273 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1274 return last_e;
1277 /* Translates a CLAST statement STMT to GCC representation in the
1278 context of a SESE.
1280 - NEXT_E is the edge where new generated code should be attached.
1281 - CONTEXT_LOOP is the loop in which the generated code will be placed
1282 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1284 static edge
1285 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1286 bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip)
1288 if (!stmt)
1289 return next_e;
1291 if (CLAST_STMT_IS_A (stmt, stmt_root))
1292 ; /* Do nothing. */
1294 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1295 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1296 next_e, bb_pbb_mapping, ip);
1298 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1299 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1300 next_e, bb_pbb_mapping, level, ip);
1302 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1303 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1304 next_e, bb_pbb_mapping, level, ip);
1306 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1307 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1308 next_e, bb_pbb_mapping, level, ip);
1310 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1311 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1312 next_e, level, ip);
1313 else
1314 gcc_unreachable ();
1316 recompute_all_dominators ();
1317 graphite_verify ();
1319 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1320 level, ip);
1323 /* Add parameter and iterator names to the CloogUnionDomain. */
1325 static CloogUnionDomain *
1326 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1327 int nb_scattering_dims,
1328 clast_index_htab_type params_index)
1330 sese region = SCOP_REGION (scop);
1331 int i;
1332 int nb_iterators = scop_max_loop_depth (scop);
1333 int nb_parameters = SESE_PARAMS (region).length ();
1334 mpz_t bound_one, bound_two;
1336 mpz_init (bound_one);
1337 mpz_init (bound_two);
1339 for (i = 0; i < nb_parameters; i++)
1341 tree param = SESE_PARAMS (region)[i];
1342 const char *name = get_name (param);
1343 int len;
1344 char *parameter;
1346 if (!name)
1347 name = "T";
1349 len = strlen (name);
1350 len += 17;
1351 parameter = XNEWVEC (char, len + 1);
1352 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1353 save_clast_name_index (params_index, parameter, i, i, bound_one,
1354 bound_two);
1355 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1356 parameter);
1357 compute_bounds_for_param (scop, i, bound_one, bound_two);
1358 free (parameter);
1361 mpz_clear (bound_one);
1362 mpz_clear (bound_two);
1364 for (i = 0; i < nb_iterators; i++)
1366 int len = 4 + 16;
1367 char *iterator;
1368 iterator = XNEWVEC (char, len);
1369 snprintf (iterator, len, "git_%d", i);
1370 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1371 iterator);
1372 free (iterator);
1375 for (i = 0; i < nb_scattering_dims; i++)
1377 int len = 5 + 16;
1378 char *scattering;
1379 scattering = XNEWVEC (char, len);
1380 snprintf (scattering, len, "scat_%d", i);
1381 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1382 scattering);
1383 free (scattering);
1386 return union_domain;
1389 /* Initialize a CLooG input file. */
1391 static FILE *
1392 init_cloog_input_file (int scop_number)
1394 FILE *graphite_out_file;
1395 int len = strlen (dump_base_name);
1396 char *dumpname = XNEWVEC (char, len + 25);
1397 char *s_scop_number = XNEWVEC (char, 15);
1399 memcpy (dumpname, dump_base_name, len + 1);
1400 strip_off_ending (dumpname, len);
1401 sprintf (s_scop_number, ".%d", scop_number);
1402 strcat (dumpname, s_scop_number);
1403 strcat (dumpname, ".cloog");
1404 graphite_out_file = fopen (dumpname, "w+b");
1406 if (graphite_out_file == 0)
1407 fatal_error ("can%'t open %s for writing: %m", dumpname);
1409 free (dumpname);
1411 return graphite_out_file;
1414 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1416 static
1417 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1419 int old_dims, i;
1420 isl_space *space;
1421 isl_basic_map *change_scattering;
1422 isl_map *change_scattering_map;
1424 old_dims = isl_map_dim (scattering, isl_dim_out);
1426 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1427 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1429 for (i = 0; i < old_dims; i++)
1431 isl_constraint *c;
1432 c = isl_equality_alloc
1433 (isl_local_space_from_space (isl_space_copy (space)));
1434 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1435 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1436 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1439 for (i = old_dims; i < new_dims; i++)
1441 isl_constraint *c;
1442 c = isl_equality_alloc
1443 (isl_local_space_from_space (isl_space_copy (space)));
1444 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1445 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1448 change_scattering_map = isl_map_from_basic_map (change_scattering);
1449 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1450 return isl_map_apply_range (scattering, change_scattering_map);
1453 /* Build cloog union domain for SCoP. */
1455 static CloogUnionDomain *
1456 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1458 int i;
1459 poly_bb_p pbb;
1460 CloogUnionDomain *union_domain =
1461 cloog_union_domain_alloc (scop_nb_params (scop));
1463 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1465 CloogDomain *domain;
1466 CloogScattering *scattering;
1468 /* Dead code elimination: when the domain of a PBB is empty,
1469 don't generate code for the PBB. */
1470 if (isl_set_is_empty (pbb->domain))
1471 continue;
1473 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1474 scattering = cloog_scattering_from_isl_map
1475 (extend_scattering (isl_map_copy (pbb->transformed),
1476 nb_scattering_dims));
1478 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1479 scattering, pbb);
1482 return union_domain;
1485 /* Return the options that will be used in GLOOG. */
1487 static CloogOptions *
1488 set_cloog_options (void)
1490 CloogOptions *options = cloog_options_malloc (cloog_state);
1492 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1493 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1494 we pass an incomplete program to cloog. */
1495 options->language = CLOOG_LANGUAGE_C;
1497 /* Enable complex equality spreading: removes dummy statements
1498 (assignments) in the generated code which repeats the
1499 substitution equations for statements. This is useless for
1500 GLooG. */
1501 options->esp = 1;
1503 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1504 options->quiet = 1;
1506 /* Allow cloog to build strides with a stride width different to one.
1507 This example has stride = 4:
1509 for (i = 0; i < 20; i += 4)
1510 A */
1511 options->strides = 1;
1513 /* We want the clast to provide the iteration domains of the executed loops.
1514 This allows us to derive minimal/maximal values for the induction
1515 variables. */
1516 options->save_domains = 1;
1518 /* Disable optimizations and make cloog generate source code closer to the
1519 input. This is useful for debugging, but later we want the optimized
1520 code.
1522 XXX: We can not disable optimizations, as loop blocking is not working
1523 without them. */
1524 if (0)
1526 options->f = -1;
1527 options->l = INT_MAX;
1530 return options;
1533 /* Prints STMT to STDERR. */
1535 void
1536 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1538 CloogOptions *options = set_cloog_options ();
1540 clast_pprint (file, stmt, 0, options);
1541 cloog_options_free (options);
1544 /* Prints STMT to STDERR. */
1546 DEBUG_FUNCTION void
1547 debug_clast_stmt (struct clast_stmt *stmt)
1549 print_clast_stmt (stderr, stmt);
1552 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1554 static
1555 int get_max_scattering_dimensions (scop_p scop)
1557 int i;
1558 poly_bb_p pbb;
1559 int scattering_dims = 0;
1561 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1563 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1564 if (pbb_scatt_dims > scattering_dims)
1565 scattering_dims = pbb_scatt_dims;
1568 return scattering_dims;
1571 static CloogInput *
1572 generate_cloog_input (scop_p scop, clast_index_htab_type params_index)
1574 CloogUnionDomain *union_domain;
1575 CloogInput *cloog_input;
1576 CloogDomain *context;
1577 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1579 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1580 union_domain = add_names_to_union_domain (scop, union_domain,
1581 nb_scattering_dims,
1582 params_index);
1583 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1585 cloog_input = cloog_input_alloc (context, union_domain);
1587 return cloog_input;
1590 /* Translate SCOP to a CLooG program and clast. These two
1591 representations should be freed together: a clast cannot be used
1592 without a program. */
1594 static struct clast_stmt *
1595 scop_to_clast (scop_p scop, clast_index_htab_type params_index)
1597 CloogInput *cloog_input;
1598 struct clast_stmt *clast;
1599 CloogOptions *options = set_cloog_options ();
1601 cloog_input = generate_cloog_input (scop, params_index);
1603 /* Dump a .cloog input file, if requested. This feature is only
1604 enabled in the Graphite branch. */
1605 if (0)
1607 static size_t file_scop_number = 0;
1608 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1609 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1612 clast = cloog_clast_create_from_input (cloog_input, options);
1614 cloog_options_free (options);
1615 return clast;
1618 /* Prints to FILE the code generated by CLooG for SCOP. */
1620 void
1621 print_generated_program (FILE *file, scop_p scop)
1623 CloogOptions *options = set_cloog_options ();
1624 clast_index_htab_type params_index;
1625 struct clast_stmt *clast;
1627 params_index.create (10);
1629 clast = scop_to_clast (scop, params_index);
1631 fprintf (file, " (clast: \n");
1632 clast_pprint (file, clast, 0, options);
1633 fprintf (file, " )\n");
1635 cloog_options_free (options);
1636 cloog_clast_free (clast);
1639 /* Prints to STDERR the code generated by CLooG for SCOP. */
1641 DEBUG_FUNCTION void
1642 debug_generated_program (scop_p scop)
1644 print_generated_program (stderr, scop);
1647 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1648 the given SCOP. Return true if code generation succeeded.
1649 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1652 bool
1653 gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping)
1655 stack_vec<tree, 10> newivs;
1656 loop_p context_loop;
1657 sese region = SCOP_REGION (scop);
1658 ifsese if_region = NULL;
1659 clast_index_htab_type newivs_index, params_index;
1660 struct clast_stmt *clast;
1661 struct ivs_params ip;
1663 timevar_push (TV_GRAPHITE_CODE_GEN);
1664 gloog_error = false;
1666 params_index.create (10);
1668 clast = scop_to_clast (scop, params_index);
1670 if (dump_file && (dump_flags & TDF_DETAILS))
1672 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1673 print_clast_stmt (dump_file, clast);
1674 fprintf (dump_file, "\n");
1677 recompute_all_dominators ();
1678 graphite_verify ();
1680 if_region = move_sese_in_condition (region);
1681 sese_insert_phis_for_liveouts (region,
1682 if_region->region->exit->src,
1683 if_region->false_region->exit,
1684 if_region->true_region->exit);
1685 recompute_all_dominators ();
1686 graphite_verify ();
1688 context_loop = SESE_ENTRY (region)->src->loop_father;
1689 newivs_index.create (10);
1691 ip.newivs = &newivs;
1692 ip.newivs_index = newivs_index;
1693 ip.params = SESE_PARAMS (region);
1694 ip.params_index = params_index;
1695 ip.region = region;
1697 translate_clast (context_loop, clast, if_region->true_region->entry,
1698 bb_pbb_mapping, 0, &ip);
1699 graphite_verify ();
1700 scev_reset ();
1701 recompute_all_dominators ();
1702 graphite_verify ();
1704 if (gloog_error)
1705 set_ifsese_condition (if_region, integer_zero_node);
1707 free (if_region->true_region);
1708 free (if_region->region);
1709 free (if_region);
1711 newivs_index.dispose ();
1712 params_index.dispose ();
1713 cloog_clast_free (clast);
1714 timevar_pop (TV_GRAPHITE_CODE_GEN);
1716 if (dump_file && (dump_flags & TDF_DETAILS))
1718 loop_p loop;
1719 loop_iterator li;
1720 int num_no_dependency = 0;
1722 FOR_EACH_LOOP (li, loop, 0)
1723 if (loop->can_be_parallel)
1724 num_no_dependency++;
1726 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1727 num_no_dependency);
1730 return !gloog_error;
1732 #endif