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