New syntax for -fsanitize-recover.
[gcc.git] / gcc / graphite-clast-to-gimple.c
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>.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 #include "config.h"
22
23 #ifdef HAVE_cloog
24 #include <isl/set.h>
25 #include <isl/map.h>
26 #include <isl/union_map.h>
27 #include <isl/list.h>
28 #include <isl/constraint.h>
29 #include <isl/ilp.h>
30 #include <isl/aff.h>
31 #include <isl/val.h>
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35 #include <isl/val_gmp.h>
36 #if defined(__cplusplus)
37 }
38 #endif
39 #include <cloog/cloog.h>
40 #include <cloog/isl/domain.h>
41 #endif
42
43 #include "system.h"
44 #include "coretypes.h"
45 #include "diagnostic-core.h"
46 #include "tree.h"
47 #include "basic-block.h"
48 #include "tree-ssa-alias.h"
49 #include "internal-fn.h"
50 #include "gimple-expr.h"
51 #include "is-a.h"
52 #include "gimple.h"
53 #include "gimple-iterator.h"
54 #include "gimplify-me.h"
55 #include "gimple-ssa.h"
56 #include "tree-ssa-loop-manip.h"
57 #include "tree-ssa-loop.h"
58 #include "tree-into-ssa.h"
59 #include "tree-pass.h"
60 #include "cfgloop.h"
61 #include "tree-chrec.h"
62 #include "tree-data-ref.h"
63 #include "tree-scalar-evolution.h"
64 #include "sese.h"
65
66 #ifdef HAVE_cloog
67 #include "cloog/cloog.h"
68 #include "graphite-poly.h"
69 #include "graphite-clast-to-gimple.h"
70 #include "graphite-htab.h"
71
72 typedef const struct clast_expr *clast_name_p;
73
74 #ifndef CLOOG_LANGUAGE_C
75 #define CLOOG_LANGUAGE_C LANGUAGE_C
76 #endif
77
78
79 /* Converts a GMP constant VAL to a tree and returns it. */
80
81 static tree
82 gmp_cst_to_tree (tree type, mpz_t val)
83 {
84 tree t = type ? type : integer_type_node;
85 mpz_t tmp;
86
87 mpz_init (tmp);
88 mpz_set (tmp, val);
89 wide_int wi = wi::from_mpz (t, tmp, true);
90 mpz_clear (tmp);
91
92 return wide_int_to_tree (t, wi);
93 }
94
95 /* Sets RES to the min of V1 and V2. */
96
97 static void
98 value_min (mpz_t res, mpz_t v1, mpz_t v2)
99 {
100 if (mpz_cmp (v1, v2) < 0)
101 mpz_set (res, v1);
102 else
103 mpz_set (res, v2);
104 }
105
106 /* Sets RES to the max of V1 and V2. */
107
108 static void
109 value_max (mpz_t res, mpz_t v1, mpz_t v2)
110 {
111 if (mpz_cmp (v1, v2) < 0)
112 mpz_set (res, v2);
113 else
114 mpz_set (res, v1);
115 }
116
117
118 /* This flag is set when an error occurred during the translation of
119 CLAST to Gimple. */
120 static bool graphite_regenerate_error;
121
122 /* Verifies properties that GRAPHITE should maintain during translation. */
123
124 static inline void
125 graphite_verify (void)
126 {
127 #ifdef ENABLE_CHECKING
128 verify_loop_structure ();
129 verify_loop_closed_ssa (true);
130 #endif
131 }
132
133 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
134 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
135 upper bounds that can be inferred from the polyhedral representation. */
136
137 typedef struct clast_name_index {
138 int index;
139 int level;
140 mpz_t bound_one, bound_two;
141 const char *name;
142 /* If free_name is set, the content of name was allocated by us and needs
143 to be freed. */
144 char *free_name;
145 } *clast_name_index_p;
146
147 /* Helper for hashing clast_name_index. */
148
149 struct clast_index_hasher
150 {
151 typedef clast_name_index value_type;
152 typedef clast_name_index compare_type;
153 static inline hashval_t hash (const value_type *);
154 static inline bool equal (const value_type *, const compare_type *);
155 static inline void remove (value_type *);
156 };
157
158 /* Computes a hash function for database element E. */
159
160 inline hashval_t
161 clast_index_hasher::hash (const value_type *e)
162 {
163 hashval_t hash = 0;
164
165 int length = strlen (e->name);
166 int i;
167
168 for (i = 0; i < length; ++i)
169 hash = hash | (e->name[i] << (i % 4));
170
171 return hash;
172 }
173
174 /* Compares database elements ELT1 and ELT2. */
175
176 inline bool
177 clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
178 {
179 return strcmp (elt1->name, elt2->name) == 0;
180 }
181
182 /* Free the memory taken by a clast_name_index struct. */
183
184 inline void
185 clast_index_hasher::remove (value_type *c)
186 {
187 if (c->free_name)
188 free (c->free_name);
189 mpz_clear (c->bound_one);
190 mpz_clear (c->bound_two);
191 free (c);
192 }
193
194 typedef hash_table<clast_index_hasher> clast_index_htab_type;
195
196 /* Returns a pointer to a new element of type clast_name_index_p built
197 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
198
199 static inline clast_name_index_p
200 new_clast_name_index (const char *name, int index, int level,
201 mpz_t bound_one, mpz_t bound_two)
202 {
203 clast_name_index_p res = XNEW (struct clast_name_index);
204 char *new_name = XNEWVEC (char, strlen (name) + 1);
205 strcpy (new_name, name);
206
207 res->name = new_name;
208 res->free_name = new_name;
209 res->level = level;
210 res->index = index;
211 mpz_init (res->bound_one);
212 mpz_init (res->bound_two);
213 mpz_set (res->bound_one, bound_one);
214 mpz_set (res->bound_two, bound_two);
215 return res;
216 }
217
218 /* For a given clast NAME, returns -1 if NAME is not in the
219 INDEX_TABLE, otherwise returns the loop level for the induction
220 variable NAME, or if it is a parameter, the parameter number in the
221 vector of parameters. */
222
223 static inline int
224 clast_name_to_level (clast_name_p name, clast_index_htab_type *index_table)
225 {
226 struct clast_name_index tmp;
227 clast_name_index **slot;
228
229 gcc_assert (name->type == clast_expr_name);
230 tmp.name = ((const struct clast_name *) name)->name;
231 tmp.free_name = NULL;
232
233 slot = index_table->find_slot (&tmp, NO_INSERT);
234
235 if (slot && *slot)
236 return ((struct clast_name_index *) *slot)->level;
237
238 return -1;
239 }
240
241 /* For a given clast NAME, returns -1 if it does not correspond to any
242 parameter, or otherwise, returns the index in the PARAMS or
243 SCATTERING_DIMENSIONS vector. */
244
245 static inline int
246 clast_name_to_index (struct clast_name *name, clast_index_htab_type *index_table)
247 {
248 struct clast_name_index tmp;
249 clast_name_index **slot;
250
251 tmp.name = ((const struct clast_name *) name)->name;
252 tmp.free_name = NULL;
253
254 slot = index_table->find_slot (&tmp, NO_INSERT);
255
256 if (slot && *slot)
257 return (*slot)->index;
258
259 return -1;
260 }
261
262 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
263 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
264 found in the INDEX_TABLE, false otherwise. */
265
266 static inline bool
267 clast_name_to_lb_ub (struct clast_name *name,
268 clast_index_htab_type *index_table, mpz_t bound_one,
269 mpz_t bound_two)
270 {
271 struct clast_name_index tmp;
272 clast_name_index **slot;
273
274 tmp.name = name->name;
275 tmp.free_name = NULL;
276
277 slot = index_table->find_slot (&tmp, NO_INSERT);
278
279 if (slot && *slot)
280 {
281 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
282 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
283 return true;
284 }
285
286 return false;
287 }
288
289 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
290
291 static inline void
292 save_clast_name_index (clast_index_htab_type *index_table, const char *name,
293 int index, int level, mpz_t bound_one, mpz_t bound_two)
294 {
295 struct clast_name_index tmp;
296 clast_name_index **slot;
297
298 tmp.name = name;
299 tmp.free_name = NULL;
300 slot = index_table->find_slot (&tmp, INSERT);
301
302 if (slot)
303 {
304 free (*slot);
305
306 *slot = new_clast_name_index (name, index, level, bound_one, bound_two);
307 }
308 }
309 \f
310
311 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
312 induction variable in NEWIVS.
313
314 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
315 parameter in PARAMS. */
316
317 typedef struct ivs_params {
318 vec<tree> params, *newivs;
319 clast_index_htab_type *newivs_index, *params_index;
320 sese region;
321 } *ivs_params_p;
322
323 /* Returns the tree variable from the name NAME that was given in
324 Cloog representation. */
325
326 static tree
327 clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
328 {
329 int index;
330
331 if (ip->params.exists () && ip->params_index)
332 {
333 index = clast_name_to_index (name, ip->params_index);
334
335 if (index >= 0)
336 return ip->params[index];
337 }
338
339 gcc_assert (ip->newivs && ip->newivs_index);
340 index = clast_name_to_index (name, ip->newivs_index);
341 gcc_assert (index >= 0);
342
343 return (*ip->newivs)[index];
344 }
345
346 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
347
348 static tree
349 max_precision_type (tree type1, tree type2)
350 {
351 enum machine_mode mode;
352 int p1, p2, precision;
353 tree type;
354
355 if (POINTER_TYPE_P (type1))
356 return type1;
357
358 if (POINTER_TYPE_P (type2))
359 return type2;
360
361 if (TYPE_UNSIGNED (type1)
362 && TYPE_UNSIGNED (type2))
363 return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
364
365 p1 = TYPE_PRECISION (type1);
366 p2 = TYPE_PRECISION (type2);
367
368 if (p1 > p2)
369 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
370 else
371 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
372
373 if (precision > BITS_PER_WORD)
374 {
375 graphite_regenerate_error = true;
376 return integer_type_node;
377 }
378
379 mode = smallest_mode_for_size (precision, MODE_INT);
380 precision = GET_MODE_PRECISION (mode);
381 type = build_nonstandard_integer_type (precision, false);
382
383 if (!type)
384 {
385 graphite_regenerate_error = true;
386 return integer_type_node;
387 }
388
389 return type;
390 }
391
392 static tree
393 clast_to_gcc_expression (tree, struct clast_expr *, ivs_params_p);
394
395 /* Converts a Cloog reduction expression R with reduction operation OP
396 to a GCC expression tree of type TYPE. */
397
398 static tree
399 clast_to_gcc_expression_red (tree type, enum tree_code op,
400 struct clast_reduction *r, ivs_params_p ip)
401 {
402 int i;
403 tree res = clast_to_gcc_expression (type, r->elts[0], ip);
404 tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
405
406 for (i = 1; i < r->n; i++)
407 {
408 tree t = clast_to_gcc_expression (operand_type, r->elts[i], ip);
409 res = fold_build2 (op, type, res, t);
410 }
411
412 return res;
413 }
414
415 /* Converts a Cloog AST expression E back to a GCC expression tree of
416 type TYPE. */
417
418 static tree
419 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
420 {
421 switch (e->type)
422 {
423 case clast_expr_name:
424 {
425 return clast_name_to_gcc ((struct clast_name *) e, ip);
426 }
427 case clast_expr_term:
428 {
429 struct clast_term *t = (struct clast_term *) e;
430
431 if (t->var)
432 {
433 if (mpz_cmp_si (t->val, 1) == 0)
434 {
435 tree name = clast_to_gcc_expression (type, t->var, ip);
436
437 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
438 name = convert_to_ptrofftype (name);
439
440 name = fold_convert (type, name);
441 return name;
442 }
443
444 else if (mpz_cmp_si (t->val, -1) == 0)
445 {
446 tree name = clast_to_gcc_expression (type, t->var, ip);
447
448 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
449 name = convert_to_ptrofftype (name);
450
451 name = fold_convert (type, name);
452
453 return fold_build1 (NEGATE_EXPR, type, name);
454 }
455 else
456 {
457 tree name = clast_to_gcc_expression (type, t->var, ip);
458 tree cst = gmp_cst_to_tree (type, t->val);
459
460 if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
461 name = convert_to_ptrofftype (name);
462
463 name = fold_convert (type, name);
464
465 if (!POINTER_TYPE_P (type))
466 return fold_build2 (MULT_EXPR, type, cst, name);
467
468 graphite_regenerate_error = true;
469 return cst;
470 }
471 }
472 else
473 return gmp_cst_to_tree (type, t->val);
474 }
475
476 case clast_expr_red:
477 {
478 struct clast_reduction *r = (struct clast_reduction *) e;
479
480 switch (r->type)
481 {
482 case clast_red_sum:
483 return clast_to_gcc_expression_red
484 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
485 r, ip);
486
487 case clast_red_min:
488 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
489
490 case clast_red_max:
491 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
492
493 default:
494 gcc_unreachable ();
495 }
496 break;
497 }
498
499 case clast_expr_bin:
500 {
501 struct clast_binary *b = (struct clast_binary *) e;
502 struct clast_expr *lhs = (struct clast_expr *) b->LHS;
503 tree tl = clast_to_gcc_expression (type, lhs, ip);
504 tree tr = gmp_cst_to_tree (type, b->RHS);
505
506 switch (b->type)
507 {
508 case clast_bin_fdiv:
509 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
510
511 case clast_bin_cdiv:
512 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
513
514 case clast_bin_div:
515 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
516
517 case clast_bin_mod:
518 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
519
520 default:
521 gcc_unreachable ();
522 }
523 }
524
525 default:
526 gcc_unreachable ();
527 }
528
529 return NULL_TREE;
530 }
531
532 /* Return a type that could represent the values between BOUND_ONE and
533 BOUND_TWO. */
534
535 static tree
536 type_for_interval (mpz_t bound_one, mpz_t bound_two)
537 {
538 bool unsigned_p;
539 tree type;
540 enum machine_mode mode;
541 int wider_precision;
542 int precision = MAX (mpz_sizeinbase (bound_one, 2),
543 mpz_sizeinbase (bound_two, 2));
544
545 if (precision > BITS_PER_WORD)
546 {
547 graphite_regenerate_error = true;
548 return integer_type_node;
549 }
550
551 if (mpz_cmp (bound_one, bound_two) <= 0)
552 unsigned_p = (mpz_sgn (bound_one) >= 0);
553 else
554 unsigned_p = (mpz_sgn (bound_two) >= 0);
555
556 mode = smallest_mode_for_size (precision, MODE_INT);
557 wider_precision = GET_MODE_PRECISION (mode);
558
559 /* As we want to generate signed types as much as possible, try to
560 fit the interval [bound_one, bound_two] in a signed type. For example,
561 supposing that we have the interval [0, 100], instead of
562 generating unsigned char, we want to generate a signed char. */
563 if (unsigned_p && precision < wider_precision)
564 unsigned_p = false;
565
566 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
567
568 if (!type)
569 {
570 graphite_regenerate_error = true;
571 return integer_type_node;
572 }
573
574 return type;
575 }
576
577 /* Return a type that could represent the integer value VAL, or
578 otherwise return NULL_TREE. */
579
580 static tree
581 type_for_value (mpz_t val)
582 {
583 return type_for_interval (val, val);
584 }
585
586 static tree
587 type_for_clast_expr (struct clast_expr *, ivs_params_p, mpz_t, mpz_t);
588
589 /* Return the type for the clast_term T. Initializes BOUND_ONE and
590 BOUND_TWO to the bounds of the term. */
591
592 static tree
593 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
594 mpz_t bound_two)
595 {
596 tree type;
597 gcc_assert (t->expr.type == clast_expr_term);
598
599 if (!t->var)
600 {
601 mpz_set (bound_one, t->val);
602 mpz_set (bound_two, t->val);
603 return type_for_value (t->val);
604 }
605
606 type = type_for_clast_expr (t->var, ip, bound_one, bound_two);
607
608 mpz_mul (bound_one, bound_one, t->val);
609 mpz_mul (bound_two, bound_two, t->val);
610
611 return max_precision_type (type, type_for_interval (bound_one, bound_two));
612 }
613
614 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
615 and BOUND_TWO to the bounds of the reduction expression. */
616
617 static tree
618 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
619 mpz_t bound_one, mpz_t bound_two)
620 {
621 int i;
622 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
623 mpz_t b1, b2, m1, m2;
624
625 if (r->n == 1)
626 return type;
627
628 mpz_init (b1);
629 mpz_init (b2);
630 mpz_init (m1);
631 mpz_init (m2);
632
633 for (i = 1; i < r->n; i++)
634 {
635 tree t = type_for_clast_expr (r->elts[i], ip, b1, b2);
636 type = max_precision_type (type, t);
637
638 switch (r->type)
639 {
640 case clast_red_sum:
641 value_min (m1, bound_one, bound_two);
642 value_min (m2, b1, b2);
643 mpz_add (bound_one, m1, m2);
644
645 value_max (m1, bound_one, bound_two);
646 value_max (m2, b1, b2);
647 mpz_add (bound_two, m1, m2);
648 break;
649
650 case clast_red_min:
651 value_min (bound_one, bound_one, bound_two);
652 value_min (bound_two, b1, b2);
653 break;
654
655 case clast_red_max:
656 value_max (bound_one, bound_one, bound_two);
657 value_max (bound_two, b1, b2);
658 break;
659
660 default:
661 gcc_unreachable ();
662 break;
663 }
664 }
665
666 mpz_clear (b1);
667 mpz_clear (b2);
668 mpz_clear (m1);
669 mpz_clear (m2);
670
671 /* Return a type that can represent the result of the reduction. */
672 return max_precision_type (type, type_for_interval (bound_one, bound_two));
673 }
674
675 /* Return the type for the clast_binary B used in STMT. */
676
677 static tree
678 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
679 mpz_t bound_two)
680 {
681 mpz_t one;
682 tree l = type_for_clast_expr ((struct clast_expr *) b->LHS, ip,
683 bound_one, bound_two);
684 tree r = type_for_value (b->RHS);
685 tree type = max_precision_type (l, r);
686
687 switch (b->type)
688 {
689 case clast_bin_fdiv:
690 mpz_mdiv (bound_one, bound_one, b->RHS);
691 mpz_mdiv (bound_two, bound_two, b->RHS);
692 break;
693
694 case clast_bin_cdiv:
695 mpz_mdiv (bound_one, bound_one, b->RHS);
696 mpz_mdiv (bound_two, bound_two, b->RHS);
697 mpz_init (one);
698 mpz_add (bound_one, bound_one, one);
699 mpz_add (bound_two, bound_two, one);
700 mpz_clear (one);
701 break;
702
703 case clast_bin_div:
704 mpz_div (bound_one, bound_one, b->RHS);
705 mpz_div (bound_two, bound_two, b->RHS);
706 break;
707
708 case clast_bin_mod:
709 mpz_mod (bound_one, bound_one, b->RHS);
710 mpz_mod (bound_two, bound_two, b->RHS);
711 break;
712
713 default:
714 gcc_unreachable ();
715 }
716
717 /* Return a type that can represent the result of the reduction. */
718 return max_precision_type (type, type_for_interval (bound_one, bound_two));
719 }
720
721 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
722 BOUND_TWO to the bounds of the term. */
723
724 static tree
725 type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
726 mpz_t bound_two)
727 {
728 bool found = false;
729
730 if (ip->params.exists () && ip->params_index)
731 found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
732
733 if (!found)
734 {
735 gcc_assert (ip->newivs && ip->newivs_index);
736 found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
737 bound_two);
738 gcc_assert (found);
739 }
740
741 return TREE_TYPE (clast_name_to_gcc (name, ip));
742 }
743
744 /* Returns the type for the CLAST expression E when used in statement
745 STMT. */
746
747 static tree
748 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
749 mpz_t bound_two)
750 {
751 switch (e->type)
752 {
753 case clast_expr_term:
754 return type_for_clast_term ((struct clast_term *) e, ip,
755 bound_one, bound_two);
756
757 case clast_expr_red:
758 return type_for_clast_red ((struct clast_reduction *) e, ip,
759 bound_one, bound_two);
760
761 case clast_expr_bin:
762 return type_for_clast_bin ((struct clast_binary *) e, ip,
763 bound_one, bound_two);
764
765 case clast_expr_name:
766 return type_for_clast_name ((struct clast_name *) e, ip,
767 bound_one, bound_two);
768
769 default:
770 gcc_unreachable ();
771 }
772
773 return NULL_TREE;
774 }
775
776 /* Returns true if the clast expression E is a constant with VALUE. */
777
778 static bool
779 clast_expr_const_value_p (struct clast_expr *e, int value)
780 {
781 struct clast_term *t;
782 if (e->type != clast_expr_term)
783 return false;
784 t = (struct clast_term *)e;
785 if (t->var)
786 return false;
787 return 0 == mpz_cmp_si (t->val, value);
788 }
789
790 /* Translates a clast equation CLEQ to a tree. */
791
792 static tree
793 graphite_translate_clast_equation (struct clast_equation *cleq,
794 ivs_params_p ip)
795 {
796 enum tree_code comp;
797 tree type, lhs, rhs, ltype, rtype;
798 mpz_t bound_one, bound_two;
799 struct clast_expr *clhs, *crhs;
800
801 clhs = cleq->LHS;
802 crhs = cleq->RHS;
803 if (cleq->sign == 0)
804 comp = EQ_EXPR;
805 else if (cleq->sign > 0)
806 comp = GE_EXPR;
807 else
808 comp = LE_EXPR;
809
810 /* Special cases to reduce range of arguments to hopefully
811 don't need types with larger precision than the input. */
812 if (crhs->type == clast_expr_red
813 && comp != EQ_EXPR)
814 {
815 struct clast_reduction *r = (struct clast_reduction *) crhs;
816 /* X >= A+1 --> X > A and
817 X <= A-1 --> X < A */
818 if (r->n == 2
819 && r->type == clast_red_sum
820 && clast_expr_const_value_p (r->elts[1], comp == GE_EXPR ? 1 : -1))
821 {
822 crhs = r->elts[0];
823 comp = comp == GE_EXPR ? GT_EXPR : LT_EXPR;
824 }
825 }
826
827 mpz_init (bound_one);
828 mpz_init (bound_two);
829
830 ltype = type_for_clast_expr (clhs, ip, bound_one, bound_two);
831 rtype = type_for_clast_expr (crhs, ip, bound_one, bound_two);
832
833 mpz_clear (bound_one);
834 mpz_clear (bound_two);
835 type = max_precision_type (ltype, rtype);
836
837 lhs = clast_to_gcc_expression (type, clhs, ip);
838 rhs = clast_to_gcc_expression (type, crhs, ip);
839
840 return fold_build2 (comp, boolean_type_node, lhs, rhs);
841 }
842
843 /* Creates the test for the condition in STMT. */
844
845 static tree
846 graphite_create_guard_cond_expr (struct clast_guard *stmt,
847 ivs_params_p ip)
848 {
849 tree cond = NULL;
850 int i;
851
852 for (i = 0; i < stmt->n; i++)
853 {
854 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
855
856 if (cond)
857 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
858 else
859 cond = eq;
860 }
861
862 return cond;
863 }
864
865 /* Creates a new if region corresponding to Cloog's guard. */
866
867 static edge
868 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
869 ivs_params_p ip)
870 {
871 tree cond_expr = graphite_create_guard_cond_expr (stmt, ip);
872 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
873 return exit_edge;
874 }
875
876 /* Compute the lower bound LOW and upper bound UP for the parameter
877 PARAM in scop SCOP based on the constraints in the context. */
878
879 static void
880 compute_bounds_for_param (scop_p scop, int param, mpz_t low, mpz_t up)
881 {
882 isl_val *v;
883 isl_aff *aff = isl_aff_zero_on_domain
884 (isl_local_space_from_space (isl_set_get_space (scop->context)));
885
886 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, param, 1);
887
888 v = isl_set_min_val (scop->context, aff);
889 isl_val_get_num_gmp (v, low);
890 isl_val_free (v);
891 v = isl_set_max_val (scop->context, aff);
892 isl_val_get_num_gmp (v, up);
893 isl_val_free (v);
894 isl_aff_free (aff);
895 }
896
897 /* Compute the lower bound LOW and upper bound UP for the induction
898 variable of loop LOOP.
899
900 FIXME: This one is not entirely correct, as min/max expressions in the
901 calculation can yield to incorrect results. To be completely
902 correct, we need to evaluate each subexpression generated by
903 CLooG. CLooG does not yet support this, so this is as good as
904 it can be. */
905
906 static void
907 compute_bounds_for_loop (struct clast_for *loop, mpz_t low, mpz_t up)
908 {
909 isl_set *domain;
910 isl_aff *dimension;
911 isl_local_space *local_space;
912 isl_val *isl_value;
913
914 domain = isl_set_copy (isl_set_from_cloog_domain (loop->domain));
915 local_space = isl_local_space_from_space (isl_set_get_space (domain));
916 dimension = isl_aff_zero_on_domain (local_space);
917 dimension = isl_aff_add_coefficient_si (dimension, isl_dim_in,
918 isl_set_dim (domain, isl_dim_set) - 1,
919 1);
920
921 isl_value = isl_set_min_val (domain, dimension);
922 isl_val_get_num_gmp (isl_value, low);
923 isl_val_free (isl_value);
924 isl_value = isl_set_max_val (domain, dimension);
925 isl_val_get_num_gmp (isl_value, up);
926 isl_val_free (isl_value);
927 isl_set_free (domain);
928 isl_aff_free (dimension);
929 }
930
931 /* Returns the type for the induction variable for the loop translated
932 from STMT_FOR. */
933
934 static tree
935 type_for_clast_for (struct clast_for *stmt_for, ivs_params_p ip)
936 {
937 mpz_t bound_one, bound_two;
938 tree lb_type, ub_type;
939
940 mpz_init (bound_one);
941 mpz_init (bound_two);
942
943 lb_type = type_for_clast_expr (stmt_for->LB, ip, bound_one, bound_two);
944 ub_type = type_for_clast_expr (stmt_for->UB, ip, bound_one, bound_two);
945
946 mpz_clear (bound_one);
947 mpz_clear (bound_two);
948
949 return max_precision_type (lb_type, ub_type);
950 }
951
952 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
953 induction variable for the new LOOP. New LOOP is attached to CFG
954 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
955 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
956 CLooG's scattering name to the induction variable created for the
957 loop of STMT. The new induction variable is inserted in the NEWIVS
958 vector and is of type TYPE. */
959
960 static struct loop *
961 graphite_create_new_loop (edge entry_edge, struct clast_for *stmt,
962 loop_p outer, tree type, tree lb, tree ub,
963 int level, ivs_params_p ip)
964 {
965 mpz_t low, up;
966
967 tree stride = gmp_cst_to_tree (type, stmt->stride);
968 tree ivvar = create_tmp_var (type, "graphite_IV");
969 tree iv, iv_after_increment;
970 loop_p loop = create_empty_loop_on_edge
971 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
972 outer ? outer : entry_edge->src->loop_father);
973
974 mpz_init (low);
975 mpz_init (up);
976 compute_bounds_for_loop (stmt, low, up);
977 save_clast_name_index (ip->newivs_index, stmt->iterator,
978 (*ip->newivs).length (), level, low, up);
979 mpz_clear (low);
980 mpz_clear (up);
981 (*ip->newivs).safe_push (iv);
982 return loop;
983 }
984
985 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
986 induction variables of the loops around GBB in SESE. */
987
988 static void
989 build_iv_mapping (vec<tree> iv_map, struct clast_user_stmt *user_stmt,
990 ivs_params_p ip)
991 {
992 struct clast_stmt *t;
993 int depth = 0;
994 CloogStatement *cs = user_stmt->statement;
995 poly_bb_p pbb = (poly_bb_p) cs->usr;
996 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
997 mpz_t bound_one, bound_two;
998
999 mpz_init (bound_one);
1000 mpz_init (bound_two);
1001
1002 for (t = user_stmt->substitutions; t; t = t->next, depth++)
1003 {
1004 struct clast_expr *expr = (struct clast_expr *)
1005 ((struct clast_assignment *)t)->RHS;
1006 tree type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1007 tree new_name = clast_to_gcc_expression (type, expr, ip);
1008 loop_p old_loop = gbb_loop_at_index (gbb, ip->region, depth);
1009
1010 iv_map[old_loop->num] = new_name;
1011 }
1012
1013 mpz_clear (bound_one);
1014 mpz_clear (bound_two);
1015 }
1016
1017 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1018
1019 static void
1020 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
1021 bb_pbb_htab_type *bb_pbb_mapping)
1022 {
1023 bool existed;
1024 poly_bb_p &e = bb_pbb_mapping->get_or_insert (bb, &existed);
1025 if (!existed)
1026 e = pbb;
1027 }
1028
1029 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1030
1031 poly_bb_p
1032 find_pbb_via_hash (bb_pbb_htab_type *bb_pbb_mapping, basic_block bb)
1033 {
1034 poly_bb_p *pbb = bb_pbb_mapping->get (bb);
1035 if (pbb)
1036 return *pbb;
1037
1038 return NULL;
1039 }
1040
1041 /* Return the scop of the loop and initialize PBBS the set of
1042 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1043 by the CLAST code generator between a generated basic_block and its
1044 related poly_bb_p. */
1045
1046 scop_p
1047 get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type *bb_pbb_mapping,
1048 vec<poly_bb_p> *pbbs)
1049 {
1050 unsigned i;
1051 basic_block *bbs = get_loop_body_in_dom_order (loop);
1052 scop_p scop = NULL;
1053
1054 for (i = 0; i < loop->num_nodes; i++)
1055 {
1056 poly_bb_p pbb = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
1057
1058 if (pbb == NULL)
1059 continue;
1060
1061 scop = PBB_SCOP (pbb);
1062 (*pbbs).safe_push (pbb);
1063 }
1064
1065 free (bbs);
1066 return scop;
1067 }
1068
1069 /* Translates a clast user statement STMT to gimple.
1070
1071 - NEXT_E is the edge where new generated code should be attached.
1072 - CONTEXT_LOOP is the loop in which the generated code will be placed
1073 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1074
1075 static edge
1076 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1077 bb_pbb_htab_type *bb_pbb_mapping, ivs_params_p ip)
1078 {
1079 int i, nb_loops;
1080 basic_block new_bb;
1081 poly_bb_p pbb = (poly_bb_p) stmt->statement->usr;
1082 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1083 vec<tree> iv_map;
1084
1085 if (GBB_BB (gbb) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1086 return next_e;
1087
1088 nb_loops = number_of_loops (cfun);
1089 iv_map.create (nb_loops);
1090 for (i = 0; i < nb_loops; i++)
1091 iv_map.quick_push (NULL_TREE);
1092
1093 build_iv_mapping (iv_map, stmt, ip);
1094 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
1095 next_e, iv_map,
1096 &graphite_regenerate_error);
1097 iv_map.release ();
1098
1099 new_bb = next_e->src;
1100 mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
1101 mark_virtual_operands_for_renaming (cfun);
1102 update_ssa (TODO_update_ssa);
1103
1104 return next_e;
1105 }
1106
1107 /* Creates a new if region protecting the loop to be executed, if the execution
1108 count is zero (lb > ub). */
1109
1110 static edge
1111 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1112 tree *type, tree *lb, tree *ub,
1113 ivs_params_p ip)
1114 {
1115 tree cond_expr;
1116 edge exit_edge;
1117
1118 *type = type_for_clast_for (stmt, ip);
1119 *lb = clast_to_gcc_expression (*type, stmt->LB, ip);
1120 *ub = clast_to_gcc_expression (*type, stmt->UB, ip);
1121
1122 /* When ub is simply a constant or a parameter, use lb <= ub. */
1123 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
1124 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
1125 else
1126 {
1127 tree one = (POINTER_TYPE_P (*type)
1128 ? convert_to_ptrofftype (integer_one_node)
1129 : fold_convert (*type, integer_one_node));
1130 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1131 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1132 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1133 even if we do not want this. However lb < ub + 1 is false, as
1134 expected. */
1135 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
1136 : PLUS_EXPR, *type, *ub, one);
1137
1138 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
1139 }
1140
1141 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1142
1143 return exit_edge;
1144 }
1145
1146 static edge
1147 translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type *,
1148 int, ivs_params_p);
1149
1150 /* Create the loop for a clast for statement.
1151
1152 - NEXT_E is the edge where new generated code should be attached.
1153 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1154
1155 static edge
1156 translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
1157 edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
1158 int level, tree type, tree lb, tree ub,
1159 ivs_params_p ip)
1160 {
1161 struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
1162 type, lb, ub, level, ip);
1163 edge last_e = single_exit (loop);
1164 edge to_body = single_succ_edge (loop->header);
1165 basic_block after = to_body->dest;
1166
1167 /* Create a basic block for loop close phi nodes. */
1168 last_e = single_succ_edge (split_edge (last_e));
1169
1170 /* Translate the body of the loop. */
1171 next_e = translate_clast (loop, stmt->body, to_body, bb_pbb_mapping,
1172 level + 1, ip);
1173 redirect_edge_succ_nodup (next_e, after);
1174 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
1175
1176 isl_set *domain = isl_set_from_cloog_domain (stmt->domain);
1177 int scheduling_dim = isl_set_n_dim (domain);
1178
1179 if (flag_loop_parallelize_all
1180 && loop_is_parallel_p (loop, bb_pbb_mapping, scheduling_dim))
1181 loop->can_be_parallel = true;
1182
1183 return last_e;
1184 }
1185
1186 /* Translates a clast for statement STMT to gimple. First a guard is created
1187 protecting the loop, if it is executed zero times. In this guard we create
1188 the real loop structure.
1189
1190 - NEXT_E is the edge where new generated code should be attached.
1191 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1192
1193 static edge
1194 translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
1195 bb_pbb_htab_type *bb_pbb_mapping, int level,
1196 ivs_params_p ip)
1197 {
1198 tree type, lb, ub;
1199 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1200 &lb, &ub, ip);
1201 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1202
1203 translate_clast_for_loop (context_loop, stmt, true_e, bb_pbb_mapping, level,
1204 type, lb, ub, ip);
1205 return last_e;
1206 }
1207
1208 /* Translates a clast assignment STMT to gimple.
1209
1210 - NEXT_E is the edge where new generated code should be attached.
1211 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1212
1213 static edge
1214 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1215 int level, ivs_params_p ip)
1216 {
1217 gimple_seq stmts;
1218 mpz_t bound_one, bound_two;
1219 tree type, new_name, var;
1220 edge res = single_succ_edge (split_edge (next_e));
1221 struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
1222
1223 mpz_init (bound_one);
1224 mpz_init (bound_two);
1225 type = type_for_clast_expr (expr, ip, bound_one, bound_two);
1226 var = create_tmp_var (type, "graphite_var");
1227 new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
1228 &stmts, true, var);
1229 if (stmts)
1230 {
1231 gsi_insert_seq_on_edge (next_e, stmts);
1232 gsi_commit_edge_inserts ();
1233 }
1234
1235 save_clast_name_index (ip->newivs_index, stmt->LHS,
1236 (*ip->newivs).length (), level,
1237 bound_one, bound_two);
1238 (*ip->newivs).safe_push (new_name);
1239
1240 mpz_clear (bound_one);
1241 mpz_clear (bound_two);
1242
1243 return res;
1244 }
1245
1246 /* Translates a clast guard statement STMT to gimple.
1247
1248 - NEXT_E is the edge where new generated code should be attached.
1249 - CONTEXT_LOOP is the loop in which the generated code will be placed
1250 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1251
1252 static edge
1253 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1254 edge next_e, bb_pbb_htab_type *bb_pbb_mapping, int level,
1255 ivs_params_p ip)
1256 {
1257 edge last_e = graphite_create_new_guard (next_e, stmt, ip);
1258 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1259
1260 translate_clast (context_loop, stmt->then, true_e, bb_pbb_mapping, level, ip);
1261 return last_e;
1262 }
1263
1264 /* Translates a CLAST statement STMT to GCC representation in the
1265 context of a SESE.
1266
1267 - NEXT_E is the edge where new generated code should be attached.
1268 - CONTEXT_LOOP is the loop in which the generated code will be placed
1269 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1270
1271 static edge
1272 translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
1273 bb_pbb_htab_type *bb_pbb_mapping, int level, ivs_params_p ip)
1274 {
1275 if (!stmt)
1276 return next_e;
1277
1278 if (CLAST_STMT_IS_A (stmt, stmt_root))
1279 ; /* Do nothing. */
1280
1281 else if (CLAST_STMT_IS_A (stmt, stmt_user))
1282 next_e = translate_clast_user ((struct clast_user_stmt *) stmt,
1283 next_e, bb_pbb_mapping, ip);
1284
1285 else if (CLAST_STMT_IS_A (stmt, stmt_for))
1286 next_e = translate_clast_for (context_loop, (struct clast_for *) stmt,
1287 next_e, bb_pbb_mapping, level, ip);
1288
1289 else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1290 next_e = translate_clast_guard (context_loop, (struct clast_guard *) stmt,
1291 next_e, bb_pbb_mapping, level, ip);
1292
1293 else if (CLAST_STMT_IS_A (stmt, stmt_block))
1294 next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
1295 next_e, bb_pbb_mapping, level, ip);
1296
1297 else if (CLAST_STMT_IS_A (stmt, stmt_ass))
1298 next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
1299 next_e, level, ip);
1300 else
1301 gcc_unreachable ();
1302
1303 recompute_all_dominators ();
1304 graphite_verify ();
1305
1306 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1307 level, ip);
1308 }
1309
1310 /* Add parameter and iterator names to the CloogUnionDomain. */
1311
1312 static CloogUnionDomain *
1313 add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
1314 int nb_scattering_dims,
1315 clast_index_htab_type *params_index)
1316 {
1317 sese region = SCOP_REGION (scop);
1318 int i;
1319 int nb_iterators = scop_max_loop_depth (scop);
1320 int nb_parameters = SESE_PARAMS (region).length ();
1321 mpz_t bound_one, bound_two;
1322
1323 mpz_init (bound_one);
1324 mpz_init (bound_two);
1325
1326 for (i = 0; i < nb_parameters; i++)
1327 {
1328 tree param = SESE_PARAMS (region)[i];
1329 const char *name = get_name (param);
1330 int len;
1331 char *parameter;
1332
1333 if (!name)
1334 name = "T";
1335
1336 len = strlen (name);
1337 len += 17;
1338 parameter = XNEWVEC (char, len + 1);
1339 snprintf (parameter, len, "%s_%d", name, SSA_NAME_VERSION (param));
1340 save_clast_name_index (params_index, parameter, i, i, bound_one,
1341 bound_two);
1342 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_PARAM, i,
1343 parameter);
1344 compute_bounds_for_param (scop, i, bound_one, bound_two);
1345 free (parameter);
1346 }
1347
1348 mpz_clear (bound_one);
1349 mpz_clear (bound_two);
1350
1351 for (i = 0; i < nb_iterators; i++)
1352 {
1353 int len = 4 + 16;
1354 char *iterator;
1355 iterator = XNEWVEC (char, len);
1356 snprintf (iterator, len, "git_%d", i);
1357 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_ITER, i,
1358 iterator);
1359 free (iterator);
1360 }
1361
1362 for (i = 0; i < nb_scattering_dims; i++)
1363 {
1364 int len = 5 + 16;
1365 char *scattering;
1366 scattering = XNEWVEC (char, len);
1367 snprintf (scattering, len, "scat_%d", i);
1368 union_domain = cloog_union_domain_set_name (union_domain, CLOOG_SCAT, i,
1369 scattering);
1370 free (scattering);
1371 }
1372
1373 return union_domain;
1374 }
1375
1376 /* Initialize a CLooG input file. */
1377
1378 static FILE *
1379 init_cloog_input_file (int scop_number)
1380 {
1381 FILE *graphite_out_file;
1382 int len = strlen (dump_base_name);
1383 char *dumpname = XNEWVEC (char, len + 25);
1384 char *s_scop_number = XNEWVEC (char, 15);
1385
1386 memcpy (dumpname, dump_base_name, len + 1);
1387 strip_off_ending (dumpname, len);
1388 sprintf (s_scop_number, ".%d", scop_number);
1389 strcat (dumpname, s_scop_number);
1390 strcat (dumpname, ".cloog");
1391 graphite_out_file = fopen (dumpname, "w+b");
1392
1393 if (graphite_out_file == 0)
1394 fatal_error ("can%'t open %s for writing: %m", dumpname);
1395
1396 free (dumpname);
1397
1398 return graphite_out_file;
1399 }
1400
1401 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1402
1403 static
1404 isl_map *extend_scattering (isl_map *scattering, int new_dims)
1405 {
1406 int old_dims, i;
1407 isl_space *space;
1408 isl_basic_map *change_scattering;
1409 isl_map *change_scattering_map;
1410
1411 old_dims = isl_map_dim (scattering, isl_dim_out);
1412
1413 space = isl_space_alloc (isl_map_get_ctx (scattering), 0, old_dims, new_dims);
1414 change_scattering = isl_basic_map_universe (isl_space_copy (space));
1415
1416 for (i = 0; i < old_dims; i++)
1417 {
1418 isl_constraint *c;
1419 c = isl_equality_alloc
1420 (isl_local_space_from_space (isl_space_copy (space)));
1421 isl_constraint_set_coefficient_si (c, isl_dim_in, i, 1);
1422 isl_constraint_set_coefficient_si (c, isl_dim_out, i, -1);
1423 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1424 }
1425
1426 for (i = old_dims; i < new_dims; i++)
1427 {
1428 isl_constraint *c;
1429 c = isl_equality_alloc
1430 (isl_local_space_from_space (isl_space_copy (space)));
1431 isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
1432 change_scattering = isl_basic_map_add_constraint (change_scattering, c);
1433 }
1434
1435 change_scattering_map = isl_map_from_basic_map (change_scattering);
1436 change_scattering_map = isl_map_align_params (change_scattering_map, space);
1437 return isl_map_apply_range (scattering, change_scattering_map);
1438 }
1439
1440 /* Build cloog union domain for SCoP. */
1441
1442 static CloogUnionDomain *
1443 build_cloog_union_domain (scop_p scop, int nb_scattering_dims)
1444 {
1445 int i;
1446 poly_bb_p pbb;
1447 CloogUnionDomain *union_domain =
1448 cloog_union_domain_alloc (scop_nb_params (scop));
1449
1450 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1451 {
1452 CloogDomain *domain;
1453 CloogScattering *scattering;
1454
1455 /* Dead code elimination: when the domain of a PBB is empty,
1456 don't generate code for the PBB. */
1457 if (isl_set_is_empty (pbb->domain))
1458 continue;
1459
1460 domain = cloog_domain_from_isl_set (isl_set_copy (pbb->domain));
1461 scattering = cloog_scattering_from_isl_map
1462 (extend_scattering (isl_map_copy (pbb->transformed),
1463 nb_scattering_dims));
1464
1465 union_domain = cloog_union_domain_add_domain (union_domain, "", domain,
1466 scattering, pbb);
1467 }
1468
1469 return union_domain;
1470 }
1471
1472 /* Return the options that will be used in graphite_regenerate_ast_cloog. */
1473
1474 static CloogOptions *
1475 set_cloog_options (void)
1476 {
1477 CloogOptions *options = cloog_options_malloc (cloog_state);
1478
1479 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1480 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1481 we pass an incomplete program to cloog. */
1482 options->language = CLOOG_LANGUAGE_C;
1483
1484 /* Enable complex equality spreading: removes dummy statements
1485 (assignments) in the generated code which repeats the
1486 substitution equations for statements. This is useless for
1487 graphite_regenerate_ast_cloog. */
1488 options->esp = 1;
1489
1490 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1491 options->quiet = 1;
1492
1493 /* Allow cloog to build strides with a stride width different to one.
1494 This example has stride = 4:
1495
1496 for (i = 0; i < 20; i += 4)
1497 A */
1498 options->strides = 1;
1499
1500 /* We want the clast to provide the iteration domains of the executed loops.
1501 This allows us to derive minimal/maximal values for the induction
1502 variables. */
1503 options->save_domains = 1;
1504
1505 /* Do not remove scalar dimensions. CLooG by default removes scalar
1506 dimensions very early from the input schedule. However, they are
1507 necessary to correctly derive from the saved domains
1508 (options->save_domains) the relationship between the generated loops
1509 and the schedule dimensions they are generated from. */
1510 options->noscalars = 1;
1511
1512 /* Disable optimizations and make cloog generate source code closer to the
1513 input. This is useful for debugging, but later we want the optimized
1514 code.
1515
1516 XXX: We can not disable optimizations, as loop blocking is not working
1517 without them. */
1518 if (0)
1519 {
1520 options->f = -1;
1521 options->l = INT_MAX;
1522 }
1523
1524 return options;
1525 }
1526
1527 /* Prints STMT to STDERR. */
1528
1529 void
1530 print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1531 {
1532 CloogOptions *options = set_cloog_options ();
1533
1534 clast_pprint (file, stmt, 0, options);
1535 cloog_options_free (options);
1536 }
1537
1538 /* Prints STMT to STDERR. */
1539
1540 DEBUG_FUNCTION void
1541 debug_clast_stmt (struct clast_stmt *stmt)
1542 {
1543 print_clast_stmt (stderr, stmt);
1544 }
1545
1546 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1547
1548 static
1549 int get_max_scattering_dimensions (scop_p scop)
1550 {
1551 int i;
1552 poly_bb_p pbb;
1553 int scattering_dims = 0;
1554
1555 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1556 {
1557 int pbb_scatt_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1558 if (pbb_scatt_dims > scattering_dims)
1559 scattering_dims = pbb_scatt_dims;
1560 }
1561
1562 return scattering_dims;
1563 }
1564
1565 static CloogInput *
1566 generate_cloog_input (scop_p scop, clast_index_htab_type *params_index)
1567 {
1568 CloogUnionDomain *union_domain;
1569 CloogInput *cloog_input;
1570 CloogDomain *context;
1571 int nb_scattering_dims = get_max_scattering_dimensions (scop);
1572
1573 union_domain = build_cloog_union_domain (scop, nb_scattering_dims);
1574 union_domain = add_names_to_union_domain (scop, union_domain,
1575 nb_scattering_dims,
1576 params_index);
1577 context = cloog_domain_from_isl_set (isl_set_copy (scop->context));
1578
1579 cloog_input = cloog_input_alloc (context, union_domain);
1580
1581 return cloog_input;
1582 }
1583
1584 /* Translate SCOP to a CLooG program and clast. These two
1585 representations should be freed together: a clast cannot be used
1586 without a program. */
1587
1588 static struct clast_stmt *
1589 scop_to_clast (scop_p scop, clast_index_htab_type *params_index)
1590 {
1591 CloogInput *cloog_input;
1592 struct clast_stmt *clast;
1593 CloogOptions *options = set_cloog_options ();
1594
1595 cloog_input = generate_cloog_input (scop, params_index);
1596
1597 /* Dump a .cloog input file, if requested. This feature is only
1598 enabled in the Graphite branch. */
1599 if (0)
1600 {
1601 static size_t file_scop_number = 0;
1602 FILE *cloog_file = init_cloog_input_file (file_scop_number);
1603 cloog_input_dump_cloog (cloog_file, cloog_input, options);
1604 }
1605
1606 clast = cloog_clast_create_from_input (cloog_input, options);
1607
1608 cloog_options_free (options);
1609 return clast;
1610 }
1611
1612 /* Prints to FILE the code generated by CLooG for SCOP. */
1613
1614 void
1615 print_generated_program (FILE *file, scop_p scop)
1616 {
1617 CloogOptions *options = set_cloog_options ();
1618 clast_index_htab_type *params_index = new clast_index_htab_type (10);
1619 struct clast_stmt *clast;
1620
1621 clast = scop_to_clast (scop, params_index);
1622
1623 fprintf (file, " (clast: \n");
1624 clast_pprint (file, clast, 0, options);
1625 fprintf (file, " )\n");
1626
1627 cloog_options_free (options);
1628 cloog_clast_free (clast);
1629 }
1630
1631 /* Prints to STDERR the code generated by CLooG for SCOP. */
1632
1633 DEBUG_FUNCTION void
1634 debug_generated_program (scop_p scop)
1635 {
1636 print_generated_program (stderr, scop);
1637 }
1638
1639 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1640 the given SCOP. Return true if code generation succeeded.
1641 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1642 */
1643
1644 bool
1645 graphite_regenerate_ast_cloog (scop_p scop, bb_pbb_htab_type *bb_pbb_mapping)
1646 {
1647 auto_vec<tree, 10> newivs;
1648 loop_p context_loop;
1649 sese region = SCOP_REGION (scop);
1650 ifsese if_region = NULL;
1651 clast_index_htab_type *newivs_index, *params_index;
1652 struct clast_stmt *clast;
1653 struct ivs_params ip;
1654
1655 timevar_push (TV_GRAPHITE_CODE_GEN);
1656 graphite_regenerate_error = false;
1657
1658 params_index = new clast_index_htab_type (10);
1659
1660 clast = scop_to_clast (scop, params_index);
1661
1662 if (dump_file && (dump_flags & TDF_DETAILS))
1663 {
1664 fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1665 print_clast_stmt (dump_file, clast);
1666 fprintf (dump_file, "\n");
1667 }
1668
1669 recompute_all_dominators ();
1670 graphite_verify ();
1671
1672 if_region = move_sese_in_condition (region);
1673 sese_insert_phis_for_liveouts (region,
1674 if_region->region->exit->src,
1675 if_region->false_region->exit,
1676 if_region->true_region->exit);
1677 recompute_all_dominators ();
1678 graphite_verify ();
1679
1680 context_loop = SESE_ENTRY (region)->src->loop_father;
1681 newivs_index= new clast_index_htab_type (10);
1682
1683 ip.newivs = &newivs;
1684 ip.newivs_index = newivs_index;
1685 ip.params = SESE_PARAMS (region);
1686 ip.params_index = params_index;
1687 ip.region = region;
1688
1689 translate_clast (context_loop, clast, if_region->true_region->entry,
1690 bb_pbb_mapping, 0, &ip);
1691 graphite_verify ();
1692 scev_reset ();
1693 recompute_all_dominators ();
1694 graphite_verify ();
1695
1696 if (graphite_regenerate_error)
1697 set_ifsese_condition (if_region, integer_zero_node);
1698
1699 free (if_region->true_region);
1700 free (if_region->region);
1701 free (if_region);
1702
1703 delete newivs_index;
1704 newivs_index = NULL;
1705 delete params_index;
1706 params_index = NULL;
1707 cloog_clast_free (clast);
1708 timevar_pop (TV_GRAPHITE_CODE_GEN);
1709
1710 if (dump_file && (dump_flags & TDF_DETAILS))
1711 {
1712 loop_p loop;
1713 int num_no_dependency = 0;
1714
1715 FOR_EACH_LOOP (loop, 0)
1716 if (loop->can_be_parallel)
1717 num_no_dependency++;
1718
1719 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1720 num_no_dependency);
1721 }
1722
1723 return !graphite_regenerate_error;
1724 }
1725 #endif