* include/bits/basic_string.h (getline): Qualify call to prevent ADL
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob0b0bf520160637fac772ea4f0baac8aedb93e9d3
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 "basic-block.h"
48 #include "tree-ssa-alias.h"
49 #include "internal-fn.h"
50 #include "gimple-expr.h"
51 #include "is-a.h"
52 #include "gimple.h"
53 #include "gimple-iterator.h"
54 #include "gimplify-me.h"
55 #include "gimple-ssa.h"
56 #include "tree-ssa-loop-manip.h"
57 #include "tree-ssa-loop.h"
58 #include "tree-into-ssa.h"
59 #include "tree-pass.h"
60 #include "cfgloop.h"
61 #include "tree-chrec.h"
62 #include "tree-data-ref.h"
63 #include "tree-scalar-evolution.h"
64 #include "sese.h"
66 #ifdef HAVE_cloog
67 #include "cloog/cloog.h"
68 #include "graphite-poly.h"
69 #include "graphite-clast-to-gimple.h"
70 #include "graphite-htab.h"
72 typedef const struct clast_expr *clast_name_p;
74 #ifndef CLOOG_LANGUAGE_C
75 #define CLOOG_LANGUAGE_C LANGUAGE_C
76 #endif
79 /* Converts a GMP constant VAL to a tree and returns it. */
81 static tree
82 gmp_cst_to_tree (tree type, mpz_t val)
84 tree t = type ? type : integer_type_node;
85 mpz_t tmp;
87 mpz_init (tmp);
88 mpz_set (tmp, val);
89 wide_int wi = wi::from_mpz (t, tmp, true);
90 mpz_clear (tmp);
92 return wide_int_to_tree (t, wi);
95 /* Sets RES to the min of V1 and V2. */
97 static void
98 value_min (mpz_t res, mpz_t v1, mpz_t v2)
100 if (mpz_cmp (v1, v2) < 0)
101 mpz_set (res, v1);
102 else
103 mpz_set (res, v2);
106 /* Sets RES to the max of V1 and V2. */
108 static void
109 value_max (mpz_t res, mpz_t v1, mpz_t v2)
111 if (mpz_cmp (v1, v2) < 0)
112 mpz_set (res, v2);
113 else
114 mpz_set (res, v1);
118 /* This flag is set when an error occurred during the translation of
119 CLAST to Gimple. */
120 static bool graphite_regenerate_error;
122 /* Verifies properties that GRAPHITE should maintain during translation. */
124 static inline void
125 graphite_verify (void)
127 #ifdef ENABLE_CHECKING
128 verify_loop_structure ();
129 verify_loop_closed_ssa (true);
130 #endif
133 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
134 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
135 upper bounds that can be inferred from the polyhedral representation. */
137 typedef struct clast_name_index {
138 int index;
139 int level;
140 mpz_t bound_one, bound_two;
141 const char *name;
142 /* If free_name is set, the content of name was allocated by us and needs
143 to be freed. */
144 char *free_name;
145 } *clast_name_index_p;
147 /* Helper for hashing clast_name_index. */
149 struct clast_index_hasher
151 typedef clast_name_index value_type;
152 typedef clast_name_index compare_type;
153 static inline hashval_t hash (const value_type *);
154 static inline bool equal (const value_type *, const compare_type *);
155 static inline void remove (value_type *);
158 /* Computes a hash function for database element E. */
160 inline hashval_t
161 clast_index_hasher::hash (const value_type *e)
163 hashval_t hash = 0;
165 int length = strlen (e->name);
166 int i;
168 for (i = 0; i < length; ++i)
169 hash = hash | (e->name[i] << (i % 4));
171 return hash;
174 /* Compares database elements ELT1 and ELT2. */
176 inline bool
177 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
179 return strcmp (elt1->name, elt2->name) == 0;
182 /* Free the memory taken by a clast_name_index struct. */
184 inline void
185 clast_index_hasher::remove (value_type *c)
187 if (c->free_name)
188 free (c->free_name);
189 mpz_clear (c->bound_one);
190 mpz_clear (c->bound_two);
191 free (c);
194 typedef hash_table<clast_index_hasher> clast_index_htab_type;
196 /* Returns a pointer to a new element of type clast_name_index_p built
197 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
199 static inline clast_name_index_p
200 new_clast_name_index (const char *name, int index, int level,
201 mpz_t bound_one, mpz_t bound_two)
203 clast_name_index_p res = XNEW (struct clast_name_index);
204 char *new_name = XNEWVEC (char, strlen (name) + 1);
205 strcpy (new_name, name);
207 res->name = new_name;
208 res->free_name = new_name;
209 res->level = level;
210 res->index = index;
211 mpz_init (res->bound_one);
212 mpz_init (res->bound_two);
213 mpz_set (res->bound_one, bound_one);
214 mpz_set (res->bound_two, bound_two);
215 return res;
218 /* For a given clast NAME, returns -1 if NAME is not in the
219 INDEX_TABLE, otherwise returns the loop level for the induction
220 variable NAME, or if it is a parameter, the parameter number in the
221 vector of parameters. */
223 static inline int
224 clast_name_to_level (clast_name_p name, clast_index_htab_type *index_table)
226 struct clast_name_index tmp;
227 clast_name_index **slot;
229 gcc_assert (name->type == clast_expr_name);
230 tmp.name = ((const struct clast_name *) name)->name;
231 tmp.free_name = NULL;
233 slot = index_table->find_slot (&tmp, NO_INSERT);
235 if (slot && *slot)
236 return ((struct clast_name_index *) *slot)->level;
238 return -1;
241 /* For a given clast NAME, returns -1 if it does not correspond to any
242 parameter, or otherwise, returns the index in the PARAMS or
243 SCATTERING_DIMENSIONS vector. */
245 static inline int
246 clast_name_to_index (struct clast_name *name, clast_index_htab_type *index_table)
248 struct clast_name_index tmp;
249 clast_name_index **slot;
251 tmp.name = ((const struct clast_name *) name)->name;
252 tmp.free_name = NULL;
254 slot = index_table->find_slot (&tmp, NO_INSERT);
256 if (slot && *slot)
257 return (*slot)->index;
259 return -1;
262 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
263 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
264 found in the INDEX_TABLE, false otherwise. */
266 static inline bool
267 clast_name_to_lb_ub (struct clast_name *name,
268 clast_index_htab_type *index_table, mpz_t bound_one,
269 mpz_t bound_two)
271 struct clast_name_index tmp;
272 clast_name_index **slot;
274 tmp.name = name->name;
275 tmp.free_name = NULL;
277 slot = index_table->find_slot (&tmp, NO_INSERT);
279 if (slot && *slot)
281 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
282 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
283 return true;
286 return false;
289 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
291 static inline void
292 save_clast_name_index (clast_index_htab_type *index_table, const char *name,
293 int index, int level, mpz_t bound_one, mpz_t bound_two)
295 struct clast_name_index tmp;
296 clast_name_index **slot;
298 tmp.name = name;
299 tmp.free_name = NULL;
300 slot = index_table->find_slot (&tmp, INSERT);
302 if (slot)
304 free (*slot);
306 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
311 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
312 induction variable in NEWIVS.
314 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
315 parameter in PARAMS. */
317 typedef struct ivs_params {
318 vec<tree> params, *newivs;
319 clast_index_htab_type *newivs_index, *params_index;
320 sese region;
321 } *ivs_params_p;
323 /* Returns the tree variable from the name NAME that was given in
324 Cloog representation. */
326 static tree
327 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
329 int index;
331 if (ip->params.exists () && ip->params_index)
333 index = clast_name_to_index (name, ip->params_index);
335 if (index >= 0)
336 return ip->params[index];
339 gcc_assert (ip->newivs && ip->newivs_index);
340 index = clast_name_to_index (name, ip->newivs_index);
341 gcc_assert (index >= 0);
343 return (*ip->newivs)[index];
346 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
348 static tree
349 max_precision_type (tree type1, tree type2)
351 enum machine_mode mode;
352 int p1, p2, precision;
353 tree type;
355 if (POINTER_TYPE_P (type1))
356 return type1;
358 if (POINTER_TYPE_P (type2))
359 return type2;
361 if (TYPE_UNSIGNED (type1)
362 && TYPE_UNSIGNED (type2))
363 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
365 p1 = TYPE_PRECISION (type1);
366 p2 = TYPE_PRECISION (type2);
368 if (p1 > p2)
369 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
370 else
371 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
373 if (precision > BITS_PER_WORD)
375 graphite_regenerate_error = true;
376 return integer_type_node;
379 mode = smallest_mode_for_size (precision, MODE_INT);
380 precision = GET_MODE_PRECISION (mode);
381 type = build_nonstandard_integer_type (precision, false);
383 if (!type)
385 graphite_regenerate_error = true;
386 return integer_type_node;
389 return type;
392 static tree
393 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
395 /* Converts a Cloog reduction expression R with reduction operation OP
396 to a GCC expression tree of type TYPE. */
398 static tree
399 clast_to_gcc_expression_red (tree type, enum tree_code op,
400 struct clast_reduction *r, ivs_params_p ip)
402 int i;
403 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
404 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
406 for (i = 1; i < r->n; i++)
408 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
409 res = fold_build2 (op, type, res, t);
412 return res;
415 /* Converts a Cloog AST expression E back to a GCC expression tree of
416 type TYPE. */
418 static tree
419 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
421 switch (e->type)
423 case clast_expr_name:
425 return clast_name_to_gcc ((struct clast_name *) e, ip);
427 case clast_expr_term:
429 struct clast_term *t = (struct clast_term *) e;
431 if (t->var)
433 if (mpz_cmp_si (t->val, 1) == 0)
435 tree name = clast_to_gcc_expression (type, t->var, ip);
437 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
438 name = convert_to_ptrofftype (name);
440 name = fold_convert (type, name);
441 return name;
444 else 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);
453 return fold_build1 (NEGATE_EXPR, type, name);
455 else
457 tree name = clast_to_gcc_expression (type, t->var, ip);
458 tree cst = gmp_cst_to_tree (type, t->val);
460 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
461 name = convert_to_ptrofftype (name);
463 name = fold_convert (type, name);
465 if (!POINTER_TYPE_P (type))
466 return fold_build2 (MULT_EXPR, type, cst, name);
468 graphite_regenerate_error = true;
469 return cst;
472 else
473 return gmp_cst_to_tree (type, t->val);
476 case clast_expr_red:
478 struct clast_reduction *r = (struct clast_reduction *) e;
480 switch (r->type)
482 case clast_red_sum:
483 return clast_to_gcc_expression_red
484 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
485 r, ip);
487 case clast_red_min:
488 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
490 case clast_red_max:
491 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
493 default:
494 gcc_unreachable ();
496 break;
499 case clast_expr_bin:
501 struct clast_binary *b = (struct clast_binary *) e;
502 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
503 tree tl = clast_to_gcc_expression (type, lhs, ip);
504 tree tr = gmp_cst_to_tree (type, b->RHS);
506 switch (b->type)
508 case clast_bin_fdiv:
509 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
511 case clast_bin_cdiv:
512 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
514 case clast_bin_div:
515 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
517 case clast_bin_mod:
518 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
520 default:
521 gcc_unreachable ();
525 default:
526 gcc_unreachable ();
529 return NULL_TREE;
532 /* Return a type that could represent the values between BOUND_ONE and
533 BOUND_TWO. */
535 static tree
536 type_for_interval (mpz_t bound_one, mpz_t bound_two)
538 bool unsigned_p;
539 tree type;
540 enum machine_mode mode;
541 int wider_precision;
542 int precision = MAX (mpz_sizeinbase (bound_one, 2),
543 mpz_sizeinbase (bound_two, 2));
545 if (precision > BITS_PER_WORD)
547 graphite_regenerate_error = true;
548 return integer_type_node;
551 if (mpz_cmp (bound_one, bound_two) <= 0)
552 unsigned_p = (mpz_sgn (bound_one) >= 0);
553 else
554 unsigned_p = (mpz_sgn (bound_two) >= 0);
556 mode = smallest_mode_for_size (precision, MODE_INT);
557 wider_precision = GET_MODE_PRECISION (mode);
559 /* As we want to generate signed types as much as possible, try to
560 fit the interval [bound_one, bound_two] in a signed type. For example,
561 supposing that we have the interval [0, 100], instead of
562 generating unsigned char, we want to generate a signed char. */
563 if (unsigned_p && precision < wider_precision)
564 unsigned_p = false;
566 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
568 if (!type)
570 graphite_regenerate_error = true;
571 return integer_type_node;
574 return type;
577 /* Return a type that could represent the integer value VAL, or
578 otherwise return NULL_TREE. */
580 static tree
581 type_for_value (mpz_t val)
583 return type_for_interval (val, val);
586 static tree
587 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
589 /* Return the type for the clast_term T. Initializes BOUND_ONE and
590 BOUND_TWO to the bounds of the term. */
592 static tree
593 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
594 mpz_t bound_two)
596 tree type;
597 gcc_assert (t->expr.type == clast_expr_term);
599 if (!t->var)
601 mpz_set (bound_one, t->val);
602 mpz_set (bound_two, t->val);
603 return type_for_value (t->val);
606 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
608 mpz_mul (bound_one, bound_one, t->val);
609 mpz_mul (bound_two, bound_two, t->val);
611 return max_precision_type (type, type_for_interval (bound_one, bound_two));
614 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
615 and BOUND_TWO to the bounds of the reduction expression. */
617 static tree
618 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
619 mpz_t bound_one, mpz_t bound_two)
621 int i;
622 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
623 mpz_t b1, b2, m1, m2;
625 if (r->n == 1)
626 return type;
628 mpz_init (b1);
629 mpz_init (b2);
630 mpz_init (m1);
631 mpz_init (m2);
633 for (i = 1; i < r->n; i++)
635 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
636 type = max_precision_type (type, t);
638 switch (r->type)
640 case clast_red_sum:
641 value_min (m1, bound_one, bound_two);
642 value_min (m2, b1, b2);
643 mpz_add (bound_one, m1, m2);
645 value_max (m1, bound_one, bound_two);
646 value_max (m2, b1, b2);
647 mpz_add (bound_two, m1, m2);
648 break;
650 case clast_red_min:
651 value_min (bound_one, bound_one, bound_two);
652 value_min (bound_two, b1, b2);
653 break;
655 case clast_red_max:
656 value_max (bound_one, bound_one, bound_two);
657 value_max (bound_two, b1, b2);
658 break;
660 default:
661 gcc_unreachable ();
662 break;
666 mpz_clear (b1);
667 mpz_clear (b2);
668 mpz_clear (m1);
669 mpz_clear (m2);
671 /* Return a type that can represent the result of the reduction. */
672 return max_precision_type (type, type_for_interval (bound_one, bound_two));
675 /* Return the type for the clast_binary B used in STMT. */
677 static tree
678 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
679 mpz_t bound_two)
681 mpz_t one;
682 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
683 bound_one, bound_two);
684 tree r = type_for_value (b->RHS);
685 tree type = max_precision_type (l, r);
687 switch (b->type)
689 case clast_bin_fdiv:
690 mpz_mdiv (bound_one, bound_one, b->RHS);
691 mpz_mdiv (bound_two, bound_two, b->RHS);
692 break;
694 case clast_bin_cdiv:
695 mpz_mdiv (bound_one, bound_one, b->RHS);
696 mpz_mdiv (bound_two, bound_two, b->RHS);
697 mpz_init (one);
698 mpz_add (bound_one, bound_one, one);
699 mpz_add (bound_two, bound_two, one);
700 mpz_clear (one);
701 break;
703 case clast_bin_div:
704 mpz_div (bound_one, bound_one, b->RHS);
705 mpz_div (bound_two, bound_two, b->RHS);
706 break;
708 case clast_bin_mod:
709 mpz_mod (bound_one, bound_one, b->RHS);
710 mpz_mod (bound_two, bound_two, b->RHS);
711 break;
713 default:
714 gcc_unreachable ();
717 /* Return a type that can represent the result of the reduction. */
718 return max_precision_type (type, type_for_interval (bound_one, bound_two));
721 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
722 BOUND_TWO to the bounds of the term. */
724 static tree
725 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
726 mpz_t bound_two)
728 bool found = false;
730 if (ip->params.exists () && ip->params_index)
731 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
733 if (!found)
735 gcc_assert (ip->newivs && ip->newivs_index);
736 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
737 bound_two);
738 gcc_assert (found);
741 return TREE_TYPE (clast_name_to_gcc (name, ip));
744 /* Returns the type for the CLAST expression E when used in statement
745 STMT. */
747 static tree
748 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
749 mpz_t bound_two)
751 switch (e->type)
753 case clast_expr_term:
754 return type_for_clast_term ((struct clast_term *) e, ip,
755 bound_one, bound_two);
757 case clast_expr_red:
758 return type_for_clast_red ((struct clast_reduction *) e, ip,
759 bound_one, bound_two);
761 case clast_expr_bin:
762 return type_for_clast_bin ((struct clast_binary *) e, ip,
763 bound_one, bound_two);
765 case clast_expr_name:
766 return type_for_clast_name ((struct clast_name *) e, ip,
767 bound_one, bound_two);
769 default:
770 gcc_unreachable ();
773 return NULL_TREE;
776 /* Returns true if the clast expression E is a constant with VALUE. */
778 static bool
779 clast_expr_const_value_p (struct clast_expr *e, int value)
781 struct clast_term *t;
782 if (e->type != clast_expr_term)
783 return false;
784 t = (struct clast_term *)e;
785 if (t->var)
786 return false;
787 return 0 == mpz_cmp_si (t->val, value);
790 /* Translates a clast equation CLEQ to a tree. */
792 static tree
793 graphite_translate_clast_equation (struct clast_equation *cleq,
794 ivs_params_p ip)
796 enum tree_code comp;
797 tree type, lhs, rhs, ltype, rtype;
798 mpz_t bound_one, bound_two;
799 struct clast_expr *clhs, *crhs;
801 clhs = cleq->LHS;
802 crhs = cleq->RHS;
803 if (cleq->sign == 0)
804 comp = EQ_EXPR;
805 else if (cleq->sign > 0)
806 comp = GE_EXPR;
807 else
808 comp = LE_EXPR;
810 /* Special cases to reduce range of arguments to hopefully
811 don't need types with larger precision than the input. */
812 if (crhs->type == clast_expr_red
813 && comp != EQ_EXPR)
815 struct clast_reduction *r = (struct clast_reduction *) crhs;
816 /* X >= A+1 --> X > A and
817 X <= A-1 --> X < A */
818 if (r->n == 2
819 && r->type == clast_red_sum
820 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
822 crhs = r->elts[0];
823 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
827 mpz_init (bound_one);
828 mpz_init (bound_two);
830 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
831 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
833 mpz_clear (bound_one);
834 mpz_clear (bound_two);
835 type = max_precision_type (ltype, rtype);
837 lhs = clast_to_gcc_expression (type, clhs, ip);
838 rhs = clast_to_gcc_expression (type, crhs, ip);
840 return fold_build2 (comp, boolean_type_node, lhs, rhs);
843 /* Creates the test for the condition in STMT. */
845 static tree
846 graphite_create_guard_cond_expr (struct clast_guard *stmt,
847 ivs_params_p ip)
849 tree cond = NULL;
850 int i;
852 for (i = 0; i < stmt->n; i++)
854 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
856 if (cond)
857 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
858 else
859 cond = eq;
862 return cond;
865 /* Creates a new if region corresponding to Cloog's guard. */
867 static edge
868 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
869 ivs_params_p ip)
871 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
872 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
873 return exit_edge;
876 /* Compute the lower bound LOW and upper bound UP for the parameter
877 PARAM in scop SCOP based on the constraints in the context. */
879 static void
880 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
882 isl_val *v;
883 isl_aff *aff = isl_aff_zero_on_domain
884 (isl_local_space_from_space (isl_set_get_space (scop->context)));
886 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
888 v = isl_set_min_val (scop->context, aff);
889 isl_val_get_num_gmp (v, low);
890 isl_val_free (v);
891 v = isl_set_max_val (scop->context, aff);
892 isl_val_get_num_gmp (v, up);
893 isl_val_free (v);
894 isl_aff_free (aff);
897 /* Compute the lower bound LOW and upper bound UP for the induction
898 variable of loop LOOP.
900 FIXME: This one is not entirely correct, as min/max expressions in the
901 calculation can yield to incorrect results. To be completely
902 correct, we need to evaluate each subexpression generated by
903 CLooG. CLooG does not yet support this, so this is as good as
904 it can be. */
906 static void
907 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
909 isl_set *domain;
910 isl_aff *dimension;
911 isl_local_space *local_space;
912 isl_val *isl_value;
914 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
915 local_space = isl_local_space_from_space (isl_set_get_space (domain));
916 dimension = isl_aff_zero_on_domain (local_space);
917 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
918 isl_set_dim (domain, isl_dim_set) - 1,
921 isl_value = isl_set_min_val (domain, dimension);
922 isl_val_get_num_gmp (isl_value, low);
923 isl_val_free (isl_value);
924 isl_value = isl_set_max_val (domain, dimension);
925 isl_val_get_num_gmp (isl_value, up);
926 isl_val_free (isl_value);
927 isl_set_free (domain);
928 isl_aff_free (dimension);
931 /* Returns the type for the induction variable for the loop translated
932 from STMT_FOR. */
934 static tree
935 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
937 mpz_t bound_one, bound_two;
938 tree lb_type, ub_type;
940 mpz_init (bound_one);
941 mpz_init (bound_two);
943 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
944 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
946 mpz_clear (bound_one);
947 mpz_clear (bound_two);
949 return max_precision_type (lb_type, ub_type);
952 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
953 induction variable for the new LOOP. New LOOP is attached to CFG
954 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
955 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
956 CLooG's scattering name to the induction variable created for the
957 loop of STMT. The new induction variable is inserted in the NEWIVS
958 vector and is of type TYPE. */
960 static struct loop *
961 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
962 loop_p outer, tree type, tree lb, tree ub,
963 int level, ivs_params_p ip)
965 mpz_t low, up;
967 tree stride = gmp_cst_to_tree (type, stmt->stride);
968 tree ivvar = create_tmp_var (type, "graphite_IV");
969 tree iv, iv_after_increment;
970 loop_p loop = create_empty_loop_on_edge
971 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
972 outer ? outer : entry_edge->src->loop_father);
974 mpz_init (low);
975 mpz_init (up);
976 compute_bounds_for_loop (stmt, low, up);
977 save_clast_name_index (ip->newivs_index, stmt->iterator,
978 (*ip->newivs).length (), level, low, up);
979 mpz_clear (low);
980 mpz_clear (up);
981 (*ip->newivs).safe_push (iv);
982 return loop;
985 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
986 induction variables of the loops around GBB in SESE. */
988 static void
989 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
990 ivs_params_p ip)
992 struct clast_stmt *t;
993 int depth = 0;
994 CloogStatement *cs = user_stmt->statement;
995 poly_bb_p pbb = (poly_bb_p) cs->usr;
996 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
997 mpz_t bound_one, bound_two;
999 mpz_init (bound_one);
1000 mpz_init (bound_two);
1002 for (t = user_stmt->substitutions; t; t = t->next, depth++)
1004 struct clast_expr *expr = (struct clast_expr *)
1005 ((struct clast_assignment *)t)->RHS;
1006 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1007 tree new_name = clast_to_gcc_expression (type, expr, ip);
1008 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1010 iv_map[old_loop->num] = new_name;
1013 mpz_clear (bound_one);
1014 mpz_clear (bound_two);
1017 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1019 static void
1020 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1021 bb_pbb_htab_type *bb_pbb_mapping)
1023 bool existed;
1024 poly_bb_p &e = bb_pbb_mapping->get_or_insert (bb, &existed);
1025 if (!existed)
1026 e = pbb;
1029 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1031 poly_bb_p
1032 find_pbb_via_hash (bb_pbb_htab_type *bb_pbb_mapping, basic_block bb)
1034 poly_bb_p *pbb = bb_pbb_mapping->get (bb);
1035 if (pbb)
1036 return *pbb;
1038 return NULL;
1041 /* Return the scop of the loop and initialize PBBS the set of
1042 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1043 by the CLAST code generator between a generated basic_block and its
1044 related poly_bb_p. */
1046 scop_p
1047 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type *bb_pbb_mapping,
1048 vec<poly_bb_p> *pbbs)
1050 unsigned i;
1051 basic_block *bbs = get_loop_body_in_dom_order (loop);
1052 scop_p scop = NULL;
1054 for (i = 0; i < loop->num_nodes; i++)
1056 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1058 if (pbb == NULL)
1059 continue;
1061 scop = PBB_SCOP (pbb);
1062 (*pbbs).safe_push (pbb);
1065 free (bbs);
1066 return scop;
1069 /* Translates a clast user statement STMT to gimple.
1071 - NEXT_E is the edge where new generated code should be attached.
1072 - CONTEXT_LOOP is the loop in which the generated code will be placed
1073 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1075 static edge
1076 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1077 bb_pbb_htab_type *bb_pbb_mapping, ivs_params_p ip)
1079 int i, nb_loops;
1080 basic_block new_bb;
1081 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1082 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1083 vec<tree> iv_map;
1085 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1086 return next_e;
1088 nb_loops = number_of_loops (cfun);
1089 iv_map.create (nb_loops);
1090 for (i = 0; i < nb_loops; i++)
1091 iv_map.quick_push (NULL_TREE);
1093 build_iv_mapping (iv_map, stmt, ip);
1094 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1095 next_e, iv_map,
1096 &graphite_regenerate_error);
1097 iv_map.release ();
1099 new_bb = next_e->src;
1100 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1101 mark_virtual_operands_for_renaming (cfun);
1102 update_ssa (TODO_update_ssa);
1104 return next_e;
1107 /* Creates a new if region protecting the loop to be executed, if the execution
1108 count is zero (lb > ub). */
1110 static edge
1111 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1112 tree *type, tree *lb, tree *ub,
1113 ivs_params_p ip)
1115 tree cond_expr;
1116 edge exit_edge;
1118 *type = type_for_clast_for (stmt, ip);
1119 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1120 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1122 /* When ub is simply a constant or a parameter, use lb <= ub. */
1123 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1124 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1125 else
1127 tree one = (POINTER_TYPE_P (*type)
1128 ? convert_to_ptrofftype (integer_one_node)
1129 : fold_convert (*type, integer_one_node));
1130 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1131 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1132 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1133 even if we do not want this. However lb < ub + 1 is false, as
1134 expected. */
1135 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1136 : PLUS_EXPR, *type, *ub, one);
1138 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1141 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1143 return exit_edge;
1146 static edge
1147 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type *,
1148 int, ivs_params_p);
1150 /* Create the loop for a clast for statement.
1152 - NEXT_E is the edge where new generated code should be attached.
1153 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1155 static edge
1156 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1157 edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
1158 int level, tree type, tree lb, tree ub,
1159 ivs_params_p ip)
1161 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1162 type, lb, ub, level, ip);
1163 edge last_e = single_exit (loop);
1164 edge to_body = single_succ_edge (loop->header);
1165 basic_block after = to_body->dest;
1167 /* Create a basic block for loop close phi nodes. */
1168 last_e = single_succ_edge (split_edge (last_e));
1170 /* Translate the body of the loop. */
1171 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1172 level + 1, ip);
1173 redirect_edge_succ_nodup (next_e, after);
1174 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1176 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1177 int scheduling_dim = isl_set_n_dim (domain);
1179 if (flag_loop_parallelize_all
1180 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1181 loop->can_be_parallel = true;
1183 return last_e;
1186 /* Translates a clast for statement STMT to gimple. First a guard is created
1187 protecting the loop, if it is executed zero times. In this guard we create
1188 the real loop structure.
1190 - NEXT_E is the edge where new generated code should be attached.
1191 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1193 static edge
1194 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1195 bb_pbb_htab_type *bb_pbb_mapping, int level,
1196 ivs_params_p ip)
1198 tree type, lb, ub;
1199 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1200 &lb, &ub, ip);
1201 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1203 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1204 type, lb, ub, ip);
1205 return last_e;
1208 /* Translates a clast assignment STMT to gimple.
1210 - NEXT_E is the edge where new generated code should be attached.
1211 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1213 static edge
1214 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1215 int level, ivs_params_p ip)
1217 gimple_seq stmts;
1218 mpz_t bound_one, bound_two;
1219 tree type, new_name, var;
1220 edge res = single_succ_edge (split_edge (next_e));
1221 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1223 mpz_init (bound_one);
1224 mpz_init (bound_two);
1225 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1226 var = create_tmp_var (type, "graphite_var");
1227 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1228 &stmts, true, var);
1229 if (stmts)
1231 gsi_insert_seq_on_edge (next_e, stmts);
1232 gsi_commit_edge_inserts ();
1235 save_clast_name_index (ip->newivs_index, stmt->LHS,
1236 (*ip->newivs).length (), level,
1237 bound_one, bound_two);
1238 (*ip->newivs).safe_push (new_name);
1240 mpz_clear (bound_one);
1241 mpz_clear (bound_two);
1243 return res;
1246 /* Translates a clast guard statement STMT to gimple.
1248 - NEXT_E is the edge where new generated code should be attached.
1249 - CONTEXT_LOOP is the loop in which the generated code will be placed
1250 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1252 static edge
1253 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1254 edge next_e, bb_pbb_htab_type *bb_pbb_mapping, int level,
1255 ivs_params_p ip)
1257 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1258 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1260 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1261 return last_e;
1264 /* Translates a CLAST statement STMT to GCC representation in the
1265 context of a SESE.
1267 - NEXT_E is the edge where new generated code should be attached.
1268 - CONTEXT_LOOP is the loop in which the generated code will be placed
1269 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1271 static edge
1272 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1273 bb_pbb_htab_type *bb_pbb_mapping, int level, ivs_params_p ip)
1275 if (!stmt)
1276 return next_e;
1278 if (CLAST_STMT_IS_A (stmt, stmt_root))
1279 ; /* Do nothing. */
1281 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1282 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1283 next_e, bb_pbb_mapping, ip);
1285 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1286 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1287 next_e, bb_pbb_mapping, level, ip);
1289 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1290 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1291 next_e, bb_pbb_mapping, level, ip);
1293 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1294 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1295 next_e, bb_pbb_mapping, level, ip);
1297 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1298 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1299 next_e, level, ip);
1300 else
1301 gcc_unreachable ();
1303 recompute_all_dominators ();
1304 graphite_verify ();
1306 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1307 level, ip);
1310 /* Add parameter and iterator names to the CloogUnionDomain. */
1312 static CloogUnionDomain *
1313 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1314 int nb_scattering_dims,
1315 clast_index_htab_type *params_index)
1317 sese region = SCOP_REGION (scop);
1318 int i;
1319 int nb_iterators = scop_max_loop_depth (scop);
1320 int nb_parameters = SESE_PARAMS (region).length ();
1321 mpz_t bound_one, bound_two;
1323 mpz_init (bound_one);
1324 mpz_init (bound_two);
1326 for (i = 0; i < nb_parameters; i++)
1328 tree param = SESE_PARAMS (region)[i];
1329 const char *name = get_name (param);
1330 int len;
1331 char *parameter;
1333 if (!name)
1334 name = "T";
1336 len = strlen (name);
1337 len += 17;
1338 parameter = XNEWVEC (char, len + 1);
1339 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1340 save_clast_name_index (params_index, parameter, i, i, bound_one,
1341 bound_two);
1342 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1343 parameter);
1344 compute_bounds_for_param (scop, i, bound_one, bound_two);
1345 free (parameter);
1348 mpz_clear (bound_one);
1349 mpz_clear (bound_two);
1351 for (i = 0; i < nb_iterators; i++)
1353 int len = 4 + 16;
1354 char *iterator;
1355 iterator = XNEWVEC (char, len);
1356 snprintf (iterator, len, "git_%d", i);
1357 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1358 iterator);
1359 free (iterator);
1362 for (i = 0; i < nb_scattering_dims; i++)
1364 int len = 5 + 16;
1365 char *scattering;
1366 scattering = XNEWVEC (char, len);
1367 snprintf (scattering, len, "scat_%d", i);
1368 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1369 scattering);
1370 free (scattering);
1373 return union_domain;
1376 /* Initialize a CLooG input file. */
1378 static FILE *
1379 init_cloog_input_file (int scop_number)
1381 FILE *graphite_out_file;
1382 int len = strlen (dump_base_name);
1383 char *dumpname = XNEWVEC (char, len + 25);
1384 char *s_scop_number = XNEWVEC (char, 15);
1386 memcpy (dumpname, dump_base_name, len + 1);
1387 strip_off_ending (dumpname, len);
1388 sprintf (s_scop_number, ".%d", scop_number);
1389 strcat (dumpname, s_scop_number);
1390 strcat (dumpname, ".cloog");
1391 graphite_out_file = fopen (dumpname, "w+b");
1393 if (graphite_out_file == 0)
1394 fatal_error ("can%'t open %s for writing: %m", dumpname);
1396 free (dumpname);
1398 return graphite_out_file;
1401 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1403 static
1404 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1406 int old_dims, i;
1407 isl_space *space;
1408 isl_basic_map *change_scattering;
1409 isl_map *change_scattering_map;
1411 old_dims = isl_map_dim (scattering, isl_dim_out);
1413 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1414 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1416 for (i = 0; i < old_dims; i++)
1418 isl_constraint *c;
1419 c = isl_equality_alloc
1420 (isl_local_space_from_space (isl_space_copy (space)));
1421 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1422 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1423 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1426 for (i = old_dims; i < new_dims; i++)
1428 isl_constraint *c;
1429 c = isl_equality_alloc
1430 (isl_local_space_from_space (isl_space_copy (space)));
1431 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1432 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1435 change_scattering_map = isl_map_from_basic_map (change_scattering);
1436 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1437 return isl_map_apply_range (scattering, change_scattering_map);
1440 /* Build cloog union domain for SCoP. */
1442 static CloogUnionDomain *
1443 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1445 int i;
1446 poly_bb_p pbb;
1447 CloogUnionDomain *union_domain =
1448 cloog_union_domain_alloc (scop_nb_params (scop));
1450 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1452 CloogDomain *domain;
1453 CloogScattering *scattering;
1455 /* Dead code elimination: when the domain of a PBB is empty,
1456 don't generate code for the PBB. */
1457 if (isl_set_is_empty (pbb->domain))
1458 continue;
1460 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1461 scattering = cloog_scattering_from_isl_map
1462 (extend_scattering (isl_map_copy (pbb->transformed),
1463 nb_scattering_dims));
1465 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1466 scattering, pbb);
1469 return union_domain;
1472 /* Return the options that will be used in graphite_regenerate_ast_cloog. */
1474 static CloogOptions *
1475 set_cloog_options (void)
1477 CloogOptions *options = cloog_options_malloc (cloog_state);
1479 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1480 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1481 we pass an incomplete program to cloog. */
1482 options->language = CLOOG_LANGUAGE_C;
1484 /* Enable complex equality spreading: removes dummy statements
1485 (assignments) in the generated code which repeats the
1486 substitution equations for statements. This is useless for
1487 graphite_regenerate_ast_cloog. */
1488 options->esp = 1;
1490 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1491 options->quiet = 1;
1493 /* Allow cloog to build strides with a stride width different to one.
1494 This example has stride = 4:
1496 for (i = 0; i < 20; i += 4)
1497 A */
1498 options->strides = 1;
1500 /* We want the clast to provide the iteration domains of the executed loops.
1501 This allows us to derive minimal/maximal values for the induction
1502 variables. */
1503 options->save_domains = 1;
1505 /* Do not remove scalar dimensions. CLooG by default removes scalar
1506 dimensions very early from the input schedule. However, they are
1507 necessary to correctly derive from the saved domains
1508 (options->save_domains) the relationship between the generated loops
1509 and the schedule dimensions they are generated from. */
1510 options->noscalars = 1;
1512 /* Disable optimizations and make cloog generate source code closer to the
1513 input. This is useful for debugging, but later we want the optimized
1514 code.
1516 XXX: We can not disable optimizations, as loop blocking is not working
1517 without them. */
1518 if (0)
1520 options->f = -1;
1521 options->l = INT_MAX;
1524 return options;
1527 /* Prints STMT to STDERR. */
1529 void
1530 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1532 CloogOptions *options = set_cloog_options ();
1534 clast_pprint (file, stmt, 0, options);
1535 cloog_options_free (options);
1538 /* Prints STMT to STDERR. */
1540 DEBUG_FUNCTION void
1541 debug_clast_stmt (struct clast_stmt *stmt)
1543 print_clast_stmt (stderr, stmt);
1546 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1548 static
1549 int get_max_scattering_dimensions (scop_p scop)
1551 int i;
1552 poly_bb_p pbb;
1553 int scattering_dims = 0;
1555 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1557 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1558 if (pbb_scatt_dims > scattering_dims)
1559 scattering_dims = pbb_scatt_dims;
1562 return scattering_dims;
1565 static CloogInput *
1566 generate_cloog_input (scop_p scop, clast_index_htab_type *params_index)
1568 CloogUnionDomain *union_domain;
1569 CloogInput *cloog_input;
1570 CloogDomain *context;
1571 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1573 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1574 union_domain = add_names_to_union_domain (scop, union_domain,
1575 nb_scattering_dims,
1576 params_index);
1577 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1579 cloog_input = cloog_input_alloc (context, union_domain);
1581 return cloog_input;
1584 /* Translate SCOP to a CLooG program and clast. These two
1585 representations should be freed together: a clast cannot be used
1586 without a program. */
1588 static struct clast_stmt *
1589 scop_to_clast (scop_p scop, clast_index_htab_type *params_index)
1591 CloogInput *cloog_input;
1592 struct clast_stmt *clast;
1593 CloogOptions *options = set_cloog_options ();
1595 cloog_input = generate_cloog_input (scop, params_index);
1597 /* Dump a .cloog input file, if requested. This feature is only
1598 enabled in the Graphite branch. */
1599 if (0)
1601 static size_t file_scop_number = 0;
1602 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1603 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1606 clast = cloog_clast_create_from_input (cloog_input, options);
1608 cloog_options_free (options);
1609 return clast;
1612 /* Prints to FILE the code generated by CLooG for SCOP. */
1614 void
1615 print_generated_program (FILE *file, scop_p scop)
1617 CloogOptions *options = set_cloog_options ();
1618 clast_index_htab_type *params_index = new clast_index_htab_type (10);
1619 struct clast_stmt *clast;
1621 clast = scop_to_clast (scop, params_index);
1623 fprintf (file, " (clast: \n");
1624 clast_pprint (file, clast, 0, options);
1625 fprintf (file, " )\n");
1627 cloog_options_free (options);
1628 cloog_clast_free (clast);
1631 /* Prints to STDERR the code generated by CLooG for SCOP. */
1633 DEBUG_FUNCTION void
1634 debug_generated_program (scop_p scop)
1636 print_generated_program (stderr, scop);
1639 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1640 the given SCOP. Return true if code generation succeeded.
1641 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1644 bool
1645 graphite_regenerate_ast_cloog (scop_p scop, bb_pbb_htab_type *bb_pbb_mapping)
1647 auto_vec<tree, 10> newivs;
1648 loop_p context_loop;
1649 sese region = SCOP_REGION (scop);
1650 ifsese if_region = NULL;
1651 clast_index_htab_type *newivs_index, *params_index;
1652 struct clast_stmt *clast;
1653 struct ivs_params ip;
1655 timevar_push (TV_GRAPHITE_CODE_GEN);
1656 graphite_regenerate_error = false;
1658 params_index = new clast_index_htab_type (10);
1660 clast = scop_to_clast (scop, params_index);
1662 if (dump_file && (dump_flags & TDF_DETAILS))
1664 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1665 print_clast_stmt (dump_file, clast);
1666 fprintf (dump_file, "\n");
1669 recompute_all_dominators ();
1670 graphite_verify ();
1672 if_region = move_sese_in_condition (region);
1673 sese_insert_phis_for_liveouts (region,
1674 if_region->region->exit->src,
1675 if_region->false_region->exit,
1676 if_region->true_region->exit);
1677 recompute_all_dominators ();
1678 graphite_verify ();
1680 context_loop = SESE_ENTRY (region)->src->loop_father;
1681 newivs_index= new clast_index_htab_type (10);
1683 ip.newivs = &newivs;
1684 ip.newivs_index = newivs_index;
1685 ip.params = SESE_PARAMS (region);
1686 ip.params_index = params_index;
1687 ip.region = region;
1689 translate_clast (context_loop, clast, if_region->true_region->entry,
1690 bb_pbb_mapping, 0, &ip);
1691 graphite_verify ();
1692 scev_reset ();
1693 recompute_all_dominators ();
1694 graphite_verify ();
1696 if (graphite_regenerate_error)
1697 set_ifsese_condition (if_region, integer_zero_node);
1699 free (if_region->true_region);
1700 free (if_region->region);
1701 free (if_region);
1703 delete newivs_index;
1704 newivs_index = NULL;
1705 delete params_index;
1706 params_index = NULL;
1707 cloog_clast_free (clast);
1708 timevar_pop (TV_GRAPHITE_CODE_GEN);
1710 if (dump_file && (dump_flags & TDF_DETAILS))
1712 loop_p loop;
1713 int num_no_dependency = 0;
1715 FOR_EACH_LOOP (loop, 0)
1716 if (loop->can_be_parallel)
1717 num_no_dependency++;
1719 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1720 num_no_dependency);
1723 return !graphite_regenerate_error;
1725 #endif