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