gcc/ada/
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob41a893eb996a487ccf43fa48539a8e3225445a78
1 /* Translation of CLAST (CLooG AST) to Gimple.
2 Copyright (C) 2009-2014 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 <isl/val.h>
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35 #include <isl/val_gmp.h>
36 #if defined(__cplusplus)
38 #endif
39 #include <cloog/cloog.h>
40 #include <cloog/isl/domain.h>
41 #endif
43 #include "system.h"
44 #include "coretypes.h"
45 #include "diagnostic-core.h"
46 #include "tree.h"
47 #include "predict.h"
48 #include "vec.h"
49 #include "hashtab.h"
50 #include "hash-set.h"
51 #include "machmode.h"
52 #include "tm.h"
53 #include "hard-reg-set.h"
54 #include "input.h"
55 #include "function.h"
56 #include "dominance.h"
57 #include "cfg.h"
58 #include "basic-block.h"
59 #include "tree-ssa-alias.h"
60 #include "internal-fn.h"
61 #include "gimple-expr.h"
62 #include "is-a.h"
63 #include "gimple.h"
64 #include "gimple-iterator.h"
65 #include "gimplify-me.h"
66 #include "gimple-ssa.h"
67 #include "tree-ssa-loop-manip.h"
68 #include "tree-ssa-loop.h"
69 #include "tree-into-ssa.h"
70 #include "tree-pass.h"
71 #include "cfgloop.h"
72 #include "tree-chrec.h"
73 #include "tree-data-ref.h"
74 #include "tree-scalar-evolution.h"
75 #include "sese.h"
77 #ifdef HAVE_cloog
78 #include "cloog/cloog.h"
79 #include "graphite-poly.h"
80 #include "graphite-clast-to-gimple.h"
81 #include "graphite-htab.h"
83 typedef const struct clast_expr *clast_name_p;
85 #ifndef CLOOG_LANGUAGE_C
86 #define CLOOG_LANGUAGE_C LANGUAGE_C
87 #endif
90 /* Converts a GMP constant VAL to a tree and returns it. */
92 static tree
93 gmp_cst_to_tree (tree type, mpz_t val)
95 tree t = type ? type : integer_type_node;
96 mpz_t tmp;
98 mpz_init (tmp);
99 mpz_set (tmp, val);
100 wide_int wi = wi::from_mpz (t, tmp, true);
101 mpz_clear (tmp);
103 return wide_int_to_tree (t, wi);
106 /* Sets RES to the min of V1 and V2. */
108 static void
109 value_min (mpz_t res, mpz_t v1, mpz_t v2)
111 if (mpz_cmp (v1, v2) < 0)
112 mpz_set (res, v1);
113 else
114 mpz_set (res, v2);
117 /* Sets RES to the max of V1 and V2. */
119 static void
120 value_max (mpz_t res, mpz_t v1, mpz_t v2)
122 if (mpz_cmp (v1, v2) < 0)
123 mpz_set (res, v2);
124 else
125 mpz_set (res, v1);
129 /* This flag is set when an error occurred during the translation of
130 CLAST to Gimple. */
131 static bool graphite_regenerate_error;
133 /* Verifies properties that GRAPHITE should maintain during translation. */
135 static inline void
136 graphite_verify (void)
138 #ifdef ENABLE_CHECKING
139 verify_loop_structure ();
140 verify_loop_closed_ssa (true);
141 #endif
144 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
145 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
146 upper bounds that can be inferred from the polyhedral representation. */
148 typedef struct clast_name_index {
149 int index;
150 int level;
151 mpz_t bound_one, bound_two;
152 const char *name;
153 /* If free_name is set, the content of name was allocated by us and needs
154 to be freed. */
155 char *free_name;
156 } *clast_name_index_p;
158 /* Helper for hashing clast_name_index. */
160 struct clast_index_hasher
162 typedef clast_name_index value_type;
163 typedef clast_name_index compare_type;
164 static inline hashval_t hash (const value_type *);
165 static inline bool equal (const value_type *, const compare_type *);
166 static inline void remove (value_type *);
169 /* Computes a hash function for database element E. */
171 inline hashval_t
172 clast_index_hasher::hash (const value_type *e)
174 hashval_t hash = 0;
176 int length = strlen (e->name);
177 int i;
179 for (i = 0; i < length; ++i)
180 hash = hash | (e->name[i] << (i % 4));
182 return hash;
185 /* Compares database elements ELT1 and ELT2. */
187 inline bool
188 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
190 return strcmp (elt1->name, elt2->name) == 0;
193 /* Free the memory taken by a clast_name_index struct. */
195 inline void
196 clast_index_hasher::remove (value_type *c)
198 if (c->free_name)
199 free (c->free_name);
200 mpz_clear (c->bound_one);
201 mpz_clear (c->bound_two);
202 free (c);
205 typedef hash_table<clast_index_hasher> clast_index_htab_type;
207 /* Returns a pointer to a new element of type clast_name_index_p built
208 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
210 static inline clast_name_index_p
211 new_clast_name_index (const char *name, int index, int level,
212 mpz_t bound_one, mpz_t bound_two)
214 clast_name_index_p res = XNEW (struct clast_name_index);
215 char *new_name = XNEWVEC (char, strlen (name) + 1);
216 strcpy (new_name, name);
218 res->name = new_name;
219 res->free_name = new_name;
220 res->level = level;
221 res->index = index;
222 mpz_init (res->bound_one);
223 mpz_init (res->bound_two);
224 mpz_set (res->bound_one, bound_one);
225 mpz_set (res->bound_two, bound_two);
226 return res;
229 /* For a given clast NAME, returns -1 if NAME is not in the
230 INDEX_TABLE, otherwise returns the loop level for the induction
231 variable NAME, or if it is a parameter, the parameter number in the
232 vector of parameters. */
234 static inline int
235 clast_name_to_level (clast_name_p name, clast_index_htab_type *index_table)
237 struct clast_name_index tmp;
238 clast_name_index **slot;
240 gcc_assert (name->type == clast_expr_name);
241 tmp.name = ((const struct clast_name *) name)->name;
242 tmp.free_name = NULL;
244 slot = index_table->find_slot (&tmp, NO_INSERT);
246 if (slot && *slot)
247 return ((struct clast_name_index *) *slot)->level;
249 return -1;
252 /* For a given clast NAME, returns -1 if it does not correspond to any
253 parameter, or otherwise, returns the index in the PARAMS or
254 SCATTERING_DIMENSIONS vector. */
256 static inline int
257 clast_name_to_index (struct clast_name *name, clast_index_htab_type *index_table)
259 struct clast_name_index tmp;
260 clast_name_index **slot;
262 tmp.name = ((const struct clast_name *) name)->name;
263 tmp.free_name = NULL;
265 slot = index_table->find_slot (&tmp, NO_INSERT);
267 if (slot && *slot)
268 return (*slot)->index;
270 return -1;
273 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
274 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
275 found in the INDEX_TABLE, false otherwise. */
277 static inline bool
278 clast_name_to_lb_ub (struct clast_name *name,
279 clast_index_htab_type *index_table, mpz_t bound_one,
280 mpz_t bound_two)
282 struct clast_name_index tmp;
283 clast_name_index **slot;
285 tmp.name = name->name;
286 tmp.free_name = NULL;
288 slot = index_table->find_slot (&tmp, NO_INSERT);
290 if (slot && *slot)
292 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
293 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
294 return true;
297 return false;
300 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
302 static inline void
303 save_clast_name_index (clast_index_htab_type *index_table, const char *name,
304 int index, int level, mpz_t bound_one, mpz_t bound_two)
306 struct clast_name_index tmp;
307 clast_name_index **slot;
309 tmp.name = name;
310 tmp.free_name = NULL;
311 slot = index_table->find_slot (&tmp, INSERT);
313 if (slot)
315 free (*slot);
317 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
322 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
323 induction variable in NEWIVS.
325 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
326 parameter in PARAMS. */
328 typedef struct ivs_params {
329 vec<tree> params, *newivs;
330 clast_index_htab_type *newivs_index, *params_index;
331 sese region;
332 } *ivs_params_p;
334 /* Returns the tree variable from the name NAME that was given in
335 Cloog representation. */
337 static tree
338 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
340 int index;
342 if (ip->params.exists () && ip->params_index)
344 index = clast_name_to_index (name, ip->params_index);
346 if (index >= 0)
347 return ip->params[index];
350 gcc_assert (ip->newivs && ip->newivs_index);
351 index = clast_name_to_index (name, ip->newivs_index);
352 gcc_assert (index >= 0);
354 return (*ip->newivs)[index];
357 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
359 static tree
360 max_precision_type (tree type1, tree type2)
362 machine_mode mode;
363 int p1, p2, precision;
364 tree type;
366 if (POINTER_TYPE_P (type1))
367 return type1;
369 if (POINTER_TYPE_P (type2))
370 return type2;
372 if (TYPE_UNSIGNED (type1)
373 && TYPE_UNSIGNED (type2))
374 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
376 p1 = TYPE_PRECISION (type1);
377 p2 = TYPE_PRECISION (type2);
379 if (p1 > p2)
380 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
381 else
382 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
384 if (precision > BITS_PER_WORD)
386 graphite_regenerate_error = true;
387 return integer_type_node;
390 mode = smallest_mode_for_size (precision, MODE_INT);
391 precision = GET_MODE_PRECISION (mode);
392 type = build_nonstandard_integer_type (precision, false);
394 if (!type)
396 graphite_regenerate_error = true;
397 return integer_type_node;
400 return type;
403 static tree
404 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
406 /* Converts a Cloog reduction expression R with reduction operation OP
407 to a GCC expression tree of type TYPE. */
409 static tree
410 clast_to_gcc_expression_red (tree type, enum tree_code op,
411 struct clast_reduction *r, ivs_params_p ip)
413 int i;
414 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
415 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
417 for (i = 1; i < r->n; i++)
419 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
420 res = fold_build2 (op, type, res, t);
423 return res;
426 /* Converts a Cloog AST expression E back to a GCC expression tree of
427 type TYPE. */
429 static tree
430 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
432 switch (e->type)
434 case clast_expr_name:
436 return clast_name_to_gcc ((struct clast_name *) e, ip);
438 case clast_expr_term:
440 struct clast_term *t = (struct clast_term *) e;
442 if (t->var)
444 if (mpz_cmp_si (t->val, 1) == 0)
446 tree name = clast_to_gcc_expression (type, t->var, ip);
448 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
449 name = convert_to_ptrofftype (name);
451 name = fold_convert (type, name);
452 return name;
455 else if (mpz_cmp_si (t->val, -1) == 0)
457 tree name = clast_to_gcc_expression (type, t->var, ip);
459 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
460 name = convert_to_ptrofftype (name);
462 name = fold_convert (type, name);
464 return fold_build1 (NEGATE_EXPR, type, name);
466 else
468 tree name = clast_to_gcc_expression (type, t->var, ip);
469 tree cst = gmp_cst_to_tree (type, t->val);
471 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
472 name = convert_to_ptrofftype (name);
474 name = fold_convert (type, name);
476 if (!POINTER_TYPE_P (type))
477 return fold_build2 (MULT_EXPR, type, cst, name);
479 graphite_regenerate_error = true;
480 return cst;
483 else
484 return gmp_cst_to_tree (type, t->val);
487 case clast_expr_red:
489 struct clast_reduction *r = (struct clast_reduction *) e;
491 switch (r->type)
493 case clast_red_sum:
494 return clast_to_gcc_expression_red
495 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
496 r, ip);
498 case clast_red_min:
499 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
501 case clast_red_max:
502 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
504 default:
505 gcc_unreachable ();
507 break;
510 case clast_expr_bin:
512 struct clast_binary *b = (struct clast_binary *) e;
513 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
514 tree tl = clast_to_gcc_expression (type, lhs, ip);
515 tree tr = gmp_cst_to_tree (type, b->RHS);
517 switch (b->type)
519 case clast_bin_fdiv:
520 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
522 case clast_bin_cdiv:
523 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
525 case clast_bin_div:
526 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
528 case clast_bin_mod:
529 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
531 default:
532 gcc_unreachable ();
536 default:
537 gcc_unreachable ();
540 return NULL_TREE;
543 /* Return a type that could represent the values between BOUND_ONE and
544 BOUND_TWO. */
546 static tree
547 type_for_interval (mpz_t bound_one, mpz_t bound_two)
549 bool unsigned_p;
550 tree type;
551 machine_mode mode;
552 int wider_precision;
553 int precision = MAX (mpz_sizeinbase (bound_one, 2),
554 mpz_sizeinbase (bound_two, 2));
556 if (precision > BITS_PER_WORD)
558 graphite_regenerate_error = true;
559 return integer_type_node;
562 if (mpz_cmp (bound_one, bound_two) <= 0)
563 unsigned_p = (mpz_sgn (bound_one) >= 0);
564 else
565 unsigned_p = (mpz_sgn (bound_two) >= 0);
567 mode = smallest_mode_for_size (precision, MODE_INT);
568 wider_precision = GET_MODE_PRECISION (mode);
570 /* As we want to generate signed types as much as possible, try to
571 fit the interval [bound_one, bound_two] in a signed type. For example,
572 supposing that we have the interval [0, 100], instead of
573 generating unsigned char, we want to generate a signed char. */
574 if (unsigned_p && precision < wider_precision)
575 unsigned_p = false;
577 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
579 if (!type)
581 graphite_regenerate_error = true;
582 return integer_type_node;
585 return type;
588 /* Return a type that could represent the integer value VAL, or
589 otherwise return NULL_TREE. */
591 static tree
592 type_for_value (mpz_t val)
594 return type_for_interval (val, val);
597 static tree
598 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
600 /* Return the type for the clast_term T. Initializes BOUND_ONE and
601 BOUND_TWO to the bounds of the term. */
603 static tree
604 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
605 mpz_t bound_two)
607 tree type;
608 gcc_assert (t->expr.type == clast_expr_term);
610 if (!t->var)
612 mpz_set (bound_one, t->val);
613 mpz_set (bound_two, t->val);
614 return type_for_value (t->val);
617 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
619 mpz_mul (bound_one, bound_one, t->val);
620 mpz_mul (bound_two, bound_two, t->val);
622 return max_precision_type (type, type_for_interval (bound_one, bound_two));
625 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
626 and BOUND_TWO to the bounds of the reduction expression. */
628 static tree
629 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
630 mpz_t bound_one, mpz_t bound_two)
632 int i;
633 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
634 mpz_t b1, b2, m1, m2;
636 if (r->n == 1)
637 return type;
639 mpz_init (b1);
640 mpz_init (b2);
641 mpz_init (m1);
642 mpz_init (m2);
644 for (i = 1; i < r->n; i++)
646 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
647 type = max_precision_type (type, t);
649 switch (r->type)
651 case clast_red_sum:
652 value_min (m1, bound_one, bound_two);
653 value_min (m2, b1, b2);
654 mpz_add (bound_one, m1, m2);
656 value_max (m1, bound_one, bound_two);
657 value_max (m2, b1, b2);
658 mpz_add (bound_two, m1, m2);
659 break;
661 case clast_red_min:
662 value_min (bound_one, bound_one, bound_two);
663 value_min (bound_two, b1, b2);
664 break;
666 case clast_red_max:
667 value_max (bound_one, bound_one, bound_two);
668 value_max (bound_two, b1, b2);
669 break;
671 default:
672 gcc_unreachable ();
673 break;
677 mpz_clear (b1);
678 mpz_clear (b2);
679 mpz_clear (m1);
680 mpz_clear (m2);
682 /* Return a type that can represent the result of the reduction. */
683 return max_precision_type (type, type_for_interval (bound_one, bound_two));
686 /* Return the type for the clast_binary B used in STMT. */
688 static tree
689 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
690 mpz_t bound_two)
692 mpz_t one;
693 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
694 bound_one, bound_two);
695 tree r = type_for_value (b->RHS);
696 tree type = max_precision_type (l, r);
698 switch (b->type)
700 case clast_bin_fdiv:
701 mpz_mdiv (bound_one, bound_one, b->RHS);
702 mpz_mdiv (bound_two, bound_two, b->RHS);
703 break;
705 case clast_bin_cdiv:
706 mpz_mdiv (bound_one, bound_one, b->RHS);
707 mpz_mdiv (bound_two, bound_two, b->RHS);
708 mpz_init (one);
709 mpz_add (bound_one, bound_one, one);
710 mpz_add (bound_two, bound_two, one);
711 mpz_clear (one);
712 break;
714 case clast_bin_div:
715 mpz_div (bound_one, bound_one, b->RHS);
716 mpz_div (bound_two, bound_two, b->RHS);
717 break;
719 case clast_bin_mod:
720 mpz_mod (bound_one, bound_one, b->RHS);
721 mpz_mod (bound_two, bound_two, b->RHS);
722 break;
724 default:
725 gcc_unreachable ();
728 /* Return a type that can represent the result of the reduction. */
729 return max_precision_type (type, type_for_interval (bound_one, bound_two));
732 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
733 BOUND_TWO to the bounds of the term. */
735 static tree
736 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
737 mpz_t bound_two)
739 bool found = false;
741 if (ip->params.exists () && ip->params_index)
742 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
744 if (!found)
746 gcc_assert (ip->newivs && ip->newivs_index);
747 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
748 bound_two);
749 gcc_assert (found);
752 return TREE_TYPE (clast_name_to_gcc (name, ip));
755 /* Returns the type for the CLAST expression E when used in statement
756 STMT. */
758 static tree
759 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
760 mpz_t bound_two)
762 switch (e->type)
764 case clast_expr_term:
765 return type_for_clast_term ((struct clast_term *) e, ip,
766 bound_one, bound_two);
768 case clast_expr_red:
769 return type_for_clast_red ((struct clast_reduction *) e, ip,
770 bound_one, bound_two);
772 case clast_expr_bin:
773 return type_for_clast_bin ((struct clast_binary *) e, ip,
774 bound_one, bound_two);
776 case clast_expr_name:
777 return type_for_clast_name ((struct clast_name *) e, ip,
778 bound_one, bound_two);
780 default:
781 gcc_unreachable ();
784 return NULL_TREE;
787 /* Returns true if the clast expression E is a constant with VALUE. */
789 static bool
790 clast_expr_const_value_p (struct clast_expr *e, int value)
792 struct clast_term *t;
793 if (e->type != clast_expr_term)
794 return false;
795 t = (struct clast_term *)e;
796 if (t->var)
797 return false;
798 return 0 == mpz_cmp_si (t->val, value);
801 /* Translates a clast equation CLEQ to a tree. */
803 static tree
804 graphite_translate_clast_equation (struct clast_equation *cleq,
805 ivs_params_p ip)
807 enum tree_code comp;
808 tree type, lhs, rhs, ltype, rtype;
809 mpz_t bound_one, bound_two;
810 struct clast_expr *clhs, *crhs;
812 clhs = cleq->LHS;
813 crhs = cleq->RHS;
814 if (cleq->sign == 0)
815 comp = EQ_EXPR;
816 else if (cleq->sign > 0)
817 comp = GE_EXPR;
818 else
819 comp = LE_EXPR;
821 /* Special cases to reduce range of arguments to hopefully
822 don't need types with larger precision than the input. */
823 if (crhs->type == clast_expr_red
824 && comp != EQ_EXPR)
826 struct clast_reduction *r = (struct clast_reduction *) crhs;
827 /* X >= A+1 --> X > A and
828 X <= A-1 --> X < A */
829 if (r->n == 2
830 && r->type == clast_red_sum
831 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
833 crhs = r->elts[0];
834 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
838 mpz_init (bound_one);
839 mpz_init (bound_two);
841 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
842 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
844 mpz_clear (bound_one);
845 mpz_clear (bound_two);
846 type = max_precision_type (ltype, rtype);
848 lhs = clast_to_gcc_expression (type, clhs, ip);
849 rhs = clast_to_gcc_expression (type, crhs, ip);
851 return fold_build2 (comp, boolean_type_node, lhs, rhs);
854 /* Creates the test for the condition in STMT. */
856 static tree
857 graphite_create_guard_cond_expr (struct clast_guard *stmt,
858 ivs_params_p ip)
860 tree cond = NULL;
861 int i;
863 for (i = 0; i < stmt->n; i++)
865 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
867 if (cond)
868 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
869 else
870 cond = eq;
873 return cond;
876 /* Creates a new if region corresponding to Cloog's guard. */
878 static edge
879 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
880 ivs_params_p ip)
882 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
883 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
884 return exit_edge;
887 /* Compute the lower bound LOW and upper bound UP for the parameter
888 PARAM in scop SCOP based on the constraints in the context. */
890 static void
891 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
893 isl_val *v;
894 isl_aff *aff = isl_aff_zero_on_domain
895 (isl_local_space_from_space (isl_set_get_space (scop->context)));
897 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
899 v = isl_set_min_val (scop->context, aff);
900 isl_val_get_num_gmp (v, low);
901 isl_val_free (v);
902 v = isl_set_max_val (scop->context, aff);
903 isl_val_get_num_gmp (v, up);
904 isl_val_free (v);
905 isl_aff_free (aff);
908 /* Compute the lower bound LOW and upper bound UP for the induction
909 variable of loop LOOP.
911 FIXME: This one is not entirely correct, as min/max expressions in the
912 calculation can yield to incorrect results. To be completely
913 correct, we need to evaluate each subexpression generated by
914 CLooG. CLooG does not yet support this, so this is as good as
915 it can be. */
917 static void
918 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
920 isl_set *domain;
921 isl_aff *dimension;
922 isl_local_space *local_space;
923 isl_val *isl_value;
925 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
926 local_space = isl_local_space_from_space (isl_set_get_space (domain));
927 dimension = isl_aff_zero_on_domain (local_space);
928 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
929 isl_set_dim (domain, isl_dim_set) - 1,
932 isl_value = isl_set_min_val (domain, dimension);
933 isl_val_get_num_gmp (isl_value, low);
934 isl_val_free (isl_value);
935 isl_value = isl_set_max_val (domain, dimension);
936 isl_val_get_num_gmp (isl_value, up);
937 isl_val_free (isl_value);
938 isl_set_free (domain);
939 isl_aff_free (dimension);
942 /* Returns the type for the induction variable for the loop translated
943 from STMT_FOR. */
945 static tree
946 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
948 mpz_t bound_one, bound_two;
949 tree lb_type, ub_type;
951 mpz_init (bound_one);
952 mpz_init (bound_two);
954 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
955 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
957 mpz_clear (bound_one);
958 mpz_clear (bound_two);
960 return max_precision_type (lb_type, ub_type);
963 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
964 induction variable for the new LOOP. New LOOP is attached to CFG
965 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
966 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
967 CLooG's scattering name to the induction variable created for the
968 loop of STMT. The new induction variable is inserted in the NEWIVS
969 vector and is of type TYPE. */
971 static struct loop *
972 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
973 loop_p outer, tree type, tree lb, tree ub,
974 int level, ivs_params_p ip)
976 mpz_t low, up;
978 tree stride = gmp_cst_to_tree (type, stmt->stride);
979 tree ivvar = create_tmp_var (type, "graphite_IV");
980 tree iv, iv_after_increment;
981 loop_p loop = create_empty_loop_on_edge
982 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
983 outer ? outer : entry_edge->src->loop_father);
985 mpz_init (low);
986 mpz_init (up);
987 compute_bounds_for_loop (stmt, low, up);
988 save_clast_name_index (ip->newivs_index, stmt->iterator,
989 (*ip->newivs).length (), level, low, up);
990 mpz_clear (low);
991 mpz_clear (up);
992 (*ip->newivs).safe_push (iv);
993 return loop;
996 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
997 induction variables of the loops around GBB in SESE. */
999 static void
1000 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
1001 ivs_params_p ip)
1003 struct clast_stmt *t;
1004 int depth = 0;
1005 CloogStatement *cs = user_stmt->statement;
1006 poly_bb_p pbb = (poly_bb_p) cs->usr;
1007 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1008 mpz_t bound_one, bound_two;
1010 mpz_init (bound_one);
1011 mpz_init (bound_two);
1013 for (t = user_stmt->substitutions; t; t = t->next, depth++)
1015 struct clast_expr *expr = (struct clast_expr *)
1016 ((struct clast_assignment *)t)->RHS;
1017 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1018 tree new_name = clast_to_gcc_expression (type, expr, ip);
1019 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1021 iv_map[old_loop->num] = new_name;
1024 mpz_clear (bound_one);
1025 mpz_clear (bound_two);
1028 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1030 static void
1031 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1032 bb_pbb_htab_type *bb_pbb_mapping)
1034 bool existed;
1035 poly_bb_p &e = bb_pbb_mapping->get_or_insert (bb, &existed);
1036 if (!existed)
1037 e = pbb;
1040 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1042 poly_bb_p
1043 find_pbb_via_hash (bb_pbb_htab_type *bb_pbb_mapping, basic_block bb)
1045 poly_bb_p *pbb = bb_pbb_mapping->get (bb);
1046 if (pbb)
1047 return *pbb;
1049 return NULL;
1052 /* Return the scop of the loop and initialize PBBS the set of
1053 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1054 by the CLAST code generator between a generated basic_block and its
1055 related poly_bb_p. */
1057 scop_p
1058 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type *bb_pbb_mapping,
1059 vec<poly_bb_p> *pbbs)
1061 unsigned i;
1062 basic_block *bbs = get_loop_body_in_dom_order (loop);
1063 scop_p scop = NULL;
1065 for (i = 0; i < loop->num_nodes; i++)
1067 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1069 if (pbb == NULL)
1070 continue;
1072 scop = PBB_SCOP (pbb);
1073 (*pbbs).safe_push (pbb);
1076 free (bbs);
1077 return scop;
1080 /* Translates a clast user statement STMT to gimple.
1082 - NEXT_E is the edge where new generated code should be attached.
1083 - CONTEXT_LOOP is the loop in which the generated code will be placed
1084 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1086 static edge
1087 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1088 bb_pbb_htab_type *bb_pbb_mapping, ivs_params_p ip)
1090 int i, nb_loops;
1091 basic_block new_bb;
1092 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1093 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1094 vec<tree> iv_map;
1096 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1097 return next_e;
1099 nb_loops = number_of_loops (cfun);
1100 iv_map.create (nb_loops);
1101 for (i = 0; i < nb_loops; i++)
1102 iv_map.quick_push (NULL_TREE);
1104 build_iv_mapping (iv_map, stmt, ip);
1105 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1106 next_e, iv_map,
1107 &graphite_regenerate_error);
1108 iv_map.release ();
1110 new_bb = next_e->src;
1111 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1112 mark_virtual_operands_for_renaming (cfun);
1113 update_ssa (TODO_update_ssa);
1115 return next_e;
1118 /* Creates a new if region protecting the loop to be executed, if the execution
1119 count is zero (lb > ub). */
1121 static edge
1122 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1123 tree *type, tree *lb, tree *ub,
1124 ivs_params_p ip)
1126 tree cond_expr;
1127 edge exit_edge;
1129 *type = type_for_clast_for (stmt, ip);
1130 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1131 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1133 /* When ub is simply a constant or a parameter, use lb <= ub. */
1134 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1135 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1136 else
1138 tree one = (POINTER_TYPE_P (*type)
1139 ? convert_to_ptrofftype (integer_one_node)
1140 : fold_convert (*type, integer_one_node));
1141 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1142 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1143 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1144 even if we do not want this. However lb < ub + 1 is false, as
1145 expected. */
1146 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1147 : PLUS_EXPR, *type, *ub, one);
1149 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1152 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1154 return exit_edge;
1157 static edge
1158 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type *,
1159 int, ivs_params_p);
1161 /* Create the loop for a clast for statement.
1163 - NEXT_E is the edge where new generated code should be attached.
1164 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1166 static edge
1167 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1168 edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
1169 int level, tree type, tree lb, tree ub,
1170 ivs_params_p ip)
1172 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1173 type, lb, ub, level, ip);
1174 edge last_e = single_exit (loop);
1175 edge to_body = single_succ_edge (loop->header);
1176 basic_block after = to_body->dest;
1178 /* Create a basic block for loop close phi nodes. */
1179 last_e = single_succ_edge (split_edge (last_e));
1181 /* Translate the body of the loop. */
1182 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1183 level + 1, ip);
1184 redirect_edge_succ_nodup (next_e, after);
1185 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1187 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1188 int scheduling_dim = isl_set_n_dim (domain);
1190 if (flag_loop_parallelize_all
1191 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1192 loop->can_be_parallel = true;
1194 return last_e;
1197 /* Translates a clast for statement STMT to gimple. First a guard is created
1198 protecting the loop, if it is executed zero times. In this guard we create
1199 the real loop structure.
1201 - NEXT_E is the edge where new generated code should be attached.
1202 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1204 static edge
1205 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1206 bb_pbb_htab_type *bb_pbb_mapping, int level,
1207 ivs_params_p ip)
1209 tree type, lb, ub;
1210 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1211 &lb, &ub, ip);
1212 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1214 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1215 type, lb, ub, ip);
1216 return last_e;
1219 /* Translates a clast assignment STMT to gimple.
1221 - NEXT_E is the edge where new generated code should be attached.
1222 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1224 static edge
1225 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1226 int level, ivs_params_p ip)
1228 gimple_seq stmts;
1229 mpz_t bound_one, bound_two;
1230 tree type, new_name, var;
1231 edge res = single_succ_edge (split_edge (next_e));
1232 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1234 mpz_init (bound_one);
1235 mpz_init (bound_two);
1236 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1237 var = create_tmp_var (type, "graphite_var");
1238 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1239 &stmts, true, var);
1240 if (stmts)
1242 gsi_insert_seq_on_edge (next_e, stmts);
1243 gsi_commit_edge_inserts ();
1246 save_clast_name_index (ip->newivs_index, stmt->LHS,
1247 (*ip->newivs).length (), level,
1248 bound_one, bound_two);
1249 (*ip->newivs).safe_push (new_name);
1251 mpz_clear (bound_one);
1252 mpz_clear (bound_two);
1254 return res;
1257 /* Translates a clast guard statement STMT to gimple.
1259 - NEXT_E is the edge where new generated code should be attached.
1260 - CONTEXT_LOOP is the loop in which the generated code will be placed
1261 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1263 static edge
1264 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1265 edge next_e, bb_pbb_htab_type *bb_pbb_mapping, int level,
1266 ivs_params_p ip)
1268 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1269 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1271 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1272 return last_e;
1275 /* Translates a CLAST statement STMT to GCC representation in the
1276 context of a SESE.
1278 - NEXT_E is the edge where new generated code should be attached.
1279 - CONTEXT_LOOP is the loop in which the generated code will be placed
1280 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1282 static edge
1283 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1284 bb_pbb_htab_type *bb_pbb_mapping, int level, ivs_params_p ip)
1286 if (!stmt)
1287 return next_e;
1289 if (CLAST_STMT_IS_A (stmt, stmt_root))
1290 ; /* Do nothing. */
1292 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1293 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1294 next_e, bb_pbb_mapping, ip);
1296 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1297 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1298 next_e, bb_pbb_mapping, level, ip);
1300 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1301 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1302 next_e, bb_pbb_mapping, level, ip);
1304 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1305 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1306 next_e, bb_pbb_mapping, level, ip);
1308 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1309 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1310 next_e, level, ip);
1311 else
1312 gcc_unreachable ();
1314 recompute_all_dominators ();
1315 graphite_verify ();
1317 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1318 level, ip);
1321 /* Add parameter and iterator names to the CloogUnionDomain. */
1323 static CloogUnionDomain *
1324 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1325 int nb_scattering_dims,
1326 clast_index_htab_type *params_index)
1328 sese region = SCOP_REGION (scop);
1329 int i;
1330 int nb_iterators = scop_max_loop_depth (scop);
1331 int nb_parameters = SESE_PARAMS (region).length ();
1332 mpz_t bound_one, bound_two;
1334 mpz_init (bound_one);
1335 mpz_init (bound_two);
1337 for (i = 0; i < nb_parameters; i++)
1339 tree param = SESE_PARAMS (region)[i];
1340 const char *name = get_name (param);
1341 int len;
1342 char *parameter;
1344 if (!name)
1345 name = "T";
1347 len = strlen (name);
1348 len += 17;
1349 parameter = XNEWVEC (char, len + 1);
1350 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1351 save_clast_name_index (params_index, parameter, i, i, bound_one,
1352 bound_two);
1353 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1354 parameter);
1355 compute_bounds_for_param (scop, i, bound_one, bound_two);
1356 free (parameter);
1359 mpz_clear (bound_one);
1360 mpz_clear (bound_two);
1362 for (i = 0; i < nb_iterators; i++)
1364 int len = 4 + 16;
1365 char *iterator;
1366 iterator = XNEWVEC (char, len);
1367 snprintf (iterator, len, "git_%d", i);
1368 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1369 iterator);
1370 free (iterator);
1373 for (i = 0; i < nb_scattering_dims; i++)
1375 int len = 5 + 16;
1376 char *scattering;
1377 scattering = XNEWVEC (char, len);
1378 snprintf (scattering, len, "scat_%d", i);
1379 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1380 scattering);
1381 free (scattering);
1384 return union_domain;
1387 /* Initialize a CLooG input file. */
1389 static FILE *
1390 init_cloog_input_file (int scop_number)
1392 FILE *graphite_out_file;
1393 int len = strlen (dump_base_name);
1394 char *dumpname = XNEWVEC (char, len + 25);
1395 char *s_scop_number = XNEWVEC (char, 15);
1397 memcpy (dumpname, dump_base_name, len + 1);
1398 strip_off_ending (dumpname, len);
1399 sprintf (s_scop_number, ".%d", scop_number);
1400 strcat (dumpname, s_scop_number);
1401 strcat (dumpname, ".cloog");
1402 graphite_out_file = fopen (dumpname, "w+b");
1404 if (graphite_out_file == 0)
1405 fatal_error ("can%'t open %s for writing: %m", dumpname);
1407 free (dumpname);
1409 return graphite_out_file;
1412 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1414 static
1415 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1417 int old_dims, i;
1418 isl_space *space;
1419 isl_basic_map *change_scattering;
1420 isl_map *change_scattering_map;
1422 old_dims = isl_map_dim (scattering, isl_dim_out);
1424 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1425 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1427 for (i = 0; i < old_dims; i++)
1429 isl_constraint *c;
1430 c = isl_equality_alloc
1431 (isl_local_space_from_space (isl_space_copy (space)));
1432 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1433 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1434 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1437 for (i = old_dims; i < new_dims; i++)
1439 isl_constraint *c;
1440 c = isl_equality_alloc
1441 (isl_local_space_from_space (isl_space_copy (space)));
1442 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1443 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1446 change_scattering_map = isl_map_from_basic_map (change_scattering);
1447 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1448 return isl_map_apply_range (scattering, change_scattering_map);
1451 /* Build cloog union domain for SCoP. */
1453 static CloogUnionDomain *
1454 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1456 int i;
1457 poly_bb_p pbb;
1458 CloogUnionDomain *union_domain =
1459 cloog_union_domain_alloc (scop_nb_params (scop));
1461 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1463 CloogDomain *domain;
1464 CloogScattering *scattering;
1466 /* Dead code elimination: when the domain of a PBB is empty,
1467 don't generate code for the PBB. */
1468 if (isl_set_is_empty (pbb->domain))
1469 continue;
1471 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1472 scattering = cloog_scattering_from_isl_map
1473 (extend_scattering (isl_map_copy (pbb->transformed),
1474 nb_scattering_dims));
1476 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1477 scattering, pbb);
1480 return union_domain;
1483 /* Return the options that will be used in graphite_regenerate_ast_cloog. */
1485 static CloogOptions *
1486 set_cloog_options (void)
1488 CloogOptions *options = cloog_options_malloc (cloog_state);
1490 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1491 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1492 we pass an incomplete program to cloog. */
1493 options->language = CLOOG_LANGUAGE_C;
1495 /* Enable complex equality spreading: removes dummy statements
1496 (assignments) in the generated code which repeats the
1497 substitution equations for statements. This is useless for
1498 graphite_regenerate_ast_cloog. */
1499 options->esp = 1;
1501 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1502 options->quiet = 1;
1504 /* Allow cloog to build strides with a stride width different to one.
1505 This example has stride = 4:
1507 for (i = 0; i < 20; i += 4)
1508 A */
1509 options->strides = 1;
1511 /* We want the clast to provide the iteration domains of the executed loops.
1512 This allows us to derive minimal/maximal values for the induction
1513 variables. */
1514 options->save_domains = 1;
1516 /* Do not remove scalar dimensions. CLooG by default removes scalar
1517 dimensions very early from the input schedule. However, they are
1518 necessary to correctly derive from the saved domains
1519 (options->save_domains) the relationship between the generated loops
1520 and the schedule dimensions they are generated from. */
1521 options->noscalars = 1;
1523 /* Disable optimizations and make cloog generate source code closer to the
1524 input. This is useful for debugging, but later we want the optimized
1525 code.
1527 XXX: We can not disable optimizations, as loop blocking is not working
1528 without them. */
1529 if (0)
1531 options->f = -1;
1532 options->l = INT_MAX;
1535 return options;
1538 /* Prints STMT to STDERR. */
1540 void
1541 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1543 CloogOptions *options = set_cloog_options ();
1545 clast_pprint (file, stmt, 0, options);
1546 cloog_options_free (options);
1549 /* Prints STMT to STDERR. */
1551 DEBUG_FUNCTION void
1552 debug_clast_stmt (struct clast_stmt *stmt)
1554 print_clast_stmt (stderr, stmt);
1557 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1559 static
1560 int get_max_scattering_dimensions (scop_p scop)
1562 int i;
1563 poly_bb_p pbb;
1564 int scattering_dims = 0;
1566 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1568 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1569 if (pbb_scatt_dims > scattering_dims)
1570 scattering_dims = pbb_scatt_dims;
1573 return scattering_dims;
1576 static CloogInput *
1577 generate_cloog_input (scop_p scop, clast_index_htab_type *params_index)
1579 CloogUnionDomain *union_domain;
1580 CloogInput *cloog_input;
1581 CloogDomain *context;
1582 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1584 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1585 union_domain = add_names_to_union_domain (scop, union_domain,
1586 nb_scattering_dims,
1587 params_index);
1588 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1590 cloog_input = cloog_input_alloc (context, union_domain);
1592 return cloog_input;
1595 /* Translate SCOP to a CLooG program and clast. These two
1596 representations should be freed together: a clast cannot be used
1597 without a program. */
1599 static struct clast_stmt *
1600 scop_to_clast (scop_p scop, clast_index_htab_type *params_index)
1602 CloogInput *cloog_input;
1603 struct clast_stmt *clast;
1604 CloogOptions *options = set_cloog_options ();
1606 cloog_input = generate_cloog_input (scop, params_index);
1608 /* Dump a .cloog input file, if requested. This feature is only
1609 enabled in the Graphite branch. */
1610 if (0)
1612 static size_t file_scop_number = 0;
1613 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1614 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1617 clast = cloog_clast_create_from_input (cloog_input, options);
1619 cloog_options_free (options);
1620 return clast;
1623 /* Prints to FILE the code generated by CLooG for SCOP. */
1625 void
1626 print_generated_program (FILE *file, scop_p scop)
1628 CloogOptions *options = set_cloog_options ();
1629 clast_index_htab_type *params_index = new clast_index_htab_type (10);
1630 struct clast_stmt *clast;
1632 clast = scop_to_clast (scop, params_index);
1634 fprintf (file, " (clast: \n");
1635 clast_pprint (file, clast, 0, options);
1636 fprintf (file, " )\n");
1638 cloog_options_free (options);
1639 cloog_clast_free (clast);
1642 /* Prints to STDERR the code generated by CLooG for SCOP. */
1644 DEBUG_FUNCTION void
1645 debug_generated_program (scop_p scop)
1647 print_generated_program (stderr, scop);
1650 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1651 the given SCOP. Return true if code generation succeeded.
1652 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1655 bool
1656 graphite_regenerate_ast_cloog (scop_p scop, bb_pbb_htab_type *bb_pbb_mapping)
1658 auto_vec<tree, 10> newivs;
1659 loop_p context_loop;
1660 sese region = SCOP_REGION (scop);
1661 ifsese if_region = NULL;
1662 clast_index_htab_type *newivs_index, *params_index;
1663 struct clast_stmt *clast;
1664 struct ivs_params ip;
1666 timevar_push (TV_GRAPHITE_CODE_GEN);
1667 graphite_regenerate_error = false;
1669 params_index = new clast_index_htab_type (10);
1671 clast = scop_to_clast (scop, params_index);
1673 if (dump_file && (dump_flags & TDF_DETAILS))
1675 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1676 print_clast_stmt (dump_file, clast);
1677 fprintf (dump_file, "\n");
1680 recompute_all_dominators ();
1681 graphite_verify ();
1683 if_region = move_sese_in_condition (region);
1684 sese_insert_phis_for_liveouts (region,
1685 if_region->region->exit->src,
1686 if_region->false_region->exit,
1687 if_region->true_region->exit);
1688 recompute_all_dominators ();
1689 graphite_verify ();
1691 context_loop = SESE_ENTRY (region)->src->loop_father;
1692 newivs_index= new clast_index_htab_type (10);
1694 ip.newivs = &newivs;
1695 ip.newivs_index = newivs_index;
1696 ip.params = SESE_PARAMS (region);
1697 ip.params_index = params_index;
1698 ip.region = region;
1700 translate_clast (context_loop, clast, if_region->true_region->entry,
1701 bb_pbb_mapping, 0, &ip);
1702 graphite_verify ();
1703 scev_reset ();
1704 recompute_all_dominators ();
1705 graphite_verify ();
1707 if (graphite_regenerate_error)
1708 set_ifsese_condition (if_region, integer_zero_node);
1710 free (if_region->true_region);
1711 free (if_region->region);
1712 free (if_region);
1714 delete newivs_index;
1715 newivs_index = NULL;
1716 delete params_index;
1717 params_index = NULL;
1718 cloog_clast_free (clast);
1719 timevar_pop (TV_GRAPHITE_CODE_GEN);
1721 if (dump_file && (dump_flags & TDF_DETAILS))
1723 loop_p loop;
1724 int num_no_dependency = 0;
1726 FOR_EACH_LOOP (loop, 0)
1727 if (loop->can_be_parallel)
1728 num_no_dependency++;
1730 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1731 num_no_dependency);
1734 return !graphite_regenerate_error;
1736 #endif