Mark ChangeLog
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob30d42c4b70d937e74200a65ef0f063bcfef806ea
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 #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE
34 #include <isl/deprecated/int.h>
35 #include <isl/lp.h>
36 #include <isl/deprecated/ilp_int.h>
37 #endif
38 #endif
40 #include "system.h"
41 #include "coretypes.h"
42 #include "diagnostic-core.h"
43 #include "tree-flow.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"
56 typedef const struct clast_expr *clast_name_p;
58 #ifndef CLOOG_LANGUAGE_C
59 #define CLOOG_LANGUAGE_C LANGUAGE_C
60 #endif
63 /* Converts a GMP constant VAL to a tree and returns it. */
65 static tree
66 gmp_cst_to_tree (tree type, mpz_t val)
68 tree t = type ? type : integer_type_node;
69 mpz_t tmp;
70 double_int di;
72 mpz_init (tmp);
73 mpz_set (tmp, val);
74 di = mpz_get_double_int (t, tmp, true);
75 mpz_clear (tmp);
77 return double_int_to_tree (t, di);
80 /* Sets RES to the min of V1 and V2. */
82 static void
83 value_min (mpz_t res, mpz_t v1, mpz_t v2)
85 if (mpz_cmp (v1, v2) < 0)
86 mpz_set (res, v1);
87 else
88 mpz_set (res, v2);
91 /* Sets RES to the max of V1 and V2. */
93 static void
94 value_max (mpz_t res, mpz_t v1, mpz_t v2)
96 if (mpz_cmp (v1, v2) < 0)
97 mpz_set (res, v2);
98 else
99 mpz_set (res, v1);
103 /* This flag is set when an error occurred during the translation of
104 CLAST to Gimple. */
105 static bool gloog_error;
107 /* Verifies properties that GRAPHITE should maintain during translation. */
109 static inline void
110 graphite_verify (void)
112 #ifdef ENABLE_CHECKING
113 verify_loop_structure ();
114 verify_loop_closed_ssa (true);
115 #endif
118 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
119 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
120 upper bounds that can be inferred from the polyhedral representation. */
122 typedef struct clast_name_index {
123 int index;
124 int level;
125 mpz_t bound_one, bound_two;
126 const char *name;
127 /* If free_name is set, the content of name was allocated by us and needs
128 to be freed. */
129 char *free_name;
130 } *clast_name_index_p;
132 /* Returns a pointer to a new element of type clast_name_index_p built
133 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
135 static inline clast_name_index_p
136 new_clast_name_index (const char *name, int index, int level,
137 mpz_t bound_one, mpz_t bound_two)
139 clast_name_index_p res = XNEW (struct clast_name_index);
140 char *new_name = XNEWVEC (char, strlen (name) + 1);
141 strcpy (new_name, name);
143 res->name = new_name;
144 res->free_name = new_name;
145 res->level = level;
146 res->index = index;
147 mpz_init (res->bound_one);
148 mpz_init (res->bound_two);
149 mpz_set (res->bound_one, bound_one);
150 mpz_set (res->bound_two, bound_two);
151 return res;
154 /* Free the memory taken by a clast_name_index struct. */
156 static void
157 free_clast_name_index (void *ptr)
159 struct clast_name_index *c = (struct clast_name_index *) ptr;
160 if (c->free_name)
161 free (c->free_name);
162 mpz_clear (c->bound_one);
163 mpz_clear (c->bound_two);
164 free (ptr);
167 /* For a given clast NAME, returns -1 if NAME is not in the
168 INDEX_TABLE, otherwise returns the loop level for the induction
169 variable NAME, or if it is a parameter, the parameter number in the
170 vector of parameters. */
172 static inline int
173 clast_name_to_level (clast_name_p name, htab_t index_table)
175 struct clast_name_index tmp;
176 PTR *slot;
178 gcc_assert (name->type == clast_expr_name);
179 tmp.name = ((const struct clast_name *) name)->name;
180 tmp.free_name = NULL;
182 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
184 if (slot && *slot)
185 return ((struct clast_name_index *) *slot)->level;
187 return -1;
190 /* For a given clast NAME, returns -1 if it does not correspond to any
191 parameter, or otherwise, returns the index in the PARAMS or
192 SCATTERING_DIMENSIONS vector. */
194 static inline int
195 clast_name_to_index (struct clast_name *name, htab_t index_table)
197 struct clast_name_index tmp;
198 PTR *slot;
200 tmp.name = ((const struct clast_name *) name)->name;
201 tmp.free_name = NULL;
203 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
205 if (slot && *slot)
206 return ((struct clast_name_index *) *slot)->index;
208 return -1;
211 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
212 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
213 found in the INDEX_TABLE, false otherwise. */
215 static inline bool
216 clast_name_to_lb_ub (struct clast_name *name, htab_t index_table,
217 mpz_t bound_one, mpz_t bound_two)
219 struct clast_name_index tmp;
220 PTR *slot;
222 tmp.name = name->name;
223 tmp.free_name = NULL;
225 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
227 if (slot && *slot)
229 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
230 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
231 return true;
234 return false;
237 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
239 static inline void
240 save_clast_name_index (htab_t index_table, const char *name,
241 int index, int level, mpz_t bound_one, mpz_t bound_two)
243 struct clast_name_index tmp;
244 PTR *slot;
246 tmp.name = name;
247 tmp.free_name = NULL;
248 slot = htab_find_slot (index_table, &tmp, INSERT);
250 if (slot)
252 free (*slot);
254 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
258 /* Computes a hash function for database element ELT. */
260 static inline hashval_t
261 clast_name_index_elt_info (const void *elt)
263 const struct clast_name_index *e = ((const struct clast_name_index *) elt);
264 hashval_t hash = 0;
266 int length = strlen (e->name);
267 int i;
269 for (i = 0; i < length; ++i)
270 hash = hash | (e->name[i] << (i % 4));
272 return hash;
275 /* Compares database elements E1 and E2. */
277 static inline int
278 eq_clast_name_indexes (const void *e1, const void *e2)
280 const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
281 const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
283 return strcmp (elt1->name, elt2->name) == 0;
288 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
289 induction variable in NEWIVS.
291 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
292 parameter in PARAMS. */
294 typedef struct ivs_params {
295 vec<tree> params, *newivs;
296 htab_t newivs_index, params_index;
297 sese region;
298 } *ivs_params_p;
300 /* Returns the tree variable from the name NAME that was given in
301 Cloog representation. */
303 static tree
304 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
306 int index;
308 if (ip->params.exists () && ip->params_index)
310 index = clast_name_to_index (name, ip->params_index);
312 if (index >= 0)
313 return ip->params[index];
316 gcc_assert (ip->newivs && ip->newivs_index);
317 index = clast_name_to_index (name, ip->newivs_index);
318 gcc_assert (index >= 0);
320 return (*ip->newivs)[index];
323 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
325 static tree
326 max_precision_type (tree type1, tree type2)
328 enum machine_mode mode;
329 int p1, p2, precision;
330 tree type;
332 if (POINTER_TYPE_P (type1))
333 return type1;
335 if (POINTER_TYPE_P (type2))
336 return type2;
338 if (TYPE_UNSIGNED (type1)
339 && TYPE_UNSIGNED (type2))
340 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
342 p1 = TYPE_PRECISION (type1);
343 p2 = TYPE_PRECISION (type2);
345 if (p1 > p2)
346 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
347 else
348 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
350 if (precision > BITS_PER_WORD)
352 gloog_error = true;
353 return integer_type_node;
356 mode = smallest_mode_for_size (precision, MODE_INT);
357 precision = GET_MODE_PRECISION (mode);
358 type = build_nonstandard_integer_type (precision, false);
360 if (!type)
362 gloog_error = true;
363 return integer_type_node;
366 return type;
369 static tree
370 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
372 /* Converts a Cloog reduction expression R with reduction operation OP
373 to a GCC expression tree of type TYPE. */
375 static tree
376 clast_to_gcc_expression_red (tree type, enum tree_code op,
377 struct clast_reduction *r, ivs_params_p ip)
379 int i;
380 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
381 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
383 for (i = 1; i < r->n; i++)
385 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
386 res = fold_build2 (op, type, res, t);
389 return res;
392 /* Converts a Cloog AST expression E back to a GCC expression tree of
393 type TYPE. */
395 static tree
396 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
398 switch (e->type)
400 case clast_expr_name:
402 return clast_name_to_gcc ((struct clast_name *) e, ip);
404 case clast_expr_term:
406 struct clast_term *t = (struct clast_term *) e;
408 if (t->var)
410 if (mpz_cmp_si (t->val, 1) == 0)
412 tree name = clast_to_gcc_expression (type, t->var, ip);
414 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
415 name = convert_to_ptrofftype (name);
417 name = fold_convert (type, name);
418 return name;
421 else if (mpz_cmp_si (t->val, -1) == 0)
423 tree name = clast_to_gcc_expression (type, t->var, ip);
425 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
426 name = convert_to_ptrofftype (name);
428 name = fold_convert (type, name);
430 return fold_build1 (NEGATE_EXPR, type, name);
432 else
434 tree name = clast_to_gcc_expression (type, t->var, ip);
435 tree cst = gmp_cst_to_tree (type, t->val);
437 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
438 name = convert_to_ptrofftype (name);
440 name = fold_convert (type, name);
442 if (!POINTER_TYPE_P (type))
443 return fold_build2 (MULT_EXPR, type, cst, name);
445 gloog_error = true;
446 return cst;
449 else
450 return gmp_cst_to_tree (type, t->val);
453 case clast_expr_red:
455 struct clast_reduction *r = (struct clast_reduction *) e;
457 switch (r->type)
459 case clast_red_sum:
460 return clast_to_gcc_expression_red
461 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
462 r, ip);
464 case clast_red_min:
465 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
467 case clast_red_max:
468 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
470 default:
471 gcc_unreachable ();
473 break;
476 case clast_expr_bin:
478 struct clast_binary *b = (struct clast_binary *) e;
479 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
480 tree tl = clast_to_gcc_expression (type, lhs, ip);
481 tree tr = gmp_cst_to_tree (type, b->RHS);
483 switch (b->type)
485 case clast_bin_fdiv:
486 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
488 case clast_bin_cdiv:
489 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
491 case clast_bin_div:
492 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
494 case clast_bin_mod:
495 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
497 default:
498 gcc_unreachable ();
502 default:
503 gcc_unreachable ();
506 return NULL_TREE;
509 /* Return a type that could represent the values between BOUND_ONE and
510 BOUND_TWO. */
512 static tree
513 type_for_interval (mpz_t bound_one, mpz_t bound_two)
515 bool unsigned_p;
516 tree type;
517 enum machine_mode mode;
518 int wider_precision;
519 int precision = MAX (mpz_sizeinbase (bound_one, 2),
520 mpz_sizeinbase (bound_two, 2));
522 if (precision > BITS_PER_WORD)
524 gloog_error = true;
525 return integer_type_node;
528 if (mpz_cmp (bound_one, bound_two) <= 0)
529 unsigned_p = (mpz_sgn (bound_one) >= 0);
530 else
531 unsigned_p = (mpz_sgn (bound_two) >= 0);
533 mode = smallest_mode_for_size (precision, MODE_INT);
534 wider_precision = GET_MODE_PRECISION (mode);
536 /* As we want to generate signed types as much as possible, try to
537 fit the interval [bound_one, bound_two] in a signed type. For example,
538 supposing that we have the interval [0, 100], instead of
539 generating unsigned char, we want to generate a signed char. */
540 if (unsigned_p && precision < wider_precision)
541 unsigned_p = false;
543 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
545 if (!type)
547 gloog_error = true;
548 return integer_type_node;
551 return type;
554 /* Return a type that could represent the integer value VAL, or
555 otherwise return NULL_TREE. */
557 static tree
558 type_for_value (mpz_t val)
560 return type_for_interval (val, val);
563 static tree
564 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
566 /* Return the type for the clast_term T. Initializes BOUND_ONE and
567 BOUND_TWO to the bounds of the term. */
569 static tree
570 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
571 mpz_t bound_two)
573 tree type;
574 gcc_assert (t->expr.type == clast_expr_term);
576 if (!t->var)
578 mpz_set (bound_one, t->val);
579 mpz_set (bound_two, t->val);
580 return type_for_value (t->val);
583 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
585 mpz_mul (bound_one, bound_one, t->val);
586 mpz_mul (bound_two, bound_two, t->val);
588 return max_precision_type (type, type_for_interval (bound_one, bound_two));
591 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
592 and BOUND_TWO to the bounds of the reduction expression. */
594 static tree
595 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
596 mpz_t bound_one, mpz_t bound_two)
598 int i;
599 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
600 mpz_t b1, b2, m1, m2;
602 if (r->n == 1)
603 return type;
605 mpz_init (b1);
606 mpz_init (b2);
607 mpz_init (m1);
608 mpz_init (m2);
610 for (i = 1; i < r->n; i++)
612 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
613 type = max_precision_type (type, t);
615 switch (r->type)
617 case clast_red_sum:
618 value_min (m1, bound_one, bound_two);
619 value_min (m2, b1, b2);
620 mpz_add (bound_one, m1, m2);
622 value_max (m1, bound_one, bound_two);
623 value_max (m2, b1, b2);
624 mpz_add (bound_two, m1, m2);
625 break;
627 case clast_red_min:
628 value_min (bound_one, bound_one, bound_two);
629 value_min (bound_two, b1, b2);
630 break;
632 case clast_red_max:
633 value_max (bound_one, bound_one, bound_two);
634 value_max (bound_two, b1, b2);
635 break;
637 default:
638 gcc_unreachable ();
639 break;
643 mpz_clear (b1);
644 mpz_clear (b2);
645 mpz_clear (m1);
646 mpz_clear (m2);
648 /* Return a type that can represent the result of the reduction. */
649 return max_precision_type (type, type_for_interval (bound_one, bound_two));
652 /* Return the type for the clast_binary B used in STMT. */
654 static tree
655 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
656 mpz_t bound_two)
658 mpz_t one;
659 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
660 bound_one, bound_two);
661 tree r = type_for_value (b->RHS);
662 tree type = max_precision_type (l, r);
664 switch (b->type)
666 case clast_bin_fdiv:
667 mpz_mdiv (bound_one, bound_one, b->RHS);
668 mpz_mdiv (bound_two, bound_two, b->RHS);
669 break;
671 case clast_bin_cdiv:
672 mpz_mdiv (bound_one, bound_one, b->RHS);
673 mpz_mdiv (bound_two, bound_two, b->RHS);
674 mpz_init (one);
675 mpz_add (bound_one, bound_one, one);
676 mpz_add (bound_two, bound_two, one);
677 mpz_clear (one);
678 break;
680 case clast_bin_div:
681 mpz_div (bound_one, bound_one, b->RHS);
682 mpz_div (bound_two, bound_two, b->RHS);
683 break;
685 case clast_bin_mod:
686 mpz_mod (bound_one, bound_one, b->RHS);
687 mpz_mod (bound_two, bound_two, b->RHS);
688 break;
690 default:
691 gcc_unreachable ();
694 /* Return a type that can represent the result of the reduction. */
695 return max_precision_type (type, type_for_interval (bound_one, bound_two));
698 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
699 BOUND_TWO to the bounds of the term. */
701 static tree
702 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
703 mpz_t bound_two)
705 bool found = false;
707 if (ip->params.exists () && ip->params_index)
708 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
710 if (!found)
712 gcc_assert (ip->newivs && ip->newivs_index);
713 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
714 bound_two);
715 gcc_assert (found);
718 return TREE_TYPE (clast_name_to_gcc (name, ip));
721 /* Returns the type for the CLAST expression E when used in statement
722 STMT. */
724 static tree
725 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
726 mpz_t bound_two)
728 switch (e->type)
730 case clast_expr_term:
731 return type_for_clast_term ((struct clast_term *) e, ip,
732 bound_one, bound_two);
734 case clast_expr_red:
735 return type_for_clast_red ((struct clast_reduction *) e, ip,
736 bound_one, bound_two);
738 case clast_expr_bin:
739 return type_for_clast_bin ((struct clast_binary *) e, ip,
740 bound_one, bound_two);
742 case clast_expr_name:
743 return type_for_clast_name ((struct clast_name *) e, ip,
744 bound_one, bound_two);
746 default:
747 gcc_unreachable ();
750 return NULL_TREE;
753 /* Returns true if the clast expression E is a constant with VALUE. */
755 static bool
756 clast_expr_const_value_p (struct clast_expr *e, int value)
758 struct clast_term *t;
759 if (e->type != clast_expr_term)
760 return false;
761 t = (struct clast_term *)e;
762 if (t->var)
763 return false;
764 return 0 == mpz_cmp_si (t->val, value);
767 /* Translates a clast equation CLEQ to a tree. */
769 static tree
770 graphite_translate_clast_equation (struct clast_equation *cleq,
771 ivs_params_p ip)
773 enum tree_code comp;
774 tree type, lhs, rhs, ltype, rtype;
775 mpz_t bound_one, bound_two;
776 struct clast_expr *clhs, *crhs;
778 clhs = cleq->LHS;
779 crhs = cleq->RHS;
780 if (cleq->sign == 0)
781 comp = EQ_EXPR;
782 else if (cleq->sign > 0)
783 comp = GE_EXPR;
784 else
785 comp = LE_EXPR;
787 /* Special cases to reduce range of arguments to hopefully
788 don't need types with larger precision than the input. */
789 if (crhs->type == clast_expr_red
790 && comp != EQ_EXPR)
792 struct clast_reduction *r = (struct clast_reduction *) crhs;
793 /* X >= A+1 --> X > A and
794 X <= A-1 --> X < A */
795 if (r->n == 2
796 && r->type == clast_red_sum
797 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
799 crhs = r->elts[0];
800 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
804 mpz_init (bound_one);
805 mpz_init (bound_two);
807 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
808 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
810 mpz_clear (bound_one);
811 mpz_clear (bound_two);
812 type = max_precision_type (ltype, rtype);
814 lhs = clast_to_gcc_expression (type, clhs, ip);
815 rhs = clast_to_gcc_expression (type, crhs, ip);
817 return fold_build2 (comp, boolean_type_node, lhs, rhs);
820 /* Creates the test for the condition in STMT. */
822 static tree
823 graphite_create_guard_cond_expr (struct clast_guard *stmt,
824 ivs_params_p ip)
826 tree cond = NULL;
827 int i;
829 for (i = 0; i < stmt->n; i++)
831 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
833 if (cond)
834 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
835 else
836 cond = eq;
839 return cond;
842 /* Creates a new if region corresponding to Cloog's guard. */
844 static edge
845 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
846 ivs_params_p ip)
848 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
849 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
850 return exit_edge;
853 /* Compute the lower bound LOW and upper bound UP for the parameter
854 PARAM in scop SCOP based on the constraints in the context. */
856 static void
857 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
859 isl_int v;
860 isl_aff *aff = isl_aff_zero_on_domain
861 (isl_local_space_from_space (isl_set_get_space (scop->context)));
863 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
865 isl_int_init (v);
866 isl_set_min (scop->context, aff, &v);
867 isl_int_get_gmp (v, low);
868 isl_set_max (scop->context, aff, &v);
869 isl_int_get_gmp (v, up);
870 isl_int_clear (v);
871 isl_aff_free (aff);
874 /* Compute the lower bound LOW and upper bound UP for the induction
875 variable of loop LOOP.
877 FIXME: This one is not entirely correct, as min/max expressions in the
878 calculation can yield to incorrect results. To be completely
879 correct, we need to evaluate each subexpression generated by
880 CLooG. CLooG does not yet support this, so this is as good as
881 it can be. */
883 static void
884 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
886 isl_set *domain;
887 isl_aff *dimension;
888 isl_local_space *local_space;
889 isl_int isl_value;
890 enum isl_lp_result lp_result;
892 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
893 local_space = isl_local_space_from_space (isl_set_get_space (domain));
894 dimension = isl_aff_zero_on_domain (local_space);
895 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
896 isl_set_dim (domain, isl_dim_set) - 1,
899 isl_int_init (isl_value);
901 lp_result = isl_set_min (domain, dimension, &isl_value);
902 assert (lp_result == isl_lp_ok);
903 isl_int_get_gmp (isl_value, low);
905 lp_result = isl_set_max (domain, dimension, &isl_value);
906 assert (lp_result == isl_lp_ok);
907 isl_int_get_gmp (isl_value, up);
909 isl_int_clear (isl_value);
910 isl_set_free (domain);
911 isl_aff_free (dimension);
914 /* Returns the type for the induction variable for the loop translated
915 from STMT_FOR. */
917 static tree
918 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
920 mpz_t bound_one, bound_two;
921 tree lb_type, ub_type;
923 mpz_init (bound_one);
924 mpz_init (bound_two);
926 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
927 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
929 mpz_clear (bound_one);
930 mpz_clear (bound_two);
932 return max_precision_type (lb_type, ub_type);
935 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
936 induction variable for the new LOOP. New LOOP is attached to CFG
937 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
938 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
939 CLooG's scattering name to the induction variable created for the
940 loop of STMT. The new induction variable is inserted in the NEWIVS
941 vector and is of type TYPE. */
943 static struct loop *
944 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
945 loop_p outer, tree type, tree lb, tree ub,
946 int level, ivs_params_p ip)
948 mpz_t low, up;
950 tree stride = gmp_cst_to_tree (type, stmt->stride);
951 tree ivvar = create_tmp_var (type, "graphite_IV");
952 tree iv, iv_after_increment;
953 loop_p loop = create_empty_loop_on_edge
954 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
955 outer ? outer : entry_edge->src->loop_father);
957 mpz_init (low);
958 mpz_init (up);
959 compute_bounds_for_loop (stmt, low, up);
960 save_clast_name_index (ip->newivs_index, stmt->iterator,
961 (*ip->newivs).length (), level, low, up);
962 mpz_clear (low);
963 mpz_clear (up);
964 (*ip->newivs).safe_push (iv);
965 return loop;
968 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
969 induction variables of the loops around GBB in SESE. */
971 static void
972 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
973 ivs_params_p ip)
975 struct clast_stmt *t;
976 int depth = 0;
977 CloogStatement *cs = user_stmt->statement;
978 poly_bb_p pbb = (poly_bb_p) cs->usr;
979 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
980 mpz_t bound_one, bound_two;
982 mpz_init (bound_one);
983 mpz_init (bound_two);
985 for (t = user_stmt->substitutions; t; t = t->next, depth++)
987 struct clast_expr *expr = (struct clast_expr *)
988 ((struct clast_assignment *)t)->RHS;
989 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
990 tree new_name = clast_to_gcc_expression (type, expr, ip);
991 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
993 iv_map[old_loop->num] = new_name;
996 mpz_clear (bound_one);
997 mpz_clear (bound_two);
1000 /* Construct bb_pbb_def with BB and PBB. */
1002 static bb_pbb_def *
1003 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
1005 bb_pbb_def *bb_pbb_p;
1007 bb_pbb_p = XNEW (bb_pbb_def);
1008 bb_pbb_p->bb = bb;
1009 bb_pbb_p->pbb = pbb;
1011 return bb_pbb_p;
1014 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1016 static void
1017 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
1019 bb_pbb_def tmp;
1020 PTR *x;
1022 tmp.bb = bb;
1023 x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
1025 if (x && !*x)
1026 *x = new_bb_pbb_def (bb, pbb);
1029 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1031 poly_bb_p
1032 find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
1034 bb_pbb_def tmp;
1035 PTR *slot;
1037 tmp.bb = bb;
1038 slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
1040 if (slot && *slot)
1041 return ((bb_pbb_def *) *slot)->pbb;
1043 return NULL;
1046 /* Return the scop of the loop and initialize PBBS the set of
1047 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1048 by the CLAST code generator between a generated basic_block and its
1049 related poly_bb_p. */
1051 scop_p
1052 get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping,
1053 vec<poly_bb_p> *pbbs)
1055 unsigned i;
1056 basic_block *bbs = get_loop_body_in_dom_order (loop);
1057 scop_p scop = NULL;
1059 for (i = 0; i < loop->num_nodes; i++)
1061 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1063 if (pbb == NULL)
1064 continue;
1066 scop = PBB_SCOP (pbb);
1067 (*pbbs).safe_push (pbb);
1070 free (bbs);
1071 return scop;
1074 /* Translates a clast user statement STMT to gimple.
1076 - NEXT_E is the edge where new generated code should be attached.
1077 - CONTEXT_LOOP is the loop in which the generated code will be placed
1078 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1080 static edge
1081 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1082 htab_t bb_pbb_mapping, ivs_params_p ip)
1084 int i, nb_loops;
1085 basic_block new_bb;
1086 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1087 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1088 vec<tree> iv_map;
1090 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
1091 return next_e;
1093 nb_loops = number_of_loops ();
1094 iv_map.create (nb_loops);
1095 for (i = 0; i < nb_loops; i++)
1096 iv_map.quick_push (NULL_TREE);
1098 build_iv_mapping (iv_map, stmt, ip);
1099 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1100 next_e, iv_map, &gloog_error);
1101 iv_map.release ();
1103 new_bb = next_e->src;
1104 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1105 mark_virtual_operands_for_renaming (cfun);
1106 update_ssa (TODO_update_ssa);
1108 return next_e;
1111 /* Creates a new if region protecting the loop to be executed, if the execution
1112 count is zero (lb > ub). */
1114 static edge
1115 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1116 tree *type, tree *lb, tree *ub,
1117 ivs_params_p ip)
1119 tree cond_expr;
1120 edge exit_edge;
1122 *type = type_for_clast_for (stmt, ip);
1123 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1124 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1126 /* When ub is simply a constant or a parameter, use lb <= ub. */
1127 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1128 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1129 else
1131 tree one = (POINTER_TYPE_P (*type)
1132 ? convert_to_ptrofftype (integer_one_node)
1133 : fold_convert (*type, integer_one_node));
1134 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1135 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1136 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1137 even if we do not want this. However lb < ub + 1 is false, as
1138 expected. */
1139 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1140 : PLUS_EXPR, *type, *ub, one);
1142 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1145 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1147 return exit_edge;
1150 static edge
1151 translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p);
1153 /* Create the loop for a clast for statement.
1155 - NEXT_E is the edge where new generated code should be attached.
1156 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1158 static edge
1159 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1160 edge next_e, htab_t bb_pbb_mapping, int level,
1161 tree type, tree lb, tree ub, ivs_params_p ip)
1163 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1164 type, lb, ub, level, ip);
1165 edge last_e = single_exit (loop);
1166 edge to_body = single_succ_edge (loop->header);
1167 basic_block after = to_body->dest;
1169 /* Create a basic block for loop close phi nodes. */
1170 last_e = single_succ_edge (split_edge (last_e));
1172 /* Translate the body of the loop. */
1173 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1174 level + 1, ip);
1175 redirect_edge_succ_nodup (next_e, after);
1176 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1178 if (flag_loop_parallelize_all
1179 && loop_is_parallel_p (loop, bb_pbb_mapping, level))
1180 loop->can_be_parallel = true;
1182 return last_e;
1185 /* Translates a clast for statement STMT to gimple. First a guard is created
1186 protecting the loop, if it is executed zero times. In this guard we create
1187 the real loop structure.
1189 - NEXT_E is the edge where new generated code should be attached.
1190 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1192 static edge
1193 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1194 htab_t bb_pbb_mapping, int level, ivs_params_p ip)
1196 tree type, lb, ub;
1197 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1198 &lb, &ub, ip);
1199 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1201 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1202 type, lb, ub, ip);
1203 return last_e;
1206 /* Translates a clast assignment STMT to gimple.
1208 - NEXT_E is the edge where new generated code should be attached.
1209 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1211 static edge
1212 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1213 int level, ivs_params_p ip)
1215 gimple_seq stmts;
1216 mpz_t bound_one, bound_two;
1217 tree type, new_name, var;
1218 edge res = single_succ_edge (split_edge (next_e));
1219 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1221 mpz_init (bound_one);
1222 mpz_init (bound_two);
1223 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1224 var = create_tmp_var (type, "graphite_var");
1225 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1226 &stmts, true, var);
1227 if (stmts)
1229 gsi_insert_seq_on_edge (next_e, stmts);
1230 gsi_commit_edge_inserts ();
1233 save_clast_name_index (ip->newivs_index, stmt->LHS,
1234 (*ip->newivs).length (), level,
1235 bound_one, bound_two);
1236 (*ip->newivs).safe_push (new_name);
1238 mpz_clear (bound_one);
1239 mpz_clear (bound_two);
1241 return res;
1244 /* Translates a clast guard statement STMT to gimple.
1246 - NEXT_E is the edge where new generated code should be attached.
1247 - CONTEXT_LOOP is the loop in which the generated code will be placed
1248 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1250 static edge
1251 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1252 edge next_e, htab_t bb_pbb_mapping, int level,
1253 ivs_params_p ip)
1255 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1256 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1258 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1259 return last_e;
1262 /* Translates a CLAST statement STMT to GCC representation in the
1263 context of a SESE.
1265 - NEXT_E is the edge where new generated code should be attached.
1266 - CONTEXT_LOOP is the loop in which the generated code will be placed
1267 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1269 static edge
1270 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1271 htab_t bb_pbb_mapping, int level, ivs_params_p ip)
1273 if (!stmt)
1274 return next_e;
1276 if (CLAST_STMT_IS_A (stmt, stmt_root))
1277 ; /* Do nothing. */
1279 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1280 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1281 next_e, bb_pbb_mapping, ip);
1283 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1284 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1285 next_e, bb_pbb_mapping, level, ip);
1287 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1288 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1289 next_e, bb_pbb_mapping, level, ip);
1291 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1292 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1293 next_e, bb_pbb_mapping, level, ip);
1295 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1296 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1297 next_e, level, ip);
1298 else
1299 gcc_unreachable();
1301 recompute_all_dominators ();
1302 graphite_verify ();
1304 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1305 level, ip);
1308 /* Add parameter and iterator names to the CloogUnionDomain. */
1310 static CloogUnionDomain *
1311 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1312 int nb_scattering_dims, htab_t params_index)
1314 sese region = SCOP_REGION (scop);
1315 int i;
1316 int nb_iterators = scop_max_loop_depth (scop);
1317 int nb_parameters = SESE_PARAMS (region).length ();
1318 mpz_t bound_one, bound_two;
1320 mpz_init (bound_one);
1321 mpz_init (bound_two);
1323 for (i = 0; i < nb_parameters; i++)
1325 tree param = SESE_PARAMS (region)[i];
1326 const char *name = get_name (param);
1327 int len;
1328 char *parameter;
1330 if (!name)
1331 name = "T";
1333 len = strlen (name);
1334 len += 17;
1335 parameter = XNEWVEC (char, len + 1);
1336 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1337 save_clast_name_index (params_index, parameter, i, i, bound_one,
1338 bound_two);
1339 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1340 parameter);
1341 compute_bounds_for_param (scop, i, bound_one, bound_two);
1342 free (parameter);
1345 mpz_clear (bound_one);
1346 mpz_clear (bound_two);
1348 for (i = 0; i < nb_iterators; i++)
1350 int len = 4 + 16;
1351 char *iterator;
1352 iterator = XNEWVEC (char, len);
1353 snprintf (iterator, len, "git_%d", i);
1354 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1355 iterator);
1356 free (iterator);
1359 for (i = 0; i < nb_scattering_dims; i++)
1361 int len = 5 + 16;
1362 char *scattering;
1363 scattering = XNEWVEC (char, len);
1364 snprintf (scattering, len, "scat_%d", i);
1365 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1366 scattering);
1367 free (scattering);
1370 return union_domain;
1373 /* Initialize a CLooG input file. */
1375 static FILE *
1376 init_cloog_input_file (int scop_number)
1378 FILE *graphite_out_file;
1379 int len = strlen (dump_base_name);
1380 char *dumpname = XNEWVEC (char, len + 25);
1381 char *s_scop_number = XNEWVEC (char, 15);
1383 memcpy (dumpname, dump_base_name, len + 1);
1384 strip_off_ending (dumpname, len);
1385 sprintf (s_scop_number, ".%d", scop_number);
1386 strcat (dumpname, s_scop_number);
1387 strcat (dumpname, ".cloog");
1388 graphite_out_file = fopen (dumpname, "w+b");
1390 if (graphite_out_file == 0)
1391 fatal_error ("can%'t open %s for writing: %m", dumpname);
1393 free (dumpname);
1395 return graphite_out_file;
1398 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1400 static
1401 isl_map *extend_scattering(isl_map *scattering, int new_dims)
1403 int old_dims, i;
1404 isl_space *space;
1405 isl_basic_map *change_scattering;
1406 isl_map *change_scattering_map;
1408 old_dims = isl_map_dim (scattering, isl_dim_out);
1410 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1411 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1413 for (i = 0; i < old_dims; i++)
1415 isl_constraint *c;
1416 c = isl_equality_alloc
1417 (isl_local_space_from_space (isl_space_copy (space)));
1418 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1419 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1420 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1423 for (i = old_dims; i < new_dims; i++)
1425 isl_constraint *c;
1426 c = isl_equality_alloc
1427 (isl_local_space_from_space (isl_space_copy (space)));
1428 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1429 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1432 change_scattering_map = isl_map_from_basic_map (change_scattering);
1433 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1434 return isl_map_apply_range (scattering, change_scattering_map);
1437 /* Build cloog union domain for SCoP. */
1439 static CloogUnionDomain *
1440 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1442 int i;
1443 poly_bb_p pbb;
1444 CloogUnionDomain *union_domain =
1445 cloog_union_domain_alloc (scop_nb_params (scop));
1447 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1449 CloogDomain *domain;
1450 CloogScattering *scattering;
1452 /* Dead code elimination: when the domain of a PBB is empty,
1453 don't generate code for the PBB. */
1454 if (isl_set_is_empty(pbb->domain))
1455 continue;
1457 domain = cloog_domain_from_isl_set(isl_set_copy(pbb->domain));
1458 scattering = cloog_scattering_from_isl_map(extend_scattering(isl_map_copy(pbb->transformed),
1459 nb_scattering_dims));
1461 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1462 scattering, pbb);
1465 return union_domain;
1468 /* Return the options that will be used in GLOOG. */
1470 static CloogOptions *
1471 set_cloog_options (void)
1473 CloogOptions *options = cloog_options_malloc (cloog_state);
1475 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1476 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1477 we pass an incomplete program to cloog. */
1478 options->language = CLOOG_LANGUAGE_C;
1480 /* Enable complex equality spreading: removes dummy statements
1481 (assignments) in the generated code which repeats the
1482 substitution equations for statements. This is useless for
1483 GLooG. */
1484 options->esp = 1;
1486 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1487 options->quiet = 1;
1489 /* Allow cloog to build strides with a stride width different to one.
1490 This example has stride = 4:
1492 for (i = 0; i < 20; i += 4)
1493 A */
1494 options->strides = 1;
1496 /* We want the clast to provide the iteration domains of the executed loops.
1497 This allows us to derive minimal/maximal values for the induction
1498 variables. */
1499 options->save_domains = 1;
1501 /* Disable optimizations and make cloog generate source code closer to the
1502 input. This is useful for debugging, but later we want the optimized
1503 code.
1505 XXX: We can not disable optimizations, as loop blocking is not working
1506 without them. */
1507 if (0)
1509 options->f = -1;
1510 options->l = INT_MAX;
1513 return options;
1516 /* Prints STMT to STDERR. */
1518 void
1519 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1521 CloogOptions *options = set_cloog_options ();
1523 clast_pprint (file, stmt, 0, options);
1524 cloog_options_free (options);
1527 /* Prints STMT to STDERR. */
1529 DEBUG_FUNCTION void
1530 debug_clast_stmt (struct clast_stmt *stmt)
1532 print_clast_stmt (stderr, stmt);
1535 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1537 static
1538 int get_max_scattering_dimensions (scop_p scop)
1540 int i;
1541 poly_bb_p pbb;
1542 int scattering_dims = 0;
1544 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1546 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1547 if (pbb_scatt_dims > scattering_dims)
1548 scattering_dims = pbb_scatt_dims;
1551 return scattering_dims;
1554 static CloogInput *
1555 generate_cloog_input (scop_p scop, htab_t params_index)
1557 CloogUnionDomain *union_domain;
1558 CloogInput *cloog_input;
1559 CloogDomain *context;
1560 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1562 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1563 union_domain = add_names_to_union_domain (scop, union_domain,
1564 nb_scattering_dims,
1565 params_index);
1566 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1568 cloog_input = cloog_input_alloc (context, union_domain);
1570 return cloog_input;
1573 /* Translate SCOP to a CLooG program and clast. These two
1574 representations should be freed together: a clast cannot be used
1575 without a program. */
1577 static struct clast_stmt *
1578 scop_to_clast (scop_p scop, htab_t params_index)
1580 CloogInput *cloog_input;
1581 struct clast_stmt *clast;
1582 CloogOptions *options = set_cloog_options ();
1584 cloog_input = generate_cloog_input (scop, params_index);
1586 /* Dump a .cloog input file, if requested. This feature is only
1587 enabled in the Graphite branch. */
1588 if (0)
1590 static size_t file_scop_number = 0;
1591 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1592 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1595 clast = cloog_clast_create_from_input (cloog_input, options);
1597 cloog_options_free (options);
1598 return clast;
1601 /* Prints to FILE the code generated by CLooG for SCOP. */
1603 void
1604 print_generated_program (FILE *file, scop_p scop)
1606 CloogOptions *options = set_cloog_options ();
1607 htab_t params_index;
1608 struct clast_stmt *clast;
1610 params_index = htab_create (10, clast_name_index_elt_info,
1611 eq_clast_name_indexes, free_clast_name_index);
1613 clast = scop_to_clast (scop, params_index);
1615 fprintf (file, " (clast: \n");
1616 clast_pprint (file, clast, 0, options);
1617 fprintf (file, " )\n");
1619 cloog_options_free (options);
1620 cloog_clast_free (clast);
1623 /* Prints to STDERR the code generated by CLooG for SCOP. */
1625 DEBUG_FUNCTION void
1626 debug_generated_program (scop_p scop)
1628 print_generated_program (stderr, scop);
1631 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1632 the given SCOP. Return true if code generation succeeded.
1633 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1636 bool
1637 gloog (scop_p scop, htab_t bb_pbb_mapping)
1639 vec<tree> newivs;
1640 newivs.create (10);
1641 loop_p context_loop;
1642 sese region = SCOP_REGION (scop);
1643 ifsese if_region = NULL;
1644 htab_t newivs_index, params_index;
1645 struct clast_stmt *clast;
1646 struct ivs_params ip;
1648 timevar_push (TV_GRAPHITE_CODE_GEN);
1649 gloog_error = false;
1651 params_index = htab_create (10, clast_name_index_elt_info,
1652 eq_clast_name_indexes, free_clast_name_index);
1654 clast = scop_to_clast (scop, params_index);
1656 if (dump_file && (dump_flags & TDF_DETAILS))
1658 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1659 print_clast_stmt (dump_file, clast);
1660 fprintf (dump_file, "\n");
1663 recompute_all_dominators ();
1664 graphite_verify ();
1666 if_region = move_sese_in_condition (region);
1667 sese_insert_phis_for_liveouts (region,
1668 if_region->region->exit->src,
1669 if_region->false_region->exit,
1670 if_region->true_region->exit);
1671 recompute_all_dominators ();
1672 graphite_verify ();
1674 context_loop = SESE_ENTRY (region)->src->loop_father;
1675 newivs_index = htab_create (10, clast_name_index_elt_info,
1676 eq_clast_name_indexes, free_clast_name_index);
1678 ip.newivs = &newivs;
1679 ip.newivs_index = newivs_index;
1680 ip.params = SESE_PARAMS (region);
1681 ip.params_index = params_index;
1682 ip.region = region;
1684 translate_clast (context_loop, clast, if_region->true_region->entry,
1685 bb_pbb_mapping, 0, &ip);
1686 graphite_verify ();
1687 scev_reset ();
1688 recompute_all_dominators ();
1689 graphite_verify ();
1691 if (gloog_error)
1692 set_ifsese_condition (if_region, integer_zero_node);
1694 free (if_region->true_region);
1695 free (if_region->region);
1696 free (if_region);
1698 htab_delete (newivs_index);
1699 htab_delete (params_index);
1700 newivs.release ();
1701 cloog_clast_free (clast);
1702 timevar_pop (TV_GRAPHITE_CODE_GEN);
1704 if (dump_file && (dump_flags & TDF_DETAILS))
1706 loop_p loop;
1707 loop_iterator li;
1708 int num_no_dependency = 0;
1710 FOR_EACH_LOOP (li, loop, 0)
1711 if (loop->can_be_parallel)
1712 num_no_dependency++;
1714 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1715 num_no_dependency);
1718 return !gloog_error;
1720 #endif