2014-08-01 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob296b893809fb699ff15b49f3dfac724bbb2ae2a3
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 #endif
35 #include "system.h"
36 #include "coretypes.h"
37 #include "diagnostic-core.h"
38 #include "tree.h"
39 #include "basic-block.h"
40 #include "tree-ssa-alias.h"
41 #include "internal-fn.h"
42 #include "gimple-expr.h"
43 #include "is-a.h"
44 #include "gimple.h"
45 #include "gimple-iterator.h"
46 #include "gimplify-me.h"
47 #include "gimple-ssa.h"
48 #include "tree-ssa-loop-manip.h"
49 #include "tree-ssa-loop.h"
50 #include "tree-into-ssa.h"
51 #include "tree-pass.h"
52 #include "cfgloop.h"
53 #include "tree-chrec.h"
54 #include "tree-data-ref.h"
55 #include "tree-scalar-evolution.h"
56 #include "sese.h"
58 #ifdef HAVE_cloog
59 #include "cloog/cloog.h"
60 #include "graphite-poly.h"
61 #include "graphite-clast-to-gimple.h"
62 #include "graphite-htab.h"
64 typedef const struct clast_expr *clast_name_p;
66 #ifndef CLOOG_LANGUAGE_C
67 #define CLOOG_LANGUAGE_C LANGUAGE_C
68 #endif
71 /* Converts a GMP constant VAL to a tree and returns it. */
73 static tree
74 gmp_cst_to_tree (tree type, mpz_t val)
76 tree t = type ? type : integer_type_node;
77 mpz_t tmp;
79 mpz_init (tmp);
80 mpz_set (tmp, val);
81 wide_int wi = wi::from_mpz (t, tmp, true);
82 mpz_clear (tmp);
84 return wide_int_to_tree (t, wi);
87 /* Sets RES to the min of V1 and V2. */
89 static void
90 value_min (mpz_t res, mpz_t v1, mpz_t v2)
92 if (mpz_cmp (v1, v2) < 0)
93 mpz_set (res, v1);
94 else
95 mpz_set (res, v2);
98 /* Sets RES to the max of V1 and V2. */
100 static void
101 value_max (mpz_t res, mpz_t v1, mpz_t v2)
103 if (mpz_cmp (v1, v2) < 0)
104 mpz_set (res, v2);
105 else
106 mpz_set (res, v1);
110 /* This flag is set when an error occurred during the translation of
111 CLAST to Gimple. */
112 static bool graphite_regenerate_error;
114 /* Verifies properties that GRAPHITE should maintain during translation. */
116 static inline void
117 graphite_verify (void)
119 #ifdef ENABLE_CHECKING
120 verify_loop_structure ();
121 verify_loop_closed_ssa (true);
122 #endif
125 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
126 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
127 upper bounds that can be inferred from the polyhedral representation. */
129 typedef struct clast_name_index {
130 int index;
131 int level;
132 mpz_t bound_one, bound_two;
133 const char *name;
134 /* If free_name is set, the content of name was allocated by us and needs
135 to be freed. */
136 char *free_name;
137 } *clast_name_index_p;
139 /* Helper for hashing clast_name_index. */
141 struct clast_index_hasher
143 typedef clast_name_index value_type;
144 typedef clast_name_index compare_type;
145 static inline hashval_t hash (const value_type *);
146 static inline bool equal (const value_type *, const compare_type *);
147 static inline void remove (value_type *);
150 /* Computes a hash function for database element E. */
152 inline hashval_t
153 clast_index_hasher::hash (const value_type *e)
155 hashval_t hash = 0;
157 int length = strlen (e->name);
158 int i;
160 for (i = 0; i < length; ++i)
161 hash = hash | (e->name[i] << (i % 4));
163 return hash;
166 /* Compares database elements ELT1 and ELT2. */
168 inline bool
169 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
171 return strcmp (elt1->name, elt2->name) == 0;
174 /* Free the memory taken by a clast_name_index struct. */
176 inline void
177 clast_index_hasher::remove (value_type *c)
179 if (c->free_name)
180 free (c->free_name);
181 mpz_clear (c->bound_one);
182 mpz_clear (c->bound_two);
183 free (c);
186 typedef hash_table<clast_index_hasher> clast_index_htab_type;
188 /* Returns a pointer to a new element of type clast_name_index_p built
189 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
191 static inline clast_name_index_p
192 new_clast_name_index (const char *name, int index, int level,
193 mpz_t bound_one, mpz_t bound_two)
195 clast_name_index_p res = XNEW (struct clast_name_index);
196 char *new_name = XNEWVEC (char, strlen (name) + 1);
197 strcpy (new_name, name);
199 res->name = new_name;
200 res->free_name = new_name;
201 res->level = level;
202 res->index = index;
203 mpz_init (res->bound_one);
204 mpz_init (res->bound_two);
205 mpz_set (res->bound_one, bound_one);
206 mpz_set (res->bound_two, bound_two);
207 return res;
210 /* For a given clast NAME, returns -1 if NAME is not in the
211 INDEX_TABLE, otherwise returns the loop level for the induction
212 variable NAME, or if it is a parameter, the parameter number in the
213 vector of parameters. */
215 static inline int
216 clast_name_to_level (clast_name_p name, clast_index_htab_type *index_table)
218 struct clast_name_index tmp;
219 clast_name_index **slot;
221 gcc_assert (name->type == clast_expr_name);
222 tmp.name = ((const struct clast_name *) name)->name;
223 tmp.free_name = NULL;
225 slot = index_table->find_slot (&tmp, NO_INSERT);
227 if (slot && *slot)
228 return ((struct clast_name_index *) *slot)->level;
230 return -1;
233 /* For a given clast NAME, returns -1 if it does not correspond to any
234 parameter, or otherwise, returns the index in the PARAMS or
235 SCATTERING_DIMENSIONS vector. */
237 static inline int
238 clast_name_to_index (struct clast_name *name, clast_index_htab_type *index_table)
240 struct clast_name_index tmp;
241 clast_name_index **slot;
243 tmp.name = ((const struct clast_name *) name)->name;
244 tmp.free_name = NULL;
246 slot = index_table->find_slot (&tmp, NO_INSERT);
248 if (slot && *slot)
249 return (*slot)->index;
251 return -1;
254 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
255 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
256 found in the INDEX_TABLE, false otherwise. */
258 static inline bool
259 clast_name_to_lb_ub (struct clast_name *name,
260 clast_index_htab_type *index_table, mpz_t bound_one,
261 mpz_t bound_two)
263 struct clast_name_index tmp;
264 clast_name_index **slot;
266 tmp.name = name->name;
267 tmp.free_name = NULL;
269 slot = index_table->find_slot (&tmp, NO_INSERT);
271 if (slot && *slot)
273 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
274 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
275 return true;
278 return false;
281 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
283 static inline void
284 save_clast_name_index (clast_index_htab_type *index_table, const char *name,
285 int index, int level, mpz_t bound_one, mpz_t bound_two)
287 struct clast_name_index tmp;
288 clast_name_index **slot;
290 tmp.name = name;
291 tmp.free_name = NULL;
292 slot = index_table->find_slot (&tmp, INSERT);
294 if (slot)
296 free (*slot);
298 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
303 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
304 induction variable in NEWIVS.
306 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
307 parameter in PARAMS. */
309 typedef struct ivs_params {
310 vec<tree> params, *newivs;
311 clast_index_htab_type *newivs_index, *params_index;
312 sese region;
313 } *ivs_params_p;
315 /* Returns the tree variable from the name NAME that was given in
316 Cloog representation. */
318 static tree
319 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
321 int index;
323 if (ip->params.exists () && ip->params_index)
325 index = clast_name_to_index (name, ip->params_index);
327 if (index >= 0)
328 return ip->params[index];
331 gcc_assert (ip->newivs && ip->newivs_index);
332 index = clast_name_to_index (name, ip->newivs_index);
333 gcc_assert (index >= 0);
335 return (*ip->newivs)[index];
338 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
340 static tree
341 max_precision_type (tree type1, tree type2)
343 enum machine_mode mode;
344 int p1, p2, precision;
345 tree type;
347 if (POINTER_TYPE_P (type1))
348 return type1;
350 if (POINTER_TYPE_P (type2))
351 return type2;
353 if (TYPE_UNSIGNED (type1)
354 && TYPE_UNSIGNED (type2))
355 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
357 p1 = TYPE_PRECISION (type1);
358 p2 = TYPE_PRECISION (type2);
360 if (p1 > p2)
361 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
362 else
363 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
365 if (precision > BITS_PER_WORD)
367 graphite_regenerate_error = true;
368 return integer_type_node;
371 mode = smallest_mode_for_size (precision, MODE_INT);
372 precision = GET_MODE_PRECISION (mode);
373 type = build_nonstandard_integer_type (precision, false);
375 if (!type)
377 graphite_regenerate_error = true;
378 return integer_type_node;
381 return type;
384 static tree
385 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
387 /* Converts a Cloog reduction expression R with reduction operation OP
388 to a GCC expression tree of type TYPE. */
390 static tree
391 clast_to_gcc_expression_red (tree type, enum tree_code op,
392 struct clast_reduction *r, ivs_params_p ip)
394 int i;
395 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
396 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
398 for (i = 1; i < r->n; i++)
400 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
401 res = fold_build2 (op, type, res, t);
404 return res;
407 /* Converts a Cloog AST expression E back to a GCC expression tree of
408 type TYPE. */
410 static tree
411 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
413 switch (e->type)
415 case clast_expr_name:
417 return clast_name_to_gcc ((struct clast_name *) e, ip);
419 case clast_expr_term:
421 struct clast_term *t = (struct clast_term *) e;
423 if (t->var)
425 if (mpz_cmp_si (t->val, 1) == 0)
427 tree name = clast_to_gcc_expression (type, t->var, ip);
429 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
430 name = convert_to_ptrofftype (name);
432 name = fold_convert (type, name);
433 return name;
436 else if (mpz_cmp_si (t->val, -1) == 0)
438 tree name = clast_to_gcc_expression (type, t->var, ip);
440 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
441 name = convert_to_ptrofftype (name);
443 name = fold_convert (type, name);
445 return fold_build1 (NEGATE_EXPR, type, name);
447 else
449 tree name = clast_to_gcc_expression (type, t->var, ip);
450 tree cst = gmp_cst_to_tree (type, t->val);
452 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
453 name = convert_to_ptrofftype (name);
455 name = fold_convert (type, name);
457 if (!POINTER_TYPE_P (type))
458 return fold_build2 (MULT_EXPR, type, cst, name);
460 graphite_regenerate_error = true;
461 return cst;
464 else
465 return gmp_cst_to_tree (type, t->val);
468 case clast_expr_red:
470 struct clast_reduction *r = (struct clast_reduction *) e;
472 switch (r->type)
474 case clast_red_sum:
475 return clast_to_gcc_expression_red
476 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
477 r, ip);
479 case clast_red_min:
480 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
482 case clast_red_max:
483 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
485 default:
486 gcc_unreachable ();
488 break;
491 case clast_expr_bin:
493 struct clast_binary *b = (struct clast_binary *) e;
494 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
495 tree tl = clast_to_gcc_expression (type, lhs, ip);
496 tree tr = gmp_cst_to_tree (type, b->RHS);
498 switch (b->type)
500 case clast_bin_fdiv:
501 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
503 case clast_bin_cdiv:
504 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
506 case clast_bin_div:
507 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
509 case clast_bin_mod:
510 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
512 default:
513 gcc_unreachable ();
517 default:
518 gcc_unreachable ();
521 return NULL_TREE;
524 /* Return a type that could represent the values between BOUND_ONE and
525 BOUND_TWO. */
527 static tree
528 type_for_interval (mpz_t bound_one, mpz_t bound_two)
530 bool unsigned_p;
531 tree type;
532 enum machine_mode mode;
533 int wider_precision;
534 int precision = MAX (mpz_sizeinbase (bound_one, 2),
535 mpz_sizeinbase (bound_two, 2));
537 if (precision > BITS_PER_WORD)
539 graphite_regenerate_error = true;
540 return integer_type_node;
543 if (mpz_cmp (bound_one, bound_two) <= 0)
544 unsigned_p = (mpz_sgn (bound_one) >= 0);
545 else
546 unsigned_p = (mpz_sgn (bound_two) >= 0);
548 mode = smallest_mode_for_size (precision, MODE_INT);
549 wider_precision = GET_MODE_PRECISION (mode);
551 /* As we want to generate signed types as much as possible, try to
552 fit the interval [bound_one, bound_two] in a signed type. For example,
553 supposing that we have the interval [0, 100], instead of
554 generating unsigned char, we want to generate a signed char. */
555 if (unsigned_p && precision < wider_precision)
556 unsigned_p = false;
558 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
560 if (!type)
562 graphite_regenerate_error = true;
563 return integer_type_node;
566 return type;
569 /* Return a type that could represent the integer value VAL, or
570 otherwise return NULL_TREE. */
572 static tree
573 type_for_value (mpz_t val)
575 return type_for_interval (val, val);
578 static tree
579 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
581 /* Return the type for the clast_term T. Initializes BOUND_ONE and
582 BOUND_TWO to the bounds of the term. */
584 static tree
585 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
586 mpz_t bound_two)
588 tree type;
589 gcc_assert (t->expr.type == clast_expr_term);
591 if (!t->var)
593 mpz_set (bound_one, t->val);
594 mpz_set (bound_two, t->val);
595 return type_for_value (t->val);
598 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
600 mpz_mul (bound_one, bound_one, t->val);
601 mpz_mul (bound_two, bound_two, t->val);
603 return max_precision_type (type, type_for_interval (bound_one, bound_two));
606 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
607 and BOUND_TWO to the bounds of the reduction expression. */
609 static tree
610 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
611 mpz_t bound_one, mpz_t bound_two)
613 int i;
614 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
615 mpz_t b1, b2, m1, m2;
617 if (r->n == 1)
618 return type;
620 mpz_init (b1);
621 mpz_init (b2);
622 mpz_init (m1);
623 mpz_init (m2);
625 for (i = 1; i < r->n; i++)
627 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
628 type = max_precision_type (type, t);
630 switch (r->type)
632 case clast_red_sum:
633 value_min (m1, bound_one, bound_two);
634 value_min (m2, b1, b2);
635 mpz_add (bound_one, m1, m2);
637 value_max (m1, bound_one, bound_two);
638 value_max (m2, b1, b2);
639 mpz_add (bound_two, m1, m2);
640 break;
642 case clast_red_min:
643 value_min (bound_one, bound_one, bound_two);
644 value_min (bound_two, b1, b2);
645 break;
647 case clast_red_max:
648 value_max (bound_one, bound_one, bound_two);
649 value_max (bound_two, b1, b2);
650 break;
652 default:
653 gcc_unreachable ();
654 break;
658 mpz_clear (b1);
659 mpz_clear (b2);
660 mpz_clear (m1);
661 mpz_clear (m2);
663 /* Return a type that can represent the result of the reduction. */
664 return max_precision_type (type, type_for_interval (bound_one, bound_two));
667 /* Return the type for the clast_binary B used in STMT. */
669 static tree
670 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
671 mpz_t bound_two)
673 mpz_t one;
674 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
675 bound_one, bound_two);
676 tree r = type_for_value (b->RHS);
677 tree type = max_precision_type (l, r);
679 switch (b->type)
681 case clast_bin_fdiv:
682 mpz_mdiv (bound_one, bound_one, b->RHS);
683 mpz_mdiv (bound_two, bound_two, b->RHS);
684 break;
686 case clast_bin_cdiv:
687 mpz_mdiv (bound_one, bound_one, b->RHS);
688 mpz_mdiv (bound_two, bound_two, b->RHS);
689 mpz_init (one);
690 mpz_add (bound_one, bound_one, one);
691 mpz_add (bound_two, bound_two, one);
692 mpz_clear (one);
693 break;
695 case clast_bin_div:
696 mpz_div (bound_one, bound_one, b->RHS);
697 mpz_div (bound_two, bound_two, b->RHS);
698 break;
700 case clast_bin_mod:
701 mpz_mod (bound_one, bound_one, b->RHS);
702 mpz_mod (bound_two, bound_two, b->RHS);
703 break;
705 default:
706 gcc_unreachable ();
709 /* Return a type that can represent the result of the reduction. */
710 return max_precision_type (type, type_for_interval (bound_one, bound_two));
713 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
714 BOUND_TWO to the bounds of the term. */
716 static tree
717 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
718 mpz_t bound_two)
720 bool found = false;
722 if (ip->params.exists () && ip->params_index)
723 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
725 if (!found)
727 gcc_assert (ip->newivs && ip->newivs_index);
728 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
729 bound_two);
730 gcc_assert (found);
733 return TREE_TYPE (clast_name_to_gcc (name, ip));
736 /* Returns the type for the CLAST expression E when used in statement
737 STMT. */
739 static tree
740 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
741 mpz_t bound_two)
743 switch (e->type)
745 case clast_expr_term:
746 return type_for_clast_term ((struct clast_term *) e, ip,
747 bound_one, bound_two);
749 case clast_expr_red:
750 return type_for_clast_red ((struct clast_reduction *) e, ip,
751 bound_one, bound_two);
753 case clast_expr_bin:
754 return type_for_clast_bin ((struct clast_binary *) e, ip,
755 bound_one, bound_two);
757 case clast_expr_name:
758 return type_for_clast_name ((struct clast_name *) e, ip,
759 bound_one, bound_two);
761 default:
762 gcc_unreachable ();
765 return NULL_TREE;
768 /* Returns true if the clast expression E is a constant with VALUE. */
770 static bool
771 clast_expr_const_value_p (struct clast_expr *e, int value)
773 struct clast_term *t;
774 if (e->type != clast_expr_term)
775 return false;
776 t = (struct clast_term *)e;
777 if (t->var)
778 return false;
779 return 0 == mpz_cmp_si (t->val, value);
782 /* Translates a clast equation CLEQ to a tree. */
784 static tree
785 graphite_translate_clast_equation (struct clast_equation *cleq,
786 ivs_params_p ip)
788 enum tree_code comp;
789 tree type, lhs, rhs, ltype, rtype;
790 mpz_t bound_one, bound_two;
791 struct clast_expr *clhs, *crhs;
793 clhs = cleq->LHS;
794 crhs = cleq->RHS;
795 if (cleq->sign == 0)
796 comp = EQ_EXPR;
797 else if (cleq->sign > 0)
798 comp = GE_EXPR;
799 else
800 comp = LE_EXPR;
802 /* Special cases to reduce range of arguments to hopefully
803 don't need types with larger precision than the input. */
804 if (crhs->type == clast_expr_red
805 && comp != EQ_EXPR)
807 struct clast_reduction *r = (struct clast_reduction *) crhs;
808 /* X >= A+1 --> X > A and
809 X <= A-1 --> X < A */
810 if (r->n == 2
811 && r->type == clast_red_sum
812 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
814 crhs = r->elts[0];
815 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
819 mpz_init (bound_one);
820 mpz_init (bound_two);
822 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
823 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
825 mpz_clear (bound_one);
826 mpz_clear (bound_two);
827 type = max_precision_type (ltype, rtype);
829 lhs = clast_to_gcc_expression (type, clhs, ip);
830 rhs = clast_to_gcc_expression (type, crhs, ip);
832 return fold_build2 (comp, boolean_type_node, lhs, rhs);
835 /* Creates the test for the condition in STMT. */
837 static tree
838 graphite_create_guard_cond_expr (struct clast_guard *stmt,
839 ivs_params_p ip)
841 tree cond = NULL;
842 int i;
844 for (i = 0; i < stmt->n; i++)
846 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
848 if (cond)
849 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
850 else
851 cond = eq;
854 return cond;
857 /* Creates a new if region corresponding to Cloog's guard. */
859 static edge
860 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
861 ivs_params_p ip)
863 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
864 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
865 return exit_edge;
868 /* Compute the lower bound LOW and upper bound UP for the parameter
869 PARAM in scop SCOP based on the constraints in the context. */
871 static void
872 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
874 isl_int v;
875 isl_aff *aff = isl_aff_zero_on_domain
876 (isl_local_space_from_space (isl_set_get_space (scop->context)));
878 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
880 isl_int_init (v);
881 isl_set_min (scop->context, aff, &v);
882 isl_int_get_gmp (v, low);
883 isl_set_max (scop->context, aff, &v);
884 isl_int_get_gmp (v, up);
885 isl_int_clear (v);
886 isl_aff_free (aff);
889 /* Compute the lower bound LOW and upper bound UP for the induction
890 variable of loop LOOP.
892 FIXME: This one is not entirely correct, as min/max expressions in the
893 calculation can yield to incorrect results. To be completely
894 correct, we need to evaluate each subexpression generated by
895 CLooG. CLooG does not yet support this, so this is as good as
896 it can be. */
898 static void
899 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
901 isl_set *domain;
902 isl_aff *dimension;
903 isl_local_space *local_space;
904 isl_int isl_value;
905 enum isl_lp_result lp_result;
907 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
908 local_space = isl_local_space_from_space (isl_set_get_space (domain));
909 dimension = isl_aff_zero_on_domain (local_space);
910 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
911 isl_set_dim (domain, isl_dim_set) - 1,
914 isl_int_init (isl_value);
916 lp_result = isl_set_min (domain, dimension, &isl_value);
917 assert (lp_result == isl_lp_ok);
918 isl_int_get_gmp (isl_value, low);
920 lp_result = isl_set_max (domain, dimension, &isl_value);
921 assert (lp_result == isl_lp_ok);
922 isl_int_get_gmp (isl_value, up);
924 isl_int_clear (isl_value);
925 isl_set_free (domain);
926 isl_aff_free (dimension);
929 /* Returns the type for the induction variable for the loop translated
930 from STMT_FOR. */
932 static tree
933 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
935 mpz_t bound_one, bound_two;
936 tree lb_type, ub_type;
938 mpz_init (bound_one);
939 mpz_init (bound_two);
941 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
942 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
944 mpz_clear (bound_one);
945 mpz_clear (bound_two);
947 return max_precision_type (lb_type, ub_type);
950 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
951 induction variable for the new LOOP. New LOOP is attached to CFG
952 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
953 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
954 CLooG's scattering name to the induction variable created for the
955 loop of STMT. The new induction variable is inserted in the NEWIVS
956 vector and is of type TYPE. */
958 static struct loop *
959 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
960 loop_p outer, tree type, tree lb, tree ub,
961 int level, ivs_params_p ip)
963 mpz_t low, up;
965 tree stride = gmp_cst_to_tree (type, stmt->stride);
966 tree ivvar = create_tmp_var (type, "graphite_IV");
967 tree iv, iv_after_increment;
968 loop_p loop = create_empty_loop_on_edge
969 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
970 outer ? outer : entry_edge->src->loop_father);
972 mpz_init (low);
973 mpz_init (up);
974 compute_bounds_for_loop (stmt, low, up);
975 save_clast_name_index (ip->newivs_index, stmt->iterator,
976 (*ip->newivs).length (), level, low, up);
977 mpz_clear (low);
978 mpz_clear (up);
979 (*ip->newivs).safe_push (iv);
980 return loop;
983 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
984 induction variables of the loops around GBB in SESE. */
986 static void
987 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
988 ivs_params_p ip)
990 struct clast_stmt *t;
991 int depth = 0;
992 CloogStatement *cs = user_stmt->statement;
993 poly_bb_p pbb = (poly_bb_p) cs->usr;
994 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
995 mpz_t bound_one, bound_two;
997 mpz_init (bound_one);
998 mpz_init (bound_two);
1000 for (t = user_stmt->substitutions; t; t = t->next, depth++)
1002 struct clast_expr *expr = (struct clast_expr *)
1003 ((struct clast_assignment *)t)->RHS;
1004 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1005 tree new_name = clast_to_gcc_expression (type, expr, ip);
1006 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1008 iv_map[old_loop->num] = new_name;
1011 mpz_clear (bound_one);
1012 mpz_clear (bound_two);
1015 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1017 static void
1018 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1019 bb_pbb_htab_type *bb_pbb_mapping)
1021 bool existed;
1022 poly_bb_p &e = bb_pbb_mapping->get_or_insert (bb, &existed);
1023 if (!existed)
1024 e = pbb;
1027 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1029 poly_bb_p
1030 find_pbb_via_hash (bb_pbb_htab_type *bb_pbb_mapping, basic_block bb)
1032 poly_bb_p *pbb = bb_pbb_mapping->get (bb);
1033 if (pbb)
1034 return *pbb;
1036 return NULL;
1039 /* Return the scop of the loop and initialize PBBS the set of
1040 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1041 by the CLAST code generator between a generated basic_block and its
1042 related poly_bb_p. */
1044 scop_p
1045 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type *bb_pbb_mapping,
1046 vec<poly_bb_p> *pbbs)
1048 unsigned i;
1049 basic_block *bbs = get_loop_body_in_dom_order (loop);
1050 scop_p scop = NULL;
1052 for (i = 0; i < loop->num_nodes; i++)
1054 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1056 if (pbb == NULL)
1057 continue;
1059 scop = PBB_SCOP (pbb);
1060 (*pbbs).safe_push (pbb);
1063 free (bbs);
1064 return scop;
1067 /* Translates a clast user statement STMT to gimple.
1069 - NEXT_E is the edge where new generated code should be attached.
1070 - CONTEXT_LOOP is the loop in which the generated code will be placed
1071 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1073 static edge
1074 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1075 bb_pbb_htab_type *bb_pbb_mapping, ivs_params_p ip)
1077 int i, nb_loops;
1078 basic_block new_bb;
1079 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1080 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1081 vec<tree> iv_map;
1083 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1084 return next_e;
1086 nb_loops = number_of_loops (cfun);
1087 iv_map.create (nb_loops);
1088 for (i = 0; i < nb_loops; i++)
1089 iv_map.quick_push (NULL_TREE);
1091 build_iv_mapping (iv_map, stmt, ip);
1092 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1093 next_e, iv_map,
1094 &graphite_regenerate_error);
1095 iv_map.release ();
1097 new_bb = next_e->src;
1098 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1099 mark_virtual_operands_for_renaming (cfun);
1100 update_ssa (TODO_update_ssa);
1102 return next_e;
1105 /* Creates a new if region protecting the loop to be executed, if the execution
1106 count is zero (lb > ub). */
1108 static edge
1109 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1110 tree *type, tree *lb, tree *ub,
1111 ivs_params_p ip)
1113 tree cond_expr;
1114 edge exit_edge;
1116 *type = type_for_clast_for (stmt, ip);
1117 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1118 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1120 /* When ub is simply a constant or a parameter, use lb <= ub. */
1121 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1122 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1123 else
1125 tree one = (POINTER_TYPE_P (*type)
1126 ? convert_to_ptrofftype (integer_one_node)
1127 : fold_convert (*type, integer_one_node));
1128 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1129 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1130 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1131 even if we do not want this. However lb < ub + 1 is false, as
1132 expected. */
1133 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1134 : PLUS_EXPR, *type, *ub, one);
1136 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1139 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1141 return exit_edge;
1144 static edge
1145 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type *,
1146 int, ivs_params_p);
1148 /* Create the loop for a clast for statement.
1150 - NEXT_E is the edge where new generated code should be attached.
1151 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1153 static edge
1154 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1155 edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
1156 int level, tree type, tree lb, tree ub,
1157 ivs_params_p ip)
1159 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1160 type, lb, ub, level, ip);
1161 edge last_e = single_exit (loop);
1162 edge to_body = single_succ_edge (loop->header);
1163 basic_block after = to_body->dest;
1165 /* Create a basic block for loop close phi nodes. */
1166 last_e = single_succ_edge (split_edge (last_e));
1168 /* Translate the body of the loop. */
1169 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1170 level + 1, ip);
1171 redirect_edge_succ_nodup (next_e, after);
1172 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1174 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1175 int scheduling_dim = isl_set_n_dim (domain);
1177 if (flag_loop_parallelize_all
1178 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1179 loop->can_be_parallel = true;
1181 return last_e;
1184 /* Translates a clast for statement STMT to gimple. First a guard is created
1185 protecting the loop, if it is executed zero times. In this guard we create
1186 the real loop structure.
1188 - NEXT_E is the edge where new generated code should be attached.
1189 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1191 static edge
1192 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1193 bb_pbb_htab_type *bb_pbb_mapping, int level,
1194 ivs_params_p ip)
1196 tree type, lb, ub;
1197 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1198 &lb, &ub, ip);
1199 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1201 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1202 type, lb, ub, ip);
1203 return last_e;
1206 /* Translates a clast assignment STMT to gimple.
1208 - NEXT_E is the edge where new generated code should be attached.
1209 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1211 static edge
1212 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1213 int level, ivs_params_p ip)
1215 gimple_seq stmts;
1216 mpz_t bound_one, bound_two;
1217 tree type, new_name, var;
1218 edge res = single_succ_edge (split_edge (next_e));
1219 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1221 mpz_init (bound_one);
1222 mpz_init (bound_two);
1223 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1224 var = create_tmp_var (type, "graphite_var");
1225 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1226 &stmts, true, var);
1227 if (stmts)
1229 gsi_insert_seq_on_edge (next_e, stmts);
1230 gsi_commit_edge_inserts ();
1233 save_clast_name_index (ip->newivs_index, stmt->LHS,
1234 (*ip->newivs).length (), level,
1235 bound_one, bound_two);
1236 (*ip->newivs).safe_push (new_name);
1238 mpz_clear (bound_one);
1239 mpz_clear (bound_two);
1241 return res;
1244 /* Translates a clast guard statement STMT to gimple.
1246 - NEXT_E is the edge where new generated code should be attached.
1247 - CONTEXT_LOOP is the loop in which the generated code will be placed
1248 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1250 static edge
1251 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1252 edge next_e, bb_pbb_htab_type *bb_pbb_mapping, int level,
1253 ivs_params_p ip)
1255 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1256 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1258 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1259 return last_e;
1262 /* Translates a CLAST statement STMT to GCC representation in the
1263 context of a SESE.
1265 - NEXT_E is the edge where new generated code should be attached.
1266 - CONTEXT_LOOP is the loop in which the generated code will be placed
1267 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1269 static edge
1270 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1271 bb_pbb_htab_type *bb_pbb_mapping, int level, ivs_params_p ip)
1273 if (!stmt)
1274 return next_e;
1276 if (CLAST_STMT_IS_A (stmt, stmt_root))
1277 ; /* Do nothing. */
1279 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1280 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1281 next_e, bb_pbb_mapping, ip);
1283 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1284 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1285 next_e, bb_pbb_mapping, level, ip);
1287 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1288 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1289 next_e, bb_pbb_mapping, level, ip);
1291 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1292 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1293 next_e, bb_pbb_mapping, level, ip);
1295 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1296 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1297 next_e, level, ip);
1298 else
1299 gcc_unreachable ();
1301 recompute_all_dominators ();
1302 graphite_verify ();
1304 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1305 level, ip);
1308 /* Add parameter and iterator names to the CloogUnionDomain. */
1310 static CloogUnionDomain *
1311 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1312 int nb_scattering_dims,
1313 clast_index_htab_type *params_index)
1315 sese region = SCOP_REGION (scop);
1316 int i;
1317 int nb_iterators = scop_max_loop_depth (scop);
1318 int nb_parameters = SESE_PARAMS (region).length ();
1319 mpz_t bound_one, bound_two;
1321 mpz_init (bound_one);
1322 mpz_init (bound_two);
1324 for (i = 0; i < nb_parameters; i++)
1326 tree param = SESE_PARAMS (region)[i];
1327 const char *name = get_name (param);
1328 int len;
1329 char *parameter;
1331 if (!name)
1332 name = "T";
1334 len = strlen (name);
1335 len += 17;
1336 parameter = XNEWVEC (char, len + 1);
1337 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1338 save_clast_name_index (params_index, parameter, i, i, bound_one,
1339 bound_two);
1340 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1341 parameter);
1342 compute_bounds_for_param (scop, i, bound_one, bound_two);
1343 free (parameter);
1346 mpz_clear (bound_one);
1347 mpz_clear (bound_two);
1349 for (i = 0; i < nb_iterators; i++)
1351 int len = 4 + 16;
1352 char *iterator;
1353 iterator = XNEWVEC (char, len);
1354 snprintf (iterator, len, "git_%d", i);
1355 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1356 iterator);
1357 free (iterator);
1360 for (i = 0; i < nb_scattering_dims; i++)
1362 int len = 5 + 16;
1363 char *scattering;
1364 scattering = XNEWVEC (char, len);
1365 snprintf (scattering, len, "scat_%d", i);
1366 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1367 scattering);
1368 free (scattering);
1371 return union_domain;
1374 /* Initialize a CLooG input file. */
1376 static FILE *
1377 init_cloog_input_file (int scop_number)
1379 FILE *graphite_out_file;
1380 int len = strlen (dump_base_name);
1381 char *dumpname = XNEWVEC (char, len + 25);
1382 char *s_scop_number = XNEWVEC (char, 15);
1384 memcpy (dumpname, dump_base_name, len + 1);
1385 strip_off_ending (dumpname, len);
1386 sprintf (s_scop_number, ".%d", scop_number);
1387 strcat (dumpname, s_scop_number);
1388 strcat (dumpname, ".cloog");
1389 graphite_out_file = fopen (dumpname, "w+b");
1391 if (graphite_out_file == 0)
1392 fatal_error ("can%'t open %s for writing: %m", dumpname);
1394 free (dumpname);
1396 return graphite_out_file;
1399 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1401 static
1402 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1404 int old_dims, i;
1405 isl_space *space;
1406 isl_basic_map *change_scattering;
1407 isl_map *change_scattering_map;
1409 old_dims = isl_map_dim (scattering, isl_dim_out);
1411 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1412 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1414 for (i = 0; i < old_dims; i++)
1416 isl_constraint *c;
1417 c = isl_equality_alloc
1418 (isl_local_space_from_space (isl_space_copy (space)));
1419 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1420 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1421 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1424 for (i = old_dims; i < new_dims; i++)
1426 isl_constraint *c;
1427 c = isl_equality_alloc
1428 (isl_local_space_from_space (isl_space_copy (space)));
1429 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1430 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1433 change_scattering_map = isl_map_from_basic_map (change_scattering);
1434 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1435 return isl_map_apply_range (scattering, change_scattering_map);
1438 /* Build cloog union domain for SCoP. */
1440 static CloogUnionDomain *
1441 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1443 int i;
1444 poly_bb_p pbb;
1445 CloogUnionDomain *union_domain =
1446 cloog_union_domain_alloc (scop_nb_params (scop));
1448 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1450 CloogDomain *domain;
1451 CloogScattering *scattering;
1453 /* Dead code elimination: when the domain of a PBB is empty,
1454 don't generate code for the PBB. */
1455 if (isl_set_is_empty (pbb->domain))
1456 continue;
1458 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1459 scattering = cloog_scattering_from_isl_map
1460 (extend_scattering (isl_map_copy (pbb->transformed),
1461 nb_scattering_dims));
1463 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1464 scattering, pbb);
1467 return union_domain;
1470 /* Return the options that will be used in graphite_regenerate_ast_cloog. */
1472 static CloogOptions *
1473 set_cloog_options (void)
1475 CloogOptions *options = cloog_options_malloc (cloog_state);
1477 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1478 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1479 we pass an incomplete program to cloog. */
1480 options->language = CLOOG_LANGUAGE_C;
1482 /* Enable complex equality spreading: removes dummy statements
1483 (assignments) in the generated code which repeats the
1484 substitution equations for statements. This is useless for
1485 graphite_regenerate_ast_cloog. */
1486 options->esp = 1;
1488 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1489 options->quiet = 1;
1491 /* Allow cloog to build strides with a stride width different to one.
1492 This example has stride = 4:
1494 for (i = 0; i < 20; i += 4)
1495 A */
1496 options->strides = 1;
1498 /* We want the clast to provide the iteration domains of the executed loops.
1499 This allows us to derive minimal/maximal values for the induction
1500 variables. */
1501 options->save_domains = 1;
1503 /* Do not remove scalar dimensions. CLooG by default removes scalar
1504 dimensions very early from the input schedule. However, they are
1505 necessary to correctly derive from the saved domains
1506 (options->save_domains) the relationship between the generated loops
1507 and the schedule dimensions they are generated from. */
1508 options->noscalars = 1;
1510 /* Disable optimizations and make cloog generate source code closer to the
1511 input. This is useful for debugging, but later we want the optimized
1512 code.
1514 XXX: We can not disable optimizations, as loop blocking is not working
1515 without them. */
1516 if (0)
1518 options->f = -1;
1519 options->l = INT_MAX;
1522 return options;
1525 /* Prints STMT to STDERR. */
1527 void
1528 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1530 CloogOptions *options = set_cloog_options ();
1532 clast_pprint (file, stmt, 0, options);
1533 cloog_options_free (options);
1536 /* Prints STMT to STDERR. */
1538 DEBUG_FUNCTION void
1539 debug_clast_stmt (struct clast_stmt *stmt)
1541 print_clast_stmt (stderr, stmt);
1544 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1546 static
1547 int get_max_scattering_dimensions (scop_p scop)
1549 int i;
1550 poly_bb_p pbb;
1551 int scattering_dims = 0;
1553 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1555 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1556 if (pbb_scatt_dims > scattering_dims)
1557 scattering_dims = pbb_scatt_dims;
1560 return scattering_dims;
1563 static CloogInput *
1564 generate_cloog_input (scop_p scop, clast_index_htab_type *params_index)
1566 CloogUnionDomain *union_domain;
1567 CloogInput *cloog_input;
1568 CloogDomain *context;
1569 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1571 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1572 union_domain = add_names_to_union_domain (scop, union_domain,
1573 nb_scattering_dims,
1574 params_index);
1575 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1577 cloog_input = cloog_input_alloc (context, union_domain);
1579 return cloog_input;
1582 /* Translate SCOP to a CLooG program and clast. These two
1583 representations should be freed together: a clast cannot be used
1584 without a program. */
1586 static struct clast_stmt *
1587 scop_to_clast (scop_p scop, clast_index_htab_type *params_index)
1589 CloogInput *cloog_input;
1590 struct clast_stmt *clast;
1591 CloogOptions *options = set_cloog_options ();
1593 cloog_input = generate_cloog_input (scop, params_index);
1595 /* Dump a .cloog input file, if requested. This feature is only
1596 enabled in the Graphite branch. */
1597 if (0)
1599 static size_t file_scop_number = 0;
1600 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1601 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1604 clast = cloog_clast_create_from_input (cloog_input, options);
1606 cloog_options_free (options);
1607 return clast;
1610 /* Prints to FILE the code generated by CLooG for SCOP. */
1612 void
1613 print_generated_program (FILE *file, scop_p scop)
1615 CloogOptions *options = set_cloog_options ();
1616 clast_index_htab_type *params_index = new clast_index_htab_type (10);
1617 struct clast_stmt *clast;
1619 clast = scop_to_clast (scop, params_index);
1621 fprintf (file, " (clast: \n");
1622 clast_pprint (file, clast, 0, options);
1623 fprintf (file, " )\n");
1625 cloog_options_free (options);
1626 cloog_clast_free (clast);
1629 /* Prints to STDERR the code generated by CLooG for SCOP. */
1631 DEBUG_FUNCTION void
1632 debug_generated_program (scop_p scop)
1634 print_generated_program (stderr, scop);
1637 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1638 the given SCOP. Return true if code generation succeeded.
1639 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1642 bool
1643 graphite_regenerate_ast_cloog (scop_p scop, bb_pbb_htab_type *bb_pbb_mapping)
1645 auto_vec<tree, 10> newivs;
1646 loop_p context_loop;
1647 sese region = SCOP_REGION (scop);
1648 ifsese if_region = NULL;
1649 clast_index_htab_type *newivs_index, *params_index;
1650 struct clast_stmt *clast;
1651 struct ivs_params ip;
1653 timevar_push (TV_GRAPHITE_CODE_GEN);
1654 graphite_regenerate_error = false;
1656 params_index = new clast_index_htab_type (10);
1658 clast = scop_to_clast (scop, params_index);
1660 if (dump_file && (dump_flags & TDF_DETAILS))
1662 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1663 print_clast_stmt (dump_file, clast);
1664 fprintf (dump_file, "\n");
1667 recompute_all_dominators ();
1668 graphite_verify ();
1670 if_region = move_sese_in_condition (region);
1671 sese_insert_phis_for_liveouts (region,
1672 if_region->region->exit->src,
1673 if_region->false_region->exit,
1674 if_region->true_region->exit);
1675 recompute_all_dominators ();
1676 graphite_verify ();
1678 context_loop = SESE_ENTRY (region)->src->loop_father;
1679 newivs_index= new clast_index_htab_type (10);
1681 ip.newivs = &newivs;
1682 ip.newivs_index = newivs_index;
1683 ip.params = SESE_PARAMS (region);
1684 ip.params_index = params_index;
1685 ip.region = region;
1687 translate_clast (context_loop, clast, if_region->true_region->entry,
1688 bb_pbb_mapping, 0, &ip);
1689 graphite_verify ();
1690 scev_reset ();
1691 recompute_all_dominators ();
1692 graphite_verify ();
1694 if (graphite_regenerate_error)
1695 set_ifsese_condition (if_region, integer_zero_node);
1697 free (if_region->true_region);
1698 free (if_region->region);
1699 free (if_region);
1701 delete newivs_index;
1702 newivs_index = NULL;
1703 delete params_index;
1704 params_index = NULL;
1705 cloog_clast_free (clast);
1706 timevar_pop (TV_GRAPHITE_CODE_GEN);
1708 if (dump_file && (dump_flags & TDF_DETAILS))
1710 loop_p loop;
1711 int num_no_dependency = 0;
1713 FOR_EACH_LOOP (loop, 0)
1714 if (loop->can_be_parallel)
1715 num_no_dependency++;
1717 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1718 num_no_dependency);
1721 return !graphite_regenerate_error;
1723 #endif