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