2013-10-22 Jan-Benedict Glaw <jbglaw@lug-owl.de>
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob7db4da6eac29db9ff0b34067fbce4118247dfc14
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 "tree-ssa.h"
40 #include "tree-pass.h"
41 #include "cfgloop.h"
42 #include "tree-chrec.h"
43 #include "tree-data-ref.h"
44 #include "tree-scalar-evolution.h"
45 #include "sese.h"
47 #ifdef HAVE_cloog
48 #include "cloog/cloog.h"
49 #include "graphite-poly.h"
50 #include "graphite-clast-to-gimple.h"
51 #include "graphite-htab.h"
53 typedef const struct clast_expr *clast_name_p;
55 #ifndef CLOOG_LANGUAGE_C
56 #define CLOOG_LANGUAGE_C LANGUAGE_C
57 #endif
60 /* Converts a GMP constant VAL to a tree and returns it. */
62 static tree
63 gmp_cst_to_tree (tree type, mpz_t val)
65 tree t = type ? type : integer_type_node;
66 mpz_t tmp;
67 double_int di;
69 mpz_init (tmp);
70 mpz_set (tmp, val);
71 di = mpz_get_double_int (t, tmp, true);
72 mpz_clear (tmp);
74 return double_int_to_tree (t, di);
77 /* Sets RES to the min of V1 and V2. */
79 static void
80 value_min (mpz_t res, mpz_t v1, mpz_t v2)
82 if (mpz_cmp (v1, v2) < 0)
83 mpz_set (res, v1);
84 else
85 mpz_set (res, v2);
88 /* Sets RES to the max of V1 and V2. */
90 static void
91 value_max (mpz_t res, mpz_t v1, mpz_t v2)
93 if (mpz_cmp (v1, v2) < 0)
94 mpz_set (res, v2);
95 else
96 mpz_set (res, v1);
100 /* This flag is set when an error occurred during the translation of
101 CLAST to Gimple. */
102 static bool gloog_error;
104 /* Verifies properties that GRAPHITE should maintain during translation. */
106 static inline void
107 graphite_verify (void)
109 #ifdef ENABLE_CHECKING
110 verify_loop_structure ();
111 verify_loop_closed_ssa (true);
112 #endif
115 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
116 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
117 upper bounds that can be inferred from the polyhedral representation. */
119 typedef struct clast_name_index {
120 int index;
121 int level;
122 mpz_t bound_one, bound_two;
123 const char *name;
124 /* If free_name is set, the content of name was allocated by us and needs
125 to be freed. */
126 char *free_name;
127 } *clast_name_index_p;
129 /* Helper for hashing clast_name_index. */
131 struct clast_index_hasher
133 typedef clast_name_index value_type;
134 typedef clast_name_index compare_type;
135 static inline hashval_t hash (const value_type *);
136 static inline bool equal (const value_type *, const compare_type *);
137 static inline void remove (value_type *);
140 /* Computes a hash function for database element E. */
142 inline hashval_t
143 clast_index_hasher::hash (const value_type *e)
145 hashval_t hash = 0;
147 int length = strlen (e->name);
148 int i;
150 for (i = 0; i < length; ++i)
151 hash = hash | (e->name[i] << (i % 4));
153 return hash;
156 /* Compares database elements ELT1 and ELT2. */
158 inline bool
159 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
161 return strcmp (elt1->name, elt2->name) == 0;
164 /* Free the memory taken by a clast_name_index struct. */
166 inline void
167 clast_index_hasher::remove (value_type *c)
169 if (c->free_name)
170 free (c->free_name);
171 mpz_clear (c->bound_one);
172 mpz_clear (c->bound_two);
173 free (c);
176 typedef hash_table <clast_index_hasher> clast_index_htab_type;
178 /* Returns a pointer to a new element of type clast_name_index_p built
179 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
181 static inline clast_name_index_p
182 new_clast_name_index (const char *name, int index, int level,
183 mpz_t bound_one, mpz_t bound_two)
185 clast_name_index_p res = XNEW (struct clast_name_index);
186 char *new_name = XNEWVEC (char, strlen (name) + 1);
187 strcpy (new_name, name);
189 res->name = new_name;
190 res->free_name = new_name;
191 res->level = level;
192 res->index = index;
193 mpz_init (res->bound_one);
194 mpz_init (res->bound_two);
195 mpz_set (res->bound_one, bound_one);
196 mpz_set (res->bound_two, bound_two);
197 return res;
200 /* For a given clast NAME, returns -1 if NAME is not in the
201 INDEX_TABLE, otherwise returns the loop level for the induction
202 variable NAME, or if it is a parameter, the parameter number in the
203 vector of parameters. */
205 static inline int
206 clast_name_to_level (clast_name_p name, clast_index_htab_type index_table)
208 struct clast_name_index tmp;
209 clast_name_index **slot;
211 gcc_assert (name->type == clast_expr_name);
212 tmp.name = ((const struct clast_name *) name)->name;
213 tmp.free_name = NULL;
215 slot = index_table.find_slot (&tmp, NO_INSERT);
217 if (slot && *slot)
218 return ((struct clast_name_index *) *slot)->level;
220 return -1;
223 /* For a given clast NAME, returns -1 if it does not correspond to any
224 parameter, or otherwise, returns the index in the PARAMS or
225 SCATTERING_DIMENSIONS vector. */
227 static inline int
228 clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table)
230 struct clast_name_index tmp;
231 clast_name_index **slot;
233 tmp.name = ((const struct clast_name *) name)->name;
234 tmp.free_name = NULL;
236 slot = index_table.find_slot (&tmp, NO_INSERT);
238 if (slot && *slot)
239 return (*slot)->index;
241 return -1;
244 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
245 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
246 found in the INDEX_TABLE, false otherwise. */
248 static inline bool
249 clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table,
250 mpz_t bound_one, mpz_t bound_two)
252 struct clast_name_index tmp;
253 clast_name_index **slot;
255 tmp.name = name->name;
256 tmp.free_name = NULL;
258 slot = index_table.find_slot (&tmp, NO_INSERT);
260 if (slot && *slot)
262 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
263 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
264 return true;
267 return false;
270 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
272 static inline void
273 save_clast_name_index (clast_index_htab_type index_table, const char *name,
274 int index, int level, mpz_t bound_one, mpz_t bound_two)
276 struct clast_name_index tmp;
277 clast_name_index **slot;
279 tmp.name = name;
280 tmp.free_name = NULL;
281 slot = index_table.find_slot (&tmp, INSERT);
283 if (slot)
285 free (*slot);
287 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
292 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
293 induction variable in NEWIVS.
295 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
296 parameter in PARAMS. */
298 typedef struct ivs_params {
299 vec<tree> params, *newivs;
300 clast_index_htab_type newivs_index, params_index;
301 sese region;
302 } *ivs_params_p;
304 /* Returns the tree variable from the name NAME that was given in
305 Cloog representation. */
307 static tree
308 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
310 int index;
312 if (ip->params.exists () && ip->params_index.is_created ())
314 index = clast_name_to_index (name, ip->params_index);
316 if (index >= 0)
317 return ip->params[index];
320 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
321 index = clast_name_to_index (name, ip->newivs_index);
322 gcc_assert (index >= 0);
324 return (*ip->newivs)[index];
327 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
329 static tree
330 max_precision_type (tree type1, tree type2)
332 enum machine_mode mode;
333 int p1, p2, precision;
334 tree type;
336 if (POINTER_TYPE_P (type1))
337 return type1;
339 if (POINTER_TYPE_P (type2))
340 return type2;
342 if (TYPE_UNSIGNED (type1)
343 && TYPE_UNSIGNED (type2))
344 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
346 p1 = TYPE_PRECISION (type1);
347 p2 = TYPE_PRECISION (type2);
349 if (p1 > p2)
350 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
351 else
352 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
354 if (precision > BITS_PER_WORD)
356 gloog_error = true;
357 return integer_type_node;
360 mode = smallest_mode_for_size (precision, MODE_INT);
361 precision = GET_MODE_PRECISION (mode);
362 type = build_nonstandard_integer_type (precision, false);
364 if (!type)
366 gloog_error = true;
367 return integer_type_node;
370 return type;
373 static tree
374 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
376 /* Converts a Cloog reduction expression R with reduction operation OP
377 to a GCC expression tree of type TYPE. */
379 static tree
380 clast_to_gcc_expression_red (tree type, enum tree_code op,
381 struct clast_reduction *r, ivs_params_p ip)
383 int i;
384 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
385 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
387 for (i = 1; i < r->n; i++)
389 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
390 res = fold_build2 (op, type, res, t);
393 return res;
396 /* Converts a Cloog AST expression E back to a GCC expression tree of
397 type TYPE. */
399 static tree
400 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
402 switch (e->type)
404 case clast_expr_name:
406 return clast_name_to_gcc ((struct clast_name *) e, ip);
408 case clast_expr_term:
410 struct clast_term *t = (struct clast_term *) e;
412 if (t->var)
414 if (mpz_cmp_si (t->val, 1) == 0)
416 tree name = clast_to_gcc_expression (type, t->var, ip);
418 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
419 name = convert_to_ptrofftype (name);
421 name = fold_convert (type, name);
422 return name;
425 else if (mpz_cmp_si (t->val, -1) == 0)
427 tree name = clast_to_gcc_expression (type, t->var, ip);
429 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
430 name = convert_to_ptrofftype (name);
432 name = fold_convert (type, name);
434 return fold_build1 (NEGATE_EXPR, type, name);
436 else
438 tree name = clast_to_gcc_expression (type, t->var, ip);
439 tree cst = gmp_cst_to_tree (type, t->val);
441 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
442 name = convert_to_ptrofftype (name);
444 name = fold_convert (type, name);
446 if (!POINTER_TYPE_P (type))
447 return fold_build2 (MULT_EXPR, type, cst, name);
449 gloog_error = true;
450 return cst;
453 else
454 return gmp_cst_to_tree (type, t->val);
457 case clast_expr_red:
459 struct clast_reduction *r = (struct clast_reduction *) e;
461 switch (r->type)
463 case clast_red_sum:
464 return clast_to_gcc_expression_red
465 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
466 r, ip);
468 case clast_red_min:
469 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
471 case clast_red_max:
472 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
474 default:
475 gcc_unreachable ();
477 break;
480 case clast_expr_bin:
482 struct clast_binary *b = (struct clast_binary *) e;
483 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
484 tree tl = clast_to_gcc_expression (type, lhs, ip);
485 tree tr = gmp_cst_to_tree (type, b->RHS);
487 switch (b->type)
489 case clast_bin_fdiv:
490 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
492 case clast_bin_cdiv:
493 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
495 case clast_bin_div:
496 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
498 case clast_bin_mod:
499 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
501 default:
502 gcc_unreachable ();
506 default:
507 gcc_unreachable ();
510 return NULL_TREE;
513 /* Return a type that could represent the values between BOUND_ONE and
514 BOUND_TWO. */
516 static tree
517 type_for_interval (mpz_t bound_one, mpz_t bound_two)
519 bool unsigned_p;
520 tree type;
521 enum machine_mode mode;
522 int wider_precision;
523 int precision = MAX (mpz_sizeinbase (bound_one, 2),
524 mpz_sizeinbase (bound_two, 2));
526 if (precision > BITS_PER_WORD)
528 gloog_error = true;
529 return integer_type_node;
532 if (mpz_cmp (bound_one, bound_two) <= 0)
533 unsigned_p = (mpz_sgn (bound_one) >= 0);
534 else
535 unsigned_p = (mpz_sgn (bound_two) >= 0);
537 mode = smallest_mode_for_size (precision, MODE_INT);
538 wider_precision = GET_MODE_PRECISION (mode);
540 /* As we want to generate signed types as much as possible, try to
541 fit the interval [bound_one, bound_two] in a signed type. For example,
542 supposing that we have the interval [0, 100], instead of
543 generating unsigned char, we want to generate a signed char. */
544 if (unsigned_p && precision < wider_precision)
545 unsigned_p = false;
547 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
549 if (!type)
551 gloog_error = true;
552 return integer_type_node;
555 return type;
558 /* Return a type that could represent the integer value VAL, or
559 otherwise return NULL_TREE. */
561 static tree
562 type_for_value (mpz_t val)
564 return type_for_interval (val, val);
567 static tree
568 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
570 /* Return the type for the clast_term T. Initializes BOUND_ONE and
571 BOUND_TWO to the bounds of the term. */
573 static tree
574 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
575 mpz_t bound_two)
577 tree type;
578 gcc_assert (t->expr.type == clast_expr_term);
580 if (!t->var)
582 mpz_set (bound_one, t->val);
583 mpz_set (bound_two, t->val);
584 return type_for_value (t->val);
587 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
589 mpz_mul (bound_one, bound_one, t->val);
590 mpz_mul (bound_two, bound_two, t->val);
592 return max_precision_type (type, type_for_interval (bound_one, bound_two));
595 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
596 and BOUND_TWO to the bounds of the reduction expression. */
598 static tree
599 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
600 mpz_t bound_one, mpz_t bound_two)
602 int i;
603 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
604 mpz_t b1, b2, m1, m2;
606 if (r->n == 1)
607 return type;
609 mpz_init (b1);
610 mpz_init (b2);
611 mpz_init (m1);
612 mpz_init (m2);
614 for (i = 1; i < r->n; i++)
616 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
617 type = max_precision_type (type, t);
619 switch (r->type)
621 case clast_red_sum:
622 value_min (m1, bound_one, bound_two);
623 value_min (m2, b1, b2);
624 mpz_add (bound_one, m1, m2);
626 value_max (m1, bound_one, bound_two);
627 value_max (m2, b1, b2);
628 mpz_add (bound_two, m1, m2);
629 break;
631 case clast_red_min:
632 value_min (bound_one, bound_one, bound_two);
633 value_min (bound_two, b1, b2);
634 break;
636 case clast_red_max:
637 value_max (bound_one, bound_one, bound_two);
638 value_max (bound_two, b1, b2);
639 break;
641 default:
642 gcc_unreachable ();
643 break;
647 mpz_clear (b1);
648 mpz_clear (b2);
649 mpz_clear (m1);
650 mpz_clear (m2);
652 /* Return a type that can represent the result of the reduction. */
653 return max_precision_type (type, type_for_interval (bound_one, bound_two));
656 /* Return the type for the clast_binary B used in STMT. */
658 static tree
659 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
660 mpz_t bound_two)
662 mpz_t one;
663 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
664 bound_one, bound_two);
665 tree r = type_for_value (b->RHS);
666 tree type = max_precision_type (l, r);
668 switch (b->type)
670 case clast_bin_fdiv:
671 mpz_mdiv (bound_one, bound_one, b->RHS);
672 mpz_mdiv (bound_two, bound_two, b->RHS);
673 break;
675 case clast_bin_cdiv:
676 mpz_mdiv (bound_one, bound_one, b->RHS);
677 mpz_mdiv (bound_two, bound_two, b->RHS);
678 mpz_init (one);
679 mpz_add (bound_one, bound_one, one);
680 mpz_add (bound_two, bound_two, one);
681 mpz_clear (one);
682 break;
684 case clast_bin_div:
685 mpz_div (bound_one, bound_one, b->RHS);
686 mpz_div (bound_two, bound_two, b->RHS);
687 break;
689 case clast_bin_mod:
690 mpz_mod (bound_one, bound_one, b->RHS);
691 mpz_mod (bound_two, bound_two, b->RHS);
692 break;
694 default:
695 gcc_unreachable ();
698 /* Return a type that can represent the result of the reduction. */
699 return max_precision_type (type, type_for_interval (bound_one, bound_two));
702 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
703 BOUND_TWO to the bounds of the term. */
705 static tree
706 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
707 mpz_t bound_two)
709 bool found = false;
711 if (ip->params.exists () && ip->params_index.is_created ())
712 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
714 if (!found)
716 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
717 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
718 bound_two);
719 gcc_assert (found);
722 return TREE_TYPE (clast_name_to_gcc (name, ip));
725 /* Returns the type for the CLAST expression E when used in statement
726 STMT. */
728 static tree
729 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
730 mpz_t bound_two)
732 switch (e->type)
734 case clast_expr_term:
735 return type_for_clast_term ((struct clast_term *) e, ip,
736 bound_one, bound_two);
738 case clast_expr_red:
739 return type_for_clast_red ((struct clast_reduction *) e, ip,
740 bound_one, bound_two);
742 case clast_expr_bin:
743 return type_for_clast_bin ((struct clast_binary *) e, ip,
744 bound_one, bound_two);
746 case clast_expr_name:
747 return type_for_clast_name ((struct clast_name *) e, ip,
748 bound_one, bound_two);
750 default:
751 gcc_unreachable ();
754 return NULL_TREE;
757 /* Returns true if the clast expression E is a constant with VALUE. */
759 static bool
760 clast_expr_const_value_p (struct clast_expr *e, int value)
762 struct clast_term *t;
763 if (e->type != clast_expr_term)
764 return false;
765 t = (struct clast_term *)e;
766 if (t->var)
767 return false;
768 return 0 == mpz_cmp_si (t->val, value);
771 /* Translates a clast equation CLEQ to a tree. */
773 static tree
774 graphite_translate_clast_equation (struct clast_equation *cleq,
775 ivs_params_p ip)
777 enum tree_code comp;
778 tree type, lhs, rhs, ltype, rtype;
779 mpz_t bound_one, bound_two;
780 struct clast_expr *clhs, *crhs;
782 clhs = cleq->LHS;
783 crhs = cleq->RHS;
784 if (cleq->sign == 0)
785 comp = EQ_EXPR;
786 else if (cleq->sign > 0)
787 comp = GE_EXPR;
788 else
789 comp = LE_EXPR;
791 /* Special cases to reduce range of arguments to hopefully
792 don't need types with larger precision than the input. */
793 if (crhs->type == clast_expr_red
794 && comp != EQ_EXPR)
796 struct clast_reduction *r = (struct clast_reduction *) crhs;
797 /* X >= A+1 --> X > A and
798 X <= A-1 --> X < A */
799 if (r->n == 2
800 && r->type == clast_red_sum
801 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
803 crhs = r->elts[0];
804 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
808 mpz_init (bound_one);
809 mpz_init (bound_two);
811 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
812 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
814 mpz_clear (bound_one);
815 mpz_clear (bound_two);
816 type = max_precision_type (ltype, rtype);
818 lhs = clast_to_gcc_expression (type, clhs, ip);
819 rhs = clast_to_gcc_expression (type, crhs, ip);
821 return fold_build2 (comp, boolean_type_node, lhs, rhs);
824 /* Creates the test for the condition in STMT. */
826 static tree
827 graphite_create_guard_cond_expr (struct clast_guard *stmt,
828 ivs_params_p ip)
830 tree cond = NULL;
831 int i;
833 for (i = 0; i < stmt->n; i++)
835 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
837 if (cond)
838 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
839 else
840 cond = eq;
843 return cond;
846 /* Creates a new if region corresponding to Cloog's guard. */
848 static edge
849 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
850 ivs_params_p ip)
852 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
853 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
854 return exit_edge;
857 /* Compute the lower bound LOW and upper bound UP for the parameter
858 PARAM in scop SCOP based on the constraints in the context. */
860 static void
861 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
863 isl_int v;
864 isl_aff *aff = isl_aff_zero_on_domain
865 (isl_local_space_from_space (isl_set_get_space (scop->context)));
867 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
869 isl_int_init (v);
870 isl_set_min (scop->context, aff, &v);
871 isl_int_get_gmp (v, low);
872 isl_set_max (scop->context, aff, &v);
873 isl_int_get_gmp (v, up);
874 isl_int_clear (v);
875 isl_aff_free (aff);
878 /* Compute the lower bound LOW and upper bound UP for the induction
879 variable of loop LOOP.
881 FIXME: This one is not entirely correct, as min/max expressions in the
882 calculation can yield to incorrect results. To be completely
883 correct, we need to evaluate each subexpression generated by
884 CLooG. CLooG does not yet support this, so this is as good as
885 it can be. */
887 static void
888 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
890 isl_set *domain;
891 isl_aff *dimension;
892 isl_local_space *local_space;
893 isl_int isl_value;
894 enum isl_lp_result lp_result;
896 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
897 local_space = isl_local_space_from_space (isl_set_get_space (domain));
898 dimension = isl_aff_zero_on_domain (local_space);
899 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
900 isl_set_dim (domain, isl_dim_set) - 1,
903 isl_int_init (isl_value);
905 lp_result = isl_set_min (domain, dimension, &isl_value);
906 assert (lp_result == isl_lp_ok);
907 isl_int_get_gmp (isl_value, low);
909 lp_result = isl_set_max (domain, dimension, &isl_value);
910 assert (lp_result == isl_lp_ok);
911 isl_int_get_gmp (isl_value, up);
913 isl_int_clear (isl_value);
914 isl_set_free (domain);
915 isl_aff_free (dimension);
918 /* Returns the type for the induction variable for the loop translated
919 from STMT_FOR. */
921 static tree
922 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
924 mpz_t bound_one, bound_two;
925 tree lb_type, ub_type;
927 mpz_init (bound_one);
928 mpz_init (bound_two);
930 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
931 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
933 mpz_clear (bound_one);
934 mpz_clear (bound_two);
936 return max_precision_type (lb_type, ub_type);
939 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
940 induction variable for the new LOOP. New LOOP is attached to CFG
941 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
942 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
943 CLooG's scattering name to the induction variable created for the
944 loop of STMT. The new induction variable is inserted in the NEWIVS
945 vector and is of type TYPE. */
947 static struct loop *
948 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
949 loop_p outer, tree type, tree lb, tree ub,
950 int level, ivs_params_p ip)
952 mpz_t low, up;
954 tree stride = gmp_cst_to_tree (type, stmt->stride);
955 tree ivvar = create_tmp_var (type, "graphite_IV");
956 tree iv, iv_after_increment;
957 loop_p loop = create_empty_loop_on_edge
958 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
959 outer ? outer : entry_edge->src->loop_father);
961 mpz_init (low);
962 mpz_init (up);
963 compute_bounds_for_loop (stmt, low, up);
964 save_clast_name_index (ip->newivs_index, stmt->iterator,
965 (*ip->newivs).length (), level, low, up);
966 mpz_clear (low);
967 mpz_clear (up);
968 (*ip->newivs).safe_push (iv);
969 return loop;
972 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
973 induction variables of the loops around GBB in SESE. */
975 static void
976 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
977 ivs_params_p ip)
979 struct clast_stmt *t;
980 int depth = 0;
981 CloogStatement *cs = user_stmt->statement;
982 poly_bb_p pbb = (poly_bb_p) cs->usr;
983 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
984 mpz_t bound_one, bound_two;
986 mpz_init (bound_one);
987 mpz_init (bound_two);
989 for (t = user_stmt->substitutions; t; t = t->next, depth++)
991 struct clast_expr *expr = (struct clast_expr *)
992 ((struct clast_assignment *)t)->RHS;
993 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
994 tree new_name = clast_to_gcc_expression (type, expr, ip);
995 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
997 iv_map[old_loop->num] = new_name;
1000 mpz_clear (bound_one);
1001 mpz_clear (bound_two);
1004 /* Construct bb_pbb_def with BB and PBB. */
1006 static bb_pbb_def *
1007 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
1009 bb_pbb_def *bb_pbb_p;
1011 bb_pbb_p = XNEW (bb_pbb_def);
1012 bb_pbb_p->bb = bb;
1013 bb_pbb_p->pbb = pbb;
1015 return bb_pbb_p;
1018 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1020 static void
1021 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1022 bb_pbb_htab_type bb_pbb_mapping)
1024 bb_pbb_def tmp;
1025 bb_pbb_def **x;
1027 tmp.bb = bb;
1028 x = bb_pbb_mapping.find_slot (&tmp, INSERT);
1030 if (x && !*x)
1031 *x = new_bb_pbb_def (bb, pbb);
1034 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1036 poly_bb_p
1037 find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb)
1039 bb_pbb_def tmp;
1040 bb_pbb_def **slot;
1042 tmp.bb = bb;
1043 slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT);
1045 if (slot && *slot)
1046 return ((bb_pbb_def *) *slot)->pbb;
1048 return NULL;
1051 /* Return the scop of the loop and initialize PBBS the set of
1052 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1053 by the CLAST code generator between a generated basic_block and its
1054 related poly_bb_p. */
1056 scop_p
1057 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping,
1058 vec<poly_bb_p> *pbbs)
1060 unsigned i;
1061 basic_block *bbs = get_loop_body_in_dom_order (loop);
1062 scop_p scop = NULL;
1064 for (i = 0; i < loop->num_nodes; i++)
1066 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1068 if (pbb == NULL)
1069 continue;
1071 scop = PBB_SCOP (pbb);
1072 (*pbbs).safe_push (pbb);
1075 free (bbs);
1076 return scop;
1079 /* Translates a clast user statement STMT to gimple.
1081 - NEXT_E is the edge where new generated code should be attached.
1082 - CONTEXT_LOOP is the loop in which the generated code will be placed
1083 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1085 static edge
1086 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1087 bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip)
1089 int i, nb_loops;
1090 basic_block new_bb;
1091 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1092 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1093 vec<tree> iv_map;
1095 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
1096 return next_e;
1098 nb_loops = number_of_loops (cfun);
1099 iv_map.create (nb_loops);
1100 for (i = 0; i < nb_loops; i++)
1101 iv_map.quick_push (NULL_TREE);
1103 build_iv_mapping (iv_map, stmt, ip);
1104 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1105 next_e, iv_map, &gloog_error);
1106 iv_map.release ();
1108 new_bb = next_e->src;
1109 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1110 mark_virtual_operands_for_renaming (cfun);
1111 update_ssa (TODO_update_ssa);
1113 return next_e;
1116 /* Creates a new if region protecting the loop to be executed, if the execution
1117 count is zero (lb > ub). */
1119 static edge
1120 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1121 tree *type, tree *lb, tree *ub,
1122 ivs_params_p ip)
1124 tree cond_expr;
1125 edge exit_edge;
1127 *type = type_for_clast_for (stmt, ip);
1128 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1129 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1131 /* When ub is simply a constant or a parameter, use lb <= ub. */
1132 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1133 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1134 else
1136 tree one = (POINTER_TYPE_P (*type)
1137 ? convert_to_ptrofftype (integer_one_node)
1138 : fold_convert (*type, integer_one_node));
1139 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1140 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1141 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1142 even if we do not want this. However lb < ub + 1 is false, as
1143 expected. */
1144 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1145 : PLUS_EXPR, *type, *ub, one);
1147 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1150 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1152 return exit_edge;
1155 static edge
1156 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type,
1157 int, ivs_params_p);
1159 /* Create the loop for a clast for statement.
1161 - NEXT_E is the edge where new generated code should be attached.
1162 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1164 static edge
1165 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1166 edge next_e, bb_pbb_htab_type bb_pbb_mapping,
1167 int level, tree type, tree lb, tree ub,
1168 ivs_params_p ip)
1170 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1171 type, lb, ub, level, ip);
1172 edge last_e = single_exit (loop);
1173 edge to_body = single_succ_edge (loop->header);
1174 basic_block after = to_body->dest;
1176 /* Create a basic block for loop close phi nodes. */
1177 last_e = single_succ_edge (split_edge (last_e));
1179 /* Translate the body of the loop. */
1180 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1181 level + 1, ip);
1182 redirect_edge_succ_nodup (next_e, after);
1183 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1185 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1186 int scheduling_dim = isl_set_n_dim (domain);
1188 if (flag_loop_parallelize_all
1189 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1190 loop->can_be_parallel = true;
1192 return last_e;
1195 /* Translates a clast for statement STMT to gimple. First a guard is created
1196 protecting the loop, if it is executed zero times. In this guard we create
1197 the real loop structure.
1199 - NEXT_E is the edge where new generated code should be attached.
1200 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1202 static edge
1203 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1204 bb_pbb_htab_type bb_pbb_mapping, int level,
1205 ivs_params_p ip)
1207 tree type, lb, ub;
1208 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1209 &lb, &ub, ip);
1210 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1212 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1213 type, lb, ub, ip);
1214 return last_e;
1217 /* Translates a clast assignment STMT to gimple.
1219 - NEXT_E is the edge where new generated code should be attached.
1220 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1222 static edge
1223 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1224 int level, ivs_params_p ip)
1226 gimple_seq stmts;
1227 mpz_t bound_one, bound_two;
1228 tree type, new_name, var;
1229 edge res = single_succ_edge (split_edge (next_e));
1230 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1232 mpz_init (bound_one);
1233 mpz_init (bound_two);
1234 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1235 var = create_tmp_var (type, "graphite_var");
1236 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1237 &stmts, true, var);
1238 if (stmts)
1240 gsi_insert_seq_on_edge (next_e, stmts);
1241 gsi_commit_edge_inserts ();
1244 save_clast_name_index (ip->newivs_index, stmt->LHS,
1245 (*ip->newivs).length (), level,
1246 bound_one, bound_two);
1247 (*ip->newivs).safe_push (new_name);
1249 mpz_clear (bound_one);
1250 mpz_clear (bound_two);
1252 return res;
1255 /* Translates a clast guard statement STMT to gimple.
1257 - NEXT_E is the edge where new generated code should be attached.
1258 - CONTEXT_LOOP is the loop in which the generated code will be placed
1259 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1261 static edge
1262 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1263 edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level,
1264 ivs_params_p ip)
1266 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1267 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1269 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1270 return last_e;
1273 /* Translates a CLAST statement STMT to GCC representation in the
1274 context of a SESE.
1276 - NEXT_E is the edge where new generated code should be attached.
1277 - CONTEXT_LOOP is the loop in which the generated code will be placed
1278 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1280 static edge
1281 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1282 bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip)
1284 if (!stmt)
1285 return next_e;
1287 if (CLAST_STMT_IS_A (stmt, stmt_root))
1288 ; /* Do nothing. */
1290 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1291 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1292 next_e, bb_pbb_mapping, ip);
1294 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1295 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1296 next_e, bb_pbb_mapping, level, ip);
1298 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1299 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1300 next_e, bb_pbb_mapping, level, ip);
1302 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1303 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1304 next_e, bb_pbb_mapping, level, ip);
1306 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1307 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1308 next_e, level, ip);
1309 else
1310 gcc_unreachable ();
1312 recompute_all_dominators ();
1313 graphite_verify ();
1315 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1316 level, ip);
1319 /* Add parameter and iterator names to the CloogUnionDomain. */
1321 static CloogUnionDomain *
1322 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1323 int nb_scattering_dims,
1324 clast_index_htab_type params_index)
1326 sese region = SCOP_REGION (scop);
1327 int i;
1328 int nb_iterators = scop_max_loop_depth (scop);
1329 int nb_parameters = SESE_PARAMS (region).length ();
1330 mpz_t bound_one, bound_two;
1332 mpz_init (bound_one);
1333 mpz_init (bound_two);
1335 for (i = 0; i < nb_parameters; i++)
1337 tree param = SESE_PARAMS (region)[i];
1338 const char *name = get_name (param);
1339 int len;
1340 char *parameter;
1342 if (!name)
1343 name = "T";
1345 len = strlen (name);
1346 len += 17;
1347 parameter = XNEWVEC (char, len + 1);
1348 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1349 save_clast_name_index (params_index, parameter, i, i, bound_one,
1350 bound_two);
1351 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1352 parameter);
1353 compute_bounds_for_param (scop, i, bound_one, bound_two);
1354 free (parameter);
1357 mpz_clear (bound_one);
1358 mpz_clear (bound_two);
1360 for (i = 0; i < nb_iterators; i++)
1362 int len = 4 + 16;
1363 char *iterator;
1364 iterator = XNEWVEC (char, len);
1365 snprintf (iterator, len, "git_%d", i);
1366 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1367 iterator);
1368 free (iterator);
1371 for (i = 0; i < nb_scattering_dims; i++)
1373 int len = 5 + 16;
1374 char *scattering;
1375 scattering = XNEWVEC (char, len);
1376 snprintf (scattering, len, "scat_%d", i);
1377 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1378 scattering);
1379 free (scattering);
1382 return union_domain;
1385 /* Initialize a CLooG input file. */
1387 static FILE *
1388 init_cloog_input_file (int scop_number)
1390 FILE *graphite_out_file;
1391 int len = strlen (dump_base_name);
1392 char *dumpname = XNEWVEC (char, len + 25);
1393 char *s_scop_number = XNEWVEC (char, 15);
1395 memcpy (dumpname, dump_base_name, len + 1);
1396 strip_off_ending (dumpname, len);
1397 sprintf (s_scop_number, ".%d", scop_number);
1398 strcat (dumpname, s_scop_number);
1399 strcat (dumpname, ".cloog");
1400 graphite_out_file = fopen (dumpname, "w+b");
1402 if (graphite_out_file == 0)
1403 fatal_error ("can%'t open %s for writing: %m", dumpname);
1405 free (dumpname);
1407 return graphite_out_file;
1410 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1412 static
1413 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1415 int old_dims, i;
1416 isl_space *space;
1417 isl_basic_map *change_scattering;
1418 isl_map *change_scattering_map;
1420 old_dims = isl_map_dim (scattering, isl_dim_out);
1422 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1423 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1425 for (i = 0; i < old_dims; i++)
1427 isl_constraint *c;
1428 c = isl_equality_alloc
1429 (isl_local_space_from_space (isl_space_copy (space)));
1430 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1431 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1432 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1435 for (i = old_dims; i < new_dims; i++)
1437 isl_constraint *c;
1438 c = isl_equality_alloc
1439 (isl_local_space_from_space (isl_space_copy (space)));
1440 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1441 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1444 change_scattering_map = isl_map_from_basic_map (change_scattering);
1445 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1446 return isl_map_apply_range (scattering, change_scattering_map);
1449 /* Build cloog union domain for SCoP. */
1451 static CloogUnionDomain *
1452 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1454 int i;
1455 poly_bb_p pbb;
1456 CloogUnionDomain *union_domain =
1457 cloog_union_domain_alloc (scop_nb_params (scop));
1459 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1461 CloogDomain *domain;
1462 CloogScattering *scattering;
1464 /* Dead code elimination: when the domain of a PBB is empty,
1465 don't generate code for the PBB. */
1466 if (isl_set_is_empty (pbb->domain))
1467 continue;
1469 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1470 scattering = cloog_scattering_from_isl_map
1471 (extend_scattering (isl_map_copy (pbb->transformed),
1472 nb_scattering_dims));
1474 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1475 scattering, pbb);
1478 return union_domain;
1481 /* Return the options that will be used in GLOOG. */
1483 static CloogOptions *
1484 set_cloog_options (void)
1486 CloogOptions *options = cloog_options_malloc (cloog_state);
1488 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1489 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1490 we pass an incomplete program to cloog. */
1491 options->language = CLOOG_LANGUAGE_C;
1493 /* Enable complex equality spreading: removes dummy statements
1494 (assignments) in the generated code which repeats the
1495 substitution equations for statements. This is useless for
1496 GLooG. */
1497 options->esp = 1;
1499 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1500 options->quiet = 1;
1502 /* Allow cloog to build strides with a stride width different to one.
1503 This example has stride = 4:
1505 for (i = 0; i < 20; i += 4)
1506 A */
1507 options->strides = 1;
1509 /* We want the clast to provide the iteration domains of the executed loops.
1510 This allows us to derive minimal/maximal values for the induction
1511 variables. */
1512 options->save_domains = 1;
1514 /* Disable optimizations and make cloog generate source code closer to the
1515 input. This is useful for debugging, but later we want the optimized
1516 code.
1518 XXX: We can not disable optimizations, as loop blocking is not working
1519 without them. */
1520 if (0)
1522 options->f = -1;
1523 options->l = INT_MAX;
1526 return options;
1529 /* Prints STMT to STDERR. */
1531 void
1532 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1534 CloogOptions *options = set_cloog_options ();
1536 clast_pprint (file, stmt, 0, options);
1537 cloog_options_free (options);
1540 /* Prints STMT to STDERR. */
1542 DEBUG_FUNCTION void
1543 debug_clast_stmt (struct clast_stmt *stmt)
1545 print_clast_stmt (stderr, stmt);
1548 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1550 static
1551 int get_max_scattering_dimensions (scop_p scop)
1553 int i;
1554 poly_bb_p pbb;
1555 int scattering_dims = 0;
1557 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1559 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1560 if (pbb_scatt_dims > scattering_dims)
1561 scattering_dims = pbb_scatt_dims;
1564 return scattering_dims;
1567 static CloogInput *
1568 generate_cloog_input (scop_p scop, clast_index_htab_type params_index)
1570 CloogUnionDomain *union_domain;
1571 CloogInput *cloog_input;
1572 CloogDomain *context;
1573 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1575 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1576 union_domain = add_names_to_union_domain (scop, union_domain,
1577 nb_scattering_dims,
1578 params_index);
1579 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1581 cloog_input = cloog_input_alloc (context, union_domain);
1583 return cloog_input;
1586 /* Translate SCOP to a CLooG program and clast. These two
1587 representations should be freed together: a clast cannot be used
1588 without a program. */
1590 static struct clast_stmt *
1591 scop_to_clast (scop_p scop, clast_index_htab_type params_index)
1593 CloogInput *cloog_input;
1594 struct clast_stmt *clast;
1595 CloogOptions *options = set_cloog_options ();
1597 cloog_input = generate_cloog_input (scop, params_index);
1599 /* Dump a .cloog input file, if requested. This feature is only
1600 enabled in the Graphite branch. */
1601 if (0)
1603 static size_t file_scop_number = 0;
1604 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1605 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1608 clast = cloog_clast_create_from_input (cloog_input, options);
1610 cloog_options_free (options);
1611 return clast;
1614 /* Prints to FILE the code generated by CLooG for SCOP. */
1616 void
1617 print_generated_program (FILE *file, scop_p scop)
1619 CloogOptions *options = set_cloog_options ();
1620 clast_index_htab_type params_index;
1621 struct clast_stmt *clast;
1623 params_index.create (10);
1625 clast = scop_to_clast (scop, params_index);
1627 fprintf (file, " (clast: \n");
1628 clast_pprint (file, clast, 0, options);
1629 fprintf (file, " )\n");
1631 cloog_options_free (options);
1632 cloog_clast_free (clast);
1635 /* Prints to STDERR the code generated by CLooG for SCOP. */
1637 DEBUG_FUNCTION void
1638 debug_generated_program (scop_p scop)
1640 print_generated_program (stderr, scop);
1643 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1644 the given SCOP. Return true if code generation succeeded.
1645 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1648 bool
1649 gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping)
1651 vec<tree> newivs;
1652 newivs.create (10);
1653 loop_p context_loop;
1654 sese region = SCOP_REGION (scop);
1655 ifsese if_region = NULL;
1656 clast_index_htab_type newivs_index, params_index;
1657 struct clast_stmt *clast;
1658 struct ivs_params ip;
1660 timevar_push (TV_GRAPHITE_CODE_GEN);
1661 gloog_error = false;
1663 params_index.create (10);
1665 clast = scop_to_clast (scop, params_index);
1667 if (dump_file && (dump_flags & TDF_DETAILS))
1669 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1670 print_clast_stmt (dump_file, clast);
1671 fprintf (dump_file, "\n");
1674 recompute_all_dominators ();
1675 graphite_verify ();
1677 if_region = move_sese_in_condition (region);
1678 sese_insert_phis_for_liveouts (region,
1679 if_region->region->exit->src,
1680 if_region->false_region->exit,
1681 if_region->true_region->exit);
1682 recompute_all_dominators ();
1683 graphite_verify ();
1685 context_loop = SESE_ENTRY (region)->src->loop_father;
1686 newivs_index.create (10);
1688 ip.newivs = &newivs;
1689 ip.newivs_index = newivs_index;
1690 ip.params = SESE_PARAMS (region);
1691 ip.params_index = params_index;
1692 ip.region = region;
1694 translate_clast (context_loop, clast, if_region->true_region->entry,
1695 bb_pbb_mapping, 0, &ip);
1696 graphite_verify ();
1697 scev_reset ();
1698 recompute_all_dominators ();
1699 graphite_verify ();
1701 if (gloog_error)
1702 set_ifsese_condition (if_region, integer_zero_node);
1704 free (if_region->true_region);
1705 free (if_region->region);
1706 free (if_region);
1708 newivs_index.dispose ();
1709 params_index.dispose ();
1710 newivs.release ();
1711 cloog_clast_free (clast);
1712 timevar_pop (TV_GRAPHITE_CODE_GEN);
1714 if (dump_file && (dump_flags & TDF_DETAILS))
1716 loop_p loop;
1717 loop_iterator li;
1718 int num_no_dependency = 0;
1720 FOR_EACH_LOOP (li, loop, 0)
1721 if (loop->can_be_parallel)
1722 num_no_dependency++;
1724 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1725 num_no_dependency);
1728 return !gloog_error;
1730 #endif