Bump version number, post release.
[official-gcc.git] / gcc-4_9-branch / gcc / graphite-clast-to-gimple.c
blob134388c14f9030bba22bdc21b0cf1e10ebf8d502
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 <cloog/cloog.h>
32 #include <cloog/isl/domain.h>
33 #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE
34 #include <isl/deprecated/int.h>
35 #include <isl/lp.h>
36 #include <isl/deprecated/ilp_int.h>
37 #endif
38 #endif
40 #include "system.h"
41 #include "coretypes.h"
42 #include "diagnostic-core.h"
43 #include "tree.h"
44 #include "basic-block.h"
45 #include "tree-ssa-alias.h"
46 #include "internal-fn.h"
47 #include "gimple-expr.h"
48 #include "is-a.h"
49 #include "gimple.h"
50 #include "gimple-iterator.h"
51 #include "gimplify-me.h"
52 #include "gimple-ssa.h"
53 #include "tree-ssa-loop-manip.h"
54 #include "tree-ssa-loop.h"
55 #include "tree-into-ssa.h"
56 #include "tree-pass.h"
57 #include "cfgloop.h"
58 #include "tree-chrec.h"
59 #include "tree-data-ref.h"
60 #include "tree-scalar-evolution.h"
61 #include "sese.h"
63 #ifdef HAVE_cloog
64 #include "cloog/cloog.h"
65 #include "graphite-poly.h"
66 #include "graphite-clast-to-gimple.h"
67 #include "graphite-htab.h"
69 typedef const struct clast_expr *clast_name_p;
71 #ifndef CLOOG_LANGUAGE_C
72 #define CLOOG_LANGUAGE_C LANGUAGE_C
73 #endif
76 /* Converts a GMP constant VAL to a tree and returns it. */
78 static tree
79 gmp_cst_to_tree (tree type, mpz_t val)
81 tree t = type ? type : integer_type_node;
82 mpz_t tmp;
83 double_int di;
85 mpz_init (tmp);
86 mpz_set (tmp, val);
87 di = mpz_get_double_int (t, tmp, true);
88 mpz_clear (tmp);
90 return double_int_to_tree (t, di);
93 /* Sets RES to the min of V1 and V2. */
95 static void
96 value_min (mpz_t res, mpz_t v1, mpz_t v2)
98 if (mpz_cmp (v1, v2) < 0)
99 mpz_set (res, v1);
100 else
101 mpz_set (res, v2);
104 /* Sets RES to the max of V1 and V2. */
106 static void
107 value_max (mpz_t res, mpz_t v1, mpz_t v2)
109 if (mpz_cmp (v1, v2) < 0)
110 mpz_set (res, v2);
111 else
112 mpz_set (res, v1);
116 /* This flag is set when an error occurred during the translation of
117 CLAST to Gimple. */
118 static bool gloog_error;
120 /* Verifies properties that GRAPHITE should maintain during translation. */
122 static inline void
123 graphite_verify (void)
125 #ifdef ENABLE_CHECKING
126 verify_loop_structure ();
127 verify_loop_closed_ssa (true);
128 #endif
131 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
132 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
133 upper bounds that can be inferred from the polyhedral representation. */
135 typedef struct clast_name_index {
136 int index;
137 int level;
138 mpz_t bound_one, bound_two;
139 const char *name;
140 /* If free_name is set, the content of name was allocated by us and needs
141 to be freed. */
142 char *free_name;
143 } *clast_name_index_p;
145 /* Helper for hashing clast_name_index. */
147 struct clast_index_hasher
149 typedef clast_name_index value_type;
150 typedef clast_name_index compare_type;
151 static inline hashval_t hash (const value_type *);
152 static inline bool equal (const value_type *, const compare_type *);
153 static inline void remove (value_type *);
156 /* Computes a hash function for database element E. */
158 inline hashval_t
159 clast_index_hasher::hash (const value_type *e)
161 hashval_t hash = 0;
163 int length = strlen (e->name);
164 int i;
166 for (i = 0; i < length; ++i)
167 hash = hash | (e->name[i] << (i % 4));
169 return hash;
172 /* Compares database elements ELT1 and ELT2. */
174 inline bool
175 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
177 return strcmp (elt1->name, elt2->name) == 0;
180 /* Free the memory taken by a clast_name_index struct. */
182 inline void
183 clast_index_hasher::remove (value_type *c)
185 if (c->free_name)
186 free (c->free_name);
187 mpz_clear (c->bound_one);
188 mpz_clear (c->bound_two);
189 free (c);
192 typedef hash_table <clast_index_hasher> clast_index_htab_type;
194 /* Returns a pointer to a new element of type clast_name_index_p built
195 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
197 static inline clast_name_index_p
198 new_clast_name_index (const char *name, int index, int level,
199 mpz_t bound_one, mpz_t bound_two)
201 clast_name_index_p res = XNEW (struct clast_name_index);
202 char *new_name = XNEWVEC (char, strlen (name) + 1);
203 strcpy (new_name, name);
205 res->name = new_name;
206 res->free_name = new_name;
207 res->level = level;
208 res->index = index;
209 mpz_init (res->bound_one);
210 mpz_init (res->bound_two);
211 mpz_set (res->bound_one, bound_one);
212 mpz_set (res->bound_two, bound_two);
213 return res;
216 /* For a given clast NAME, returns -1 if NAME is not in the
217 INDEX_TABLE, otherwise returns the loop level for the induction
218 variable NAME, or if it is a parameter, the parameter number in the
219 vector of parameters. */
221 static inline int
222 clast_name_to_level (clast_name_p name, clast_index_htab_type index_table)
224 struct clast_name_index tmp;
225 clast_name_index **slot;
227 gcc_assert (name->type == clast_expr_name);
228 tmp.name = ((const struct clast_name *) name)->name;
229 tmp.free_name = NULL;
231 slot = index_table.find_slot (&tmp, NO_INSERT);
233 if (slot && *slot)
234 return ((struct clast_name_index *) *slot)->level;
236 return -1;
239 /* For a given clast NAME, returns -1 if it does not correspond to any
240 parameter, or otherwise, returns the index in the PARAMS or
241 SCATTERING_DIMENSIONS vector. */
243 static inline int
244 clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table)
246 struct clast_name_index tmp;
247 clast_name_index **slot;
249 tmp.name = ((const struct clast_name *) name)->name;
250 tmp.free_name = NULL;
252 slot = index_table.find_slot (&tmp, NO_INSERT);
254 if (slot && *slot)
255 return (*slot)->index;
257 return -1;
260 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
261 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
262 found in the INDEX_TABLE, false otherwise. */
264 static inline bool
265 clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table,
266 mpz_t bound_one, mpz_t bound_two)
268 struct clast_name_index tmp;
269 clast_name_index **slot;
271 tmp.name = name->name;
272 tmp.free_name = NULL;
274 slot = index_table.find_slot (&tmp, NO_INSERT);
276 if (slot && *slot)
278 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
279 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
280 return true;
283 return false;
286 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
288 static inline void
289 save_clast_name_index (clast_index_htab_type index_table, const char *name,
290 int index, int level, mpz_t bound_one, mpz_t bound_two)
292 struct clast_name_index tmp;
293 clast_name_index **slot;
295 tmp.name = name;
296 tmp.free_name = NULL;
297 slot = index_table.find_slot (&tmp, INSERT);
299 if (slot)
301 free (*slot);
303 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
308 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
309 induction variable in NEWIVS.
311 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
312 parameter in PARAMS. */
314 typedef struct ivs_params {
315 vec<tree> params, *newivs;
316 clast_index_htab_type newivs_index, params_index;
317 sese region;
318 } *ivs_params_p;
320 /* Returns the tree variable from the name NAME that was given in
321 Cloog representation. */
323 static tree
324 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
326 int index;
328 if (ip->params.exists () && ip->params_index.is_created ())
330 index = clast_name_to_index (name, ip->params_index);
332 if (index >= 0)
333 return ip->params[index];
336 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
337 index = clast_name_to_index (name, ip->newivs_index);
338 gcc_assert (index >= 0);
340 return (*ip->newivs)[index];
343 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
345 static tree
346 max_precision_type (tree type1, tree type2)
348 enum machine_mode mode;
349 int p1, p2, precision;
350 tree type;
352 if (POINTER_TYPE_P (type1))
353 return type1;
355 if (POINTER_TYPE_P (type2))
356 return type2;
358 if (TYPE_UNSIGNED (type1)
359 && TYPE_UNSIGNED (type2))
360 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
362 p1 = TYPE_PRECISION (type1);
363 p2 = TYPE_PRECISION (type2);
365 if (p1 > p2)
366 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
367 else
368 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
370 if (precision > BITS_PER_WORD)
372 gloog_error = true;
373 return integer_type_node;
376 mode = smallest_mode_for_size (precision, MODE_INT);
377 precision = GET_MODE_PRECISION (mode);
378 type = build_nonstandard_integer_type (precision, false);
380 if (!type)
382 gloog_error = true;
383 return integer_type_node;
386 return type;
389 static tree
390 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
392 /* Converts a Cloog reduction expression R with reduction operation OP
393 to a GCC expression tree of type TYPE. */
395 static tree
396 clast_to_gcc_expression_red (tree type, enum tree_code op,
397 struct clast_reduction *r, ivs_params_p ip)
399 int i;
400 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
401 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
403 for (i = 1; i < r->n; i++)
405 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
406 res = fold_build2 (op, type, res, t);
409 return res;
412 /* Converts a Cloog AST expression E back to a GCC expression tree of
413 type TYPE. */
415 static tree
416 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
418 switch (e->type)
420 case clast_expr_name:
422 return clast_name_to_gcc ((struct clast_name *) e, ip);
424 case clast_expr_term:
426 struct clast_term *t = (struct clast_term *) e;
428 if (t->var)
430 if (mpz_cmp_si (t->val, 1) == 0)
432 tree name = clast_to_gcc_expression (type, t->var, ip);
434 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
435 name = convert_to_ptrofftype (name);
437 name = fold_convert (type, name);
438 return name;
441 else if (mpz_cmp_si (t->val, -1) == 0)
443 tree name = clast_to_gcc_expression (type, t->var, ip);
445 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
446 name = convert_to_ptrofftype (name);
448 name = fold_convert (type, name);
450 return fold_build1 (NEGATE_EXPR, type, name);
452 else
454 tree name = clast_to_gcc_expression (type, t->var, ip);
455 tree cst = gmp_cst_to_tree (type, t->val);
457 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
458 name = convert_to_ptrofftype (name);
460 name = fold_convert (type, name);
462 if (!POINTER_TYPE_P (type))
463 return fold_build2 (MULT_EXPR, type, cst, name);
465 gloog_error = true;
466 return cst;
469 else
470 return gmp_cst_to_tree (type, t->val);
473 case clast_expr_red:
475 struct clast_reduction *r = (struct clast_reduction *) e;
477 switch (r->type)
479 case clast_red_sum:
480 return clast_to_gcc_expression_red
481 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
482 r, ip);
484 case clast_red_min:
485 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
487 case clast_red_max:
488 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
490 default:
491 gcc_unreachable ();
493 break;
496 case clast_expr_bin:
498 struct clast_binary *b = (struct clast_binary *) e;
499 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
500 tree tl = clast_to_gcc_expression (type, lhs, ip);
501 tree tr = gmp_cst_to_tree (type, b->RHS);
503 switch (b->type)
505 case clast_bin_fdiv:
506 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
508 case clast_bin_cdiv:
509 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
511 case clast_bin_div:
512 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
514 case clast_bin_mod:
515 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
517 default:
518 gcc_unreachable ();
522 default:
523 gcc_unreachable ();
526 return NULL_TREE;
529 /* Return a type that could represent the values between BOUND_ONE and
530 BOUND_TWO. */
532 static tree
533 type_for_interval (mpz_t bound_one, mpz_t bound_two)
535 bool unsigned_p;
536 tree type;
537 enum machine_mode mode;
538 int wider_precision;
539 int precision = MAX (mpz_sizeinbase (bound_one, 2),
540 mpz_sizeinbase (bound_two, 2));
542 if (precision > BITS_PER_WORD)
544 gloog_error = true;
545 return integer_type_node;
548 if (mpz_cmp (bound_one, bound_two) <= 0)
549 unsigned_p = (mpz_sgn (bound_one) >= 0);
550 else
551 unsigned_p = (mpz_sgn (bound_two) >= 0);
553 mode = smallest_mode_for_size (precision, MODE_INT);
554 wider_precision = GET_MODE_PRECISION (mode);
556 /* As we want to generate signed types as much as possible, try to
557 fit the interval [bound_one, bound_two] in a signed type. For example,
558 supposing that we have the interval [0, 100], instead of
559 generating unsigned char, we want to generate a signed char. */
560 if (unsigned_p && precision < wider_precision)
561 unsigned_p = false;
563 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
565 if (!type)
567 gloog_error = true;
568 return integer_type_node;
571 return type;
574 /* Return a type that could represent the integer value VAL, or
575 otherwise return NULL_TREE. */
577 static tree
578 type_for_value (mpz_t val)
580 return type_for_interval (val, val);
583 static tree
584 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
586 /* Return the type for the clast_term T. Initializes BOUND_ONE and
587 BOUND_TWO to the bounds of the term. */
589 static tree
590 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
591 mpz_t bound_two)
593 tree type;
594 gcc_assert (t->expr.type == clast_expr_term);
596 if (!t->var)
598 mpz_set (bound_one, t->val);
599 mpz_set (bound_two, t->val);
600 return type_for_value (t->val);
603 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
605 mpz_mul (bound_one, bound_one, t->val);
606 mpz_mul (bound_two, bound_two, t->val);
608 return max_precision_type (type, type_for_interval (bound_one, bound_two));
611 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
612 and BOUND_TWO to the bounds of the reduction expression. */
614 static tree
615 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
616 mpz_t bound_one, mpz_t bound_two)
618 int i;
619 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
620 mpz_t b1, b2, m1, m2;
622 if (r->n == 1)
623 return type;
625 mpz_init (b1);
626 mpz_init (b2);
627 mpz_init (m1);
628 mpz_init (m2);
630 for (i = 1; i < r->n; i++)
632 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
633 type = max_precision_type (type, t);
635 switch (r->type)
637 case clast_red_sum:
638 value_min (m1, bound_one, bound_two);
639 value_min (m2, b1, b2);
640 mpz_add (bound_one, m1, m2);
642 value_max (m1, bound_one, bound_two);
643 value_max (m2, b1, b2);
644 mpz_add (bound_two, m1, m2);
645 break;
647 case clast_red_min:
648 value_min (bound_one, bound_one, bound_two);
649 value_min (bound_two, b1, b2);
650 break;
652 case clast_red_max:
653 value_max (bound_one, bound_one, bound_two);
654 value_max (bound_two, b1, b2);
655 break;
657 default:
658 gcc_unreachable ();
659 break;
663 mpz_clear (b1);
664 mpz_clear (b2);
665 mpz_clear (m1);
666 mpz_clear (m2);
668 /* Return a type that can represent the result of the reduction. */
669 return max_precision_type (type, type_for_interval (bound_one, bound_two));
672 /* Return the type for the clast_binary B used in STMT. */
674 static tree
675 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
676 mpz_t bound_two)
678 mpz_t one;
679 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
680 bound_one, bound_two);
681 tree r = type_for_value (b->RHS);
682 tree type = max_precision_type (l, r);
684 switch (b->type)
686 case clast_bin_fdiv:
687 mpz_mdiv (bound_one, bound_one, b->RHS);
688 mpz_mdiv (bound_two, bound_two, b->RHS);
689 break;
691 case clast_bin_cdiv:
692 mpz_mdiv (bound_one, bound_one, b->RHS);
693 mpz_mdiv (bound_two, bound_two, b->RHS);
694 mpz_init (one);
695 mpz_add (bound_one, bound_one, one);
696 mpz_add (bound_two, bound_two, one);
697 mpz_clear (one);
698 break;
700 case clast_bin_div:
701 mpz_div (bound_one, bound_one, b->RHS);
702 mpz_div (bound_two, bound_two, b->RHS);
703 break;
705 case clast_bin_mod:
706 mpz_mod (bound_one, bound_one, b->RHS);
707 mpz_mod (bound_two, bound_two, b->RHS);
708 break;
710 default:
711 gcc_unreachable ();
714 /* Return a type that can represent the result of the reduction. */
715 return max_precision_type (type, type_for_interval (bound_one, bound_two));
718 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
719 BOUND_TWO to the bounds of the term. */
721 static tree
722 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
723 mpz_t bound_two)
725 bool found = false;
727 if (ip->params.exists () && ip->params_index.is_created ())
728 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
730 if (!found)
732 gcc_assert (ip->newivs && ip->newivs_index.is_created ());
733 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
734 bound_two);
735 gcc_assert (found);
738 return TREE_TYPE (clast_name_to_gcc (name, ip));
741 /* Returns the type for the CLAST expression E when used in statement
742 STMT. */
744 static tree
745 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
746 mpz_t bound_two)
748 switch (e->type)
750 case clast_expr_term:
751 return type_for_clast_term ((struct clast_term *) e, ip,
752 bound_one, bound_two);
754 case clast_expr_red:
755 return type_for_clast_red ((struct clast_reduction *) e, ip,
756 bound_one, bound_two);
758 case clast_expr_bin:
759 return type_for_clast_bin ((struct clast_binary *) e, ip,
760 bound_one, bound_two);
762 case clast_expr_name:
763 return type_for_clast_name ((struct clast_name *) e, ip,
764 bound_one, bound_two);
766 default:
767 gcc_unreachable ();
770 return NULL_TREE;
773 /* Returns true if the clast expression E is a constant with VALUE. */
775 static bool
776 clast_expr_const_value_p (struct clast_expr *e, int value)
778 struct clast_term *t;
779 if (e->type != clast_expr_term)
780 return false;
781 t = (struct clast_term *)e;
782 if (t->var)
783 return false;
784 return 0 == mpz_cmp_si (t->val, value);
787 /* Translates a clast equation CLEQ to a tree. */
789 static tree
790 graphite_translate_clast_equation (struct clast_equation *cleq,
791 ivs_params_p ip)
793 enum tree_code comp;
794 tree type, lhs, rhs, ltype, rtype;
795 mpz_t bound_one, bound_two;
796 struct clast_expr *clhs, *crhs;
798 clhs = cleq->LHS;
799 crhs = cleq->RHS;
800 if (cleq->sign == 0)
801 comp = EQ_EXPR;
802 else if (cleq->sign > 0)
803 comp = GE_EXPR;
804 else
805 comp = LE_EXPR;
807 /* Special cases to reduce range of arguments to hopefully
808 don't need types with larger precision than the input. */
809 if (crhs->type == clast_expr_red
810 && comp != EQ_EXPR)
812 struct clast_reduction *r = (struct clast_reduction *) crhs;
813 /* X >= A+1 --> X > A and
814 X <= A-1 --> X < A */
815 if (r->n == 2
816 && r->type == clast_red_sum
817 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
819 crhs = r->elts[0];
820 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
824 mpz_init (bound_one);
825 mpz_init (bound_two);
827 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
828 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
830 mpz_clear (bound_one);
831 mpz_clear (bound_two);
832 type = max_precision_type (ltype, rtype);
834 lhs = clast_to_gcc_expression (type, clhs, ip);
835 rhs = clast_to_gcc_expression (type, crhs, ip);
837 return fold_build2 (comp, boolean_type_node, lhs, rhs);
840 /* Creates the test for the condition in STMT. */
842 static tree
843 graphite_create_guard_cond_expr (struct clast_guard *stmt,
844 ivs_params_p ip)
846 tree cond = NULL;
847 int i;
849 for (i = 0; i < stmt->n; i++)
851 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
853 if (cond)
854 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
855 else
856 cond = eq;
859 return cond;
862 /* Creates a new if region corresponding to Cloog's guard. */
864 static edge
865 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
866 ivs_params_p ip)
868 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
869 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
870 return exit_edge;
873 /* Compute the lower bound LOW and upper bound UP for the parameter
874 PARAM in scop SCOP based on the constraints in the context. */
876 static void
877 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
879 isl_int v;
880 isl_aff *aff = isl_aff_zero_on_domain
881 (isl_local_space_from_space (isl_set_get_space (scop->context)));
883 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
885 isl_int_init (v);
886 isl_set_min (scop->context, aff, &v);
887 isl_int_get_gmp (v, low);
888 isl_set_max (scop->context, aff, &v);
889 isl_int_get_gmp (v, up);
890 isl_int_clear (v);
891 isl_aff_free (aff);
894 /* Compute the lower bound LOW and upper bound UP for the induction
895 variable of loop LOOP.
897 FIXME: This one is not entirely correct, as min/max expressions in the
898 calculation can yield to incorrect results. To be completely
899 correct, we need to evaluate each subexpression generated by
900 CLooG. CLooG does not yet support this, so this is as good as
901 it can be. */
903 static void
904 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
906 isl_set *domain;
907 isl_aff *dimension;
908 isl_local_space *local_space;
909 isl_int isl_value;
910 enum isl_lp_result lp_result;
912 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
913 local_space = isl_local_space_from_space (isl_set_get_space (domain));
914 dimension = isl_aff_zero_on_domain (local_space);
915 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
916 isl_set_dim (domain, isl_dim_set) - 1,
919 isl_int_init (isl_value);
921 lp_result = isl_set_min (domain, dimension, &isl_value);
922 assert (lp_result == isl_lp_ok);
923 isl_int_get_gmp (isl_value, low);
925 lp_result = isl_set_max (domain, dimension, &isl_value);
926 assert (lp_result == isl_lp_ok);
927 isl_int_get_gmp (isl_value, up);
929 isl_int_clear (isl_value);
930 isl_set_free (domain);
931 isl_aff_free (dimension);
934 /* Returns the type for the induction variable for the loop translated
935 from STMT_FOR. */
937 static tree
938 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
940 mpz_t bound_one, bound_two;
941 tree lb_type, ub_type;
943 mpz_init (bound_one);
944 mpz_init (bound_two);
946 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
947 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
949 mpz_clear (bound_one);
950 mpz_clear (bound_two);
952 return max_precision_type (lb_type, ub_type);
955 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
956 induction variable for the new LOOP. New LOOP is attached to CFG
957 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
958 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
959 CLooG's scattering name to the induction variable created for the
960 loop of STMT. The new induction variable is inserted in the NEWIVS
961 vector and is of type TYPE. */
963 static struct loop *
964 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
965 loop_p outer, tree type, tree lb, tree ub,
966 int level, ivs_params_p ip)
968 mpz_t low, up;
970 tree stride = gmp_cst_to_tree (type, stmt->stride);
971 tree ivvar = create_tmp_var (type, "graphite_IV");
972 tree iv, iv_after_increment;
973 loop_p loop = create_empty_loop_on_edge
974 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
975 outer ? outer : entry_edge->src->loop_father);
977 mpz_init (low);
978 mpz_init (up);
979 compute_bounds_for_loop (stmt, low, up);
980 save_clast_name_index (ip->newivs_index, stmt->iterator,
981 (*ip->newivs).length (), level, low, up);
982 mpz_clear (low);
983 mpz_clear (up);
984 (*ip->newivs).safe_push (iv);
985 return loop;
988 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
989 induction variables of the loops around GBB in SESE. */
991 static void
992 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
993 ivs_params_p ip)
995 struct clast_stmt *t;
996 int depth = 0;
997 CloogStatement *cs = user_stmt->statement;
998 poly_bb_p pbb = (poly_bb_p) cs->usr;
999 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1000 mpz_t bound_one, bound_two;
1002 mpz_init (bound_one);
1003 mpz_init (bound_two);
1005 for (t = user_stmt->substitutions; t; t = t->next, depth++)
1007 struct clast_expr *expr = (struct clast_expr *)
1008 ((struct clast_assignment *)t)->RHS;
1009 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1010 tree new_name = clast_to_gcc_expression (type, expr, ip);
1011 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1013 iv_map[old_loop->num] = new_name;
1016 mpz_clear (bound_one);
1017 mpz_clear (bound_two);
1020 /* Construct bb_pbb_def with BB and PBB. */
1022 static bb_pbb_def *
1023 new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
1025 bb_pbb_def *bb_pbb_p;
1027 bb_pbb_p = XNEW (bb_pbb_def);
1028 bb_pbb_p->bb = bb;
1029 bb_pbb_p->pbb = pbb;
1031 return bb_pbb_p;
1034 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1036 static void
1037 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1038 bb_pbb_htab_type bb_pbb_mapping)
1040 bb_pbb_def tmp;
1041 bb_pbb_def **x;
1043 tmp.bb = bb;
1044 x = bb_pbb_mapping.find_slot (&tmp, INSERT);
1046 if (x && !*x)
1047 *x = new_bb_pbb_def (bb, pbb);
1050 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1052 poly_bb_p
1053 find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb)
1055 bb_pbb_def tmp;
1056 bb_pbb_def **slot;
1058 tmp.bb = bb;
1059 slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT);
1061 if (slot && *slot)
1062 return ((bb_pbb_def *) *slot)->pbb;
1064 return NULL;
1067 /* Return the scop of the loop and initialize PBBS the set of
1068 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1069 by the CLAST code generator between a generated basic_block and its
1070 related poly_bb_p. */
1072 scop_p
1073 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping,
1074 vec<poly_bb_p> *pbbs)
1076 unsigned i;
1077 basic_block *bbs = get_loop_body_in_dom_order (loop);
1078 scop_p scop = NULL;
1080 for (i = 0; i < loop->num_nodes; i++)
1082 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1084 if (pbb == NULL)
1085 continue;
1087 scop = PBB_SCOP (pbb);
1088 (*pbbs).safe_push (pbb);
1091 free (bbs);
1092 return scop;
1095 /* Translates a clast user statement STMT to gimple.
1097 - NEXT_E is the edge where new generated code should be attached.
1098 - CONTEXT_LOOP is the loop in which the generated code will be placed
1099 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1101 static edge
1102 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1103 bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip)
1105 int i, nb_loops;
1106 basic_block new_bb;
1107 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1108 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1109 vec<tree> iv_map;
1111 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1112 return next_e;
1114 nb_loops = number_of_loops (cfun);
1115 iv_map.create (nb_loops);
1116 for (i = 0; i < nb_loops; i++)
1117 iv_map.quick_push (NULL_TREE);
1119 build_iv_mapping (iv_map, stmt, ip);
1120 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1121 next_e, iv_map, &gloog_error);
1122 iv_map.release ();
1124 new_bb = next_e->src;
1125 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1126 mark_virtual_operands_for_renaming (cfun);
1127 update_ssa (TODO_update_ssa);
1129 return next_e;
1132 /* Creates a new if region protecting the loop to be executed, if the execution
1133 count is zero (lb > ub). */
1135 static edge
1136 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1137 tree *type, tree *lb, tree *ub,
1138 ivs_params_p ip)
1140 tree cond_expr;
1141 edge exit_edge;
1143 *type = type_for_clast_for (stmt, ip);
1144 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1145 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1147 /* When ub is simply a constant or a parameter, use lb <= ub. */
1148 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1149 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1150 else
1152 tree one = (POINTER_TYPE_P (*type)
1153 ? convert_to_ptrofftype (integer_one_node)
1154 : fold_convert (*type, integer_one_node));
1155 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1156 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1157 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1158 even if we do not want this. However lb < ub + 1 is false, as
1159 expected. */
1160 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1161 : PLUS_EXPR, *type, *ub, one);
1163 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1166 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1168 return exit_edge;
1171 static edge
1172 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type,
1173 int, ivs_params_p);
1175 /* Create the loop for a clast for statement.
1177 - NEXT_E is the edge where new generated code should be attached.
1178 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1180 static edge
1181 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1182 edge next_e, bb_pbb_htab_type bb_pbb_mapping,
1183 int level, tree type, tree lb, tree ub,
1184 ivs_params_p ip)
1186 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1187 type, lb, ub, level, ip);
1188 edge last_e = single_exit (loop);
1189 edge to_body = single_succ_edge (loop->header);
1190 basic_block after = to_body->dest;
1192 /* Create a basic block for loop close phi nodes. */
1193 last_e = single_succ_edge (split_edge (last_e));
1195 /* Translate the body of the loop. */
1196 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1197 level + 1, ip);
1198 redirect_edge_succ_nodup (next_e, after);
1199 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1201 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1202 int scheduling_dim = isl_set_n_dim (domain);
1204 if (flag_loop_parallelize_all
1205 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1206 loop->can_be_parallel = true;
1208 return last_e;
1211 /* Translates a clast for statement STMT to gimple. First a guard is created
1212 protecting the loop, if it is executed zero times. In this guard we create
1213 the real loop structure.
1215 - NEXT_E is the edge where new generated code should be attached.
1216 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1218 static edge
1219 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1220 bb_pbb_htab_type bb_pbb_mapping, int level,
1221 ivs_params_p ip)
1223 tree type, lb, ub;
1224 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1225 &lb, &ub, ip);
1226 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1228 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1229 type, lb, ub, ip);
1230 return last_e;
1233 /* Translates a clast assignment STMT to gimple.
1235 - NEXT_E is the edge where new generated code should be attached.
1236 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1238 static edge
1239 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1240 int level, ivs_params_p ip)
1242 gimple_seq stmts;
1243 mpz_t bound_one, bound_two;
1244 tree type, new_name, var;
1245 edge res = single_succ_edge (split_edge (next_e));
1246 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1248 mpz_init (bound_one);
1249 mpz_init (bound_two);
1250 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1251 var = create_tmp_var (type, "graphite_var");
1252 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1253 &stmts, true, var);
1254 if (stmts)
1256 gsi_insert_seq_on_edge (next_e, stmts);
1257 gsi_commit_edge_inserts ();
1260 save_clast_name_index (ip->newivs_index, stmt->LHS,
1261 (*ip->newivs).length (), level,
1262 bound_one, bound_two);
1263 (*ip->newivs).safe_push (new_name);
1265 mpz_clear (bound_one);
1266 mpz_clear (bound_two);
1268 return res;
1271 /* Translates a clast guard statement STMT to gimple.
1273 - NEXT_E is the edge where new generated code should be attached.
1274 - CONTEXT_LOOP is the loop in which the generated code will be placed
1275 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1277 static edge
1278 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1279 edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level,
1280 ivs_params_p ip)
1282 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1283 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1285 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1286 return last_e;
1289 /* Translates a CLAST statement STMT to GCC representation in the
1290 context of a SESE.
1292 - NEXT_E is the edge where new generated code should be attached.
1293 - CONTEXT_LOOP is the loop in which the generated code will be placed
1294 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1296 static edge
1297 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1298 bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip)
1300 if (!stmt)
1301 return next_e;
1303 if (CLAST_STMT_IS_A (stmt, stmt_root))
1304 ; /* Do nothing. */
1306 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1307 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1308 next_e, bb_pbb_mapping, ip);
1310 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1311 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1312 next_e, bb_pbb_mapping, level, ip);
1314 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1315 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1316 next_e, bb_pbb_mapping, level, ip);
1318 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1319 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1320 next_e, bb_pbb_mapping, level, ip);
1322 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1323 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1324 next_e, level, ip);
1325 else
1326 gcc_unreachable ();
1328 recompute_all_dominators ();
1329 graphite_verify ();
1331 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1332 level, ip);
1335 /* Add parameter and iterator names to the CloogUnionDomain. */
1337 static CloogUnionDomain *
1338 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1339 int nb_scattering_dims,
1340 clast_index_htab_type params_index)
1342 sese region = SCOP_REGION (scop);
1343 int i;
1344 int nb_iterators = scop_max_loop_depth (scop);
1345 int nb_parameters = SESE_PARAMS (region).length ();
1346 mpz_t bound_one, bound_two;
1348 mpz_init (bound_one);
1349 mpz_init (bound_two);
1351 for (i = 0; i < nb_parameters; i++)
1353 tree param = SESE_PARAMS (region)[i];
1354 const char *name = get_name (param);
1355 int len;
1356 char *parameter;
1358 if (!name)
1359 name = "T";
1361 len = strlen (name);
1362 len += 17;
1363 parameter = XNEWVEC (char, len + 1);
1364 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1365 save_clast_name_index (params_index, parameter, i, i, bound_one,
1366 bound_two);
1367 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1368 parameter);
1369 compute_bounds_for_param (scop, i, bound_one, bound_two);
1370 free (parameter);
1373 mpz_clear (bound_one);
1374 mpz_clear (bound_two);
1376 for (i = 0; i < nb_iterators; i++)
1378 int len = 4 + 16;
1379 char *iterator;
1380 iterator = XNEWVEC (char, len);
1381 snprintf (iterator, len, "git_%d", i);
1382 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1383 iterator);
1384 free (iterator);
1387 for (i = 0; i < nb_scattering_dims; i++)
1389 int len = 5 + 16;
1390 char *scattering;
1391 scattering = XNEWVEC (char, len);
1392 snprintf (scattering, len, "scat_%d", i);
1393 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1394 scattering);
1395 free (scattering);
1398 return union_domain;
1401 /* Initialize a CLooG input file. */
1403 static FILE *
1404 init_cloog_input_file (int scop_number)
1406 FILE *graphite_out_file;
1407 int len = strlen (dump_base_name);
1408 char *dumpname = XNEWVEC (char, len + 25);
1409 char *s_scop_number = XNEWVEC (char, 15);
1411 memcpy (dumpname, dump_base_name, len + 1);
1412 strip_off_ending (dumpname, len);
1413 sprintf (s_scop_number, ".%d", scop_number);
1414 strcat (dumpname, s_scop_number);
1415 strcat (dumpname, ".cloog");
1416 graphite_out_file = fopen (dumpname, "w+b");
1418 if (graphite_out_file == 0)
1419 fatal_error ("can%'t open %s for writing: %m", dumpname);
1421 free (dumpname);
1423 return graphite_out_file;
1426 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1428 static
1429 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1431 int old_dims, i;
1432 isl_space *space;
1433 isl_basic_map *change_scattering;
1434 isl_map *change_scattering_map;
1436 old_dims = isl_map_dim (scattering, isl_dim_out);
1438 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1439 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1441 for (i = 0; i < old_dims; i++)
1443 isl_constraint *c;
1444 c = isl_equality_alloc
1445 (isl_local_space_from_space (isl_space_copy (space)));
1446 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1447 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1448 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1451 for (i = old_dims; i < new_dims; i++)
1453 isl_constraint *c;
1454 c = isl_equality_alloc
1455 (isl_local_space_from_space (isl_space_copy (space)));
1456 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1457 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1460 change_scattering_map = isl_map_from_basic_map (change_scattering);
1461 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1462 return isl_map_apply_range (scattering, change_scattering_map);
1465 /* Build cloog union domain for SCoP. */
1467 static CloogUnionDomain *
1468 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1470 int i;
1471 poly_bb_p pbb;
1472 CloogUnionDomain *union_domain =
1473 cloog_union_domain_alloc (scop_nb_params (scop));
1475 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1477 CloogDomain *domain;
1478 CloogScattering *scattering;
1480 /* Dead code elimination: when the domain of a PBB is empty,
1481 don't generate code for the PBB. */
1482 if (isl_set_is_empty (pbb->domain))
1483 continue;
1485 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1486 scattering = cloog_scattering_from_isl_map
1487 (extend_scattering (isl_map_copy (pbb->transformed),
1488 nb_scattering_dims));
1490 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1491 scattering, pbb);
1494 return union_domain;
1497 /* Return the options that will be used in GLOOG. */
1499 static CloogOptions *
1500 set_cloog_options (void)
1502 CloogOptions *options = cloog_options_malloc (cloog_state);
1504 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1505 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1506 we pass an incomplete program to cloog. */
1507 options->language = CLOOG_LANGUAGE_C;
1509 /* Enable complex equality spreading: removes dummy statements
1510 (assignments) in the generated code which repeats the
1511 substitution equations for statements. This is useless for
1512 GLooG. */
1513 options->esp = 1;
1515 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1516 options->quiet = 1;
1518 /* Allow cloog to build strides with a stride width different to one.
1519 This example has stride = 4:
1521 for (i = 0; i < 20; i += 4)
1522 A */
1523 options->strides = 1;
1525 /* We want the clast to provide the iteration domains of the executed loops.
1526 This allows us to derive minimal/maximal values for the induction
1527 variables. */
1528 options->save_domains = 1;
1530 /* Do not remove scalar dimensions. CLooG by default removes scalar
1531 dimensions very early from the input schedule. However, they are
1532 necessary to correctly derive from the saved domains
1533 (options->save_domains) the relationship between the generated loops
1534 and the schedule dimensions they are generated from. */
1535 options->noscalars = 1;
1537 /* Disable optimizations and make cloog generate source code closer to the
1538 input. This is useful for debugging, but later we want the optimized
1539 code.
1541 XXX: We can not disable optimizations, as loop blocking is not working
1542 without them. */
1543 if (0)
1545 options->f = -1;
1546 options->l = INT_MAX;
1549 return options;
1552 /* Prints STMT to STDERR. */
1554 void
1555 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1557 CloogOptions *options = set_cloog_options ();
1559 clast_pprint (file, stmt, 0, options);
1560 cloog_options_free (options);
1563 /* Prints STMT to STDERR. */
1565 DEBUG_FUNCTION void
1566 debug_clast_stmt (struct clast_stmt *stmt)
1568 print_clast_stmt (stderr, stmt);
1571 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1573 static
1574 int get_max_scattering_dimensions (scop_p scop)
1576 int i;
1577 poly_bb_p pbb;
1578 int scattering_dims = 0;
1580 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1582 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1583 if (pbb_scatt_dims > scattering_dims)
1584 scattering_dims = pbb_scatt_dims;
1587 return scattering_dims;
1590 static CloogInput *
1591 generate_cloog_input (scop_p scop, clast_index_htab_type params_index)
1593 CloogUnionDomain *union_domain;
1594 CloogInput *cloog_input;
1595 CloogDomain *context;
1596 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1598 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1599 union_domain = add_names_to_union_domain (scop, union_domain,
1600 nb_scattering_dims,
1601 params_index);
1602 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1604 cloog_input = cloog_input_alloc (context, union_domain);
1606 return cloog_input;
1609 /* Translate SCOP to a CLooG program and clast. These two
1610 representations should be freed together: a clast cannot be used
1611 without a program. */
1613 static struct clast_stmt *
1614 scop_to_clast (scop_p scop, clast_index_htab_type params_index)
1616 CloogInput *cloog_input;
1617 struct clast_stmt *clast;
1618 CloogOptions *options = set_cloog_options ();
1620 cloog_input = generate_cloog_input (scop, params_index);
1622 /* Dump a .cloog input file, if requested. This feature is only
1623 enabled in the Graphite branch. */
1624 if (0)
1626 static size_t file_scop_number = 0;
1627 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1628 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1631 clast = cloog_clast_create_from_input (cloog_input, options);
1633 cloog_options_free (options);
1634 return clast;
1637 /* Prints to FILE the code generated by CLooG for SCOP. */
1639 void
1640 print_generated_program (FILE *file, scop_p scop)
1642 CloogOptions *options = set_cloog_options ();
1643 clast_index_htab_type params_index;
1644 struct clast_stmt *clast;
1646 params_index.create (10);
1648 clast = scop_to_clast (scop, params_index);
1650 fprintf (file, " (clast: \n");
1651 clast_pprint (file, clast, 0, options);
1652 fprintf (file, " )\n");
1654 cloog_options_free (options);
1655 cloog_clast_free (clast);
1658 /* Prints to STDERR the code generated by CLooG for SCOP. */
1660 DEBUG_FUNCTION void
1661 debug_generated_program (scop_p scop)
1663 print_generated_program (stderr, scop);
1666 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1667 the given SCOP. Return true if code generation succeeded.
1668 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1671 bool
1672 gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping)
1674 auto_vec<tree, 10> newivs;
1675 loop_p context_loop;
1676 sese region = SCOP_REGION (scop);
1677 ifsese if_region = NULL;
1678 clast_index_htab_type newivs_index, params_index;
1679 struct clast_stmt *clast;
1680 struct ivs_params ip;
1682 timevar_push (TV_GRAPHITE_CODE_GEN);
1683 gloog_error = false;
1685 params_index.create (10);
1687 clast = scop_to_clast (scop, params_index);
1689 if (dump_file && (dump_flags & TDF_DETAILS))
1691 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1692 print_clast_stmt (dump_file, clast);
1693 fprintf (dump_file, "\n");
1696 recompute_all_dominators ();
1697 graphite_verify ();
1699 if_region = move_sese_in_condition (region);
1700 sese_insert_phis_for_liveouts (region,
1701 if_region->region->exit->src,
1702 if_region->false_region->exit,
1703 if_region->true_region->exit);
1704 recompute_all_dominators ();
1705 graphite_verify ();
1707 context_loop = SESE_ENTRY (region)->src->loop_father;
1708 newivs_index.create (10);
1710 ip.newivs = &newivs;
1711 ip.newivs_index = newivs_index;
1712 ip.params = SESE_PARAMS (region);
1713 ip.params_index = params_index;
1714 ip.region = region;
1716 translate_clast (context_loop, clast, if_region->true_region->entry,
1717 bb_pbb_mapping, 0, &ip);
1718 graphite_verify ();
1719 scev_reset ();
1720 recompute_all_dominators ();
1721 graphite_verify ();
1723 if (gloog_error)
1724 set_ifsese_condition (if_region, integer_zero_node);
1726 free (if_region->true_region);
1727 free (if_region->region);
1728 free (if_region);
1730 newivs_index.dispose ();
1731 params_index.dispose ();
1732 cloog_clast_free (clast);
1733 timevar_pop (TV_GRAPHITE_CODE_GEN);
1735 if (dump_file && (dump_flags & TDF_DETAILS))
1737 loop_p loop;
1738 int num_no_dependency = 0;
1740 FOR_EACH_LOOP (loop, 0)
1741 if (loop->can_be_parallel)
1742 num_no_dependency++;
1744 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1745 num_no_dependency);
1748 return !gloog_error;
1750 #endif