avoid generation of empty guards in trivial cases
[gcc.git] / gcc / graphite-isl-ast-to-gimple.c
1 /* Translation of ISL AST to Gimple.
2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
3 Contributed by Roman Gareev <gareevroman@gmail.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_isl
24 /* Workaround for GMP 5.1.3 bug, see PR56019. */
25 #include <stddef.h>
26
27 #include <isl/constraint.h>
28 #include <isl/set.h>
29 #include <isl/union_set.h>
30 #include <isl/map.h>
31 #include <isl/union_map.h>
32 #include <isl/ast_build.h>
33
34 /* Since ISL-0.13, the extern is in val_gmp.h. */
35 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
36 extern "C" {
37 #endif
38 #include <isl/val_gmp.h>
39 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
40 }
41 #endif
42
43 #include "system.h"
44 #include "coretypes.h"
45 #include "backend.h"
46 #include "cfghooks.h"
47 #include "tree.h"
48 #include "gimple.h"
49 #include "params.h"
50 #include "fold-const.h"
51 #include "gimple-iterator.h"
52 #include "tree-ssa-loop.h"
53 #include "tree-pass.h"
54 #include "cfgloop.h"
55 #include "tree-data-ref.h"
56 #include "graphite-poly.h"
57 #include "tree-ssa-loop-manip.h"
58 #include "tree-scalar-evolution.h"
59 #include "gimple-ssa.h"
60 #include "tree-phinodes.h"
61 #include "tree-into-ssa.h"
62 #include "ssa-iterators.h"
63 #include <map>
64 #include "graphite-isl-ast-to-gimple.h"
65
66 /* This flag is set when an error occurred during the translation of
67 ISL AST to Gimple. */
68
69 static bool graphite_regenerate_error;
70
71 /* We always try to use signed 128 bit types, but fall back to smaller types
72 in case a platform does not provide types of these sizes. In the future we
73 should use isl to derive the optimal type for each subexpression. */
74
75 static int max_mode_int_precision =
76 GET_MODE_PRECISION (mode_for_size (MAX_FIXED_MODE_SIZE, MODE_INT, 0));
77 static int graphite_expression_type_precision = 128 <= max_mode_int_precision ?
78 128 : max_mode_int_precision;
79
80 struct ast_build_info
81 {
82 ast_build_info()
83 : is_parallelizable(false)
84 { };
85 bool is_parallelizable;
86 };
87
88 /* Converts a GMP constant VAL to a tree and returns it. */
89
90 static tree
91 gmp_cst_to_tree (tree type, mpz_t val)
92 {
93 tree t = type ? type : integer_type_node;
94 mpz_t tmp;
95
96 mpz_init (tmp);
97 mpz_set (tmp, val);
98 wide_int wi = wi::from_mpz (t, tmp, true);
99 mpz_clear (tmp);
100
101 return wide_int_to_tree (t, wi);
102 }
103
104 /* Verifies properties that GRAPHITE should maintain during translation. */
105
106 static inline void
107 graphite_verify (void)
108 {
109 #ifdef ENABLE_CHECKING
110 verify_loop_structure ();
111 verify_loop_closed_ssa (true);
112 #endif
113 }
114
115 /* IVS_PARAMS maps ISL's scattering and parameter identifiers
116 to corresponding trees. */
117
118 typedef std::map<isl_id *, tree> ivs_params;
119
120 /* Free all memory allocated for ISL's identifiers. */
121
122 void ivs_params_clear (ivs_params &ip)
123 {
124 std::map<isl_id *, tree>::iterator it;
125 for (it = ip.begin ();
126 it != ip.end (); it++)
127 {
128 isl_id_free (it->first);
129 }
130 }
131
132 class translate_isl_ast_to_gimple
133 {
134 public:
135 translate_isl_ast_to_gimple (sese_info_p r)
136 : region (r)
137 { }
138
139 /* Translates an ISL AST node NODE to GCC representation in the
140 context of a SESE. */
141 edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
142 edge next_e, ivs_params &ip);
143
144 /* Translates an isl_ast_node_for to Gimple. */
145 edge translate_isl_ast_node_for (loop_p context_loop,
146 __isl_keep isl_ast_node *node,
147 edge next_e, ivs_params &ip);
148
149 /* Create the loop for a isl_ast_node_for.
150
151 - NEXT_E is the edge where new generated code should be attached. */
152 edge translate_isl_ast_for_loop (loop_p context_loop,
153 __isl_keep isl_ast_node *node_for,
154 edge next_e,
155 tree type, tree lb, tree ub,
156 ivs_params &ip);
157
158 /* Translates an isl_ast_node_if to Gimple. */
159 edge translate_isl_ast_node_if (loop_p context_loop,
160 __isl_keep isl_ast_node *node,
161 edge next_e, ivs_params &ip);
162
163 /* Translates an isl_ast_node_user to Gimple.
164
165 FIXME: We should remove iv_map.create (loop->num + 1), if it is
166 possible. */
167 edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
168 edge next_e, ivs_params &ip);
169
170 /* Translates an isl_ast_node_block to Gimple. */
171 edge translate_isl_ast_node_block (loop_p context_loop,
172 __isl_keep isl_ast_node *node,
173 edge next_e, ivs_params &ip);
174
175 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
176 type TYPE. */
177 tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
178 ivs_params &ip);
179
180 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
181 type TYPE. */
182 tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
183 ivs_params &ip);
184
185 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
186 type TYPE. */
187 tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
188 ivs_params &ip);
189
190 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
191 to a GCC expression tree of type TYPE. */
192 tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
193 ivs_params &ip);
194
195 /* Converts an ISL AST expression E back to a GCC expression tree of
196 type TYPE. */
197 tree gcc_expression_from_isl_expression (tree type,
198 __isl_take isl_ast_expr *,
199 ivs_params &ip);
200
201 /* Return the tree variable that corresponds to the given isl ast identifier
202 expression (an isl_ast_expr of type isl_ast_expr_id).
203
204 FIXME: We should replace blind conversation of id's type with derivation
205 of the optimal type when we get the corresponding isl support. Blindly
206 converting type sizes may be problematic when we switch to smaller
207 types. */
208 tree gcc_expression_from_isl_ast_expr_id (tree type,
209 __isl_keep isl_ast_expr *expr_id,
210 ivs_params &ip);
211
212 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
213 type TYPE. */
214 tree gcc_expression_from_isl_expr_int (tree type,
215 __isl_take isl_ast_expr *expr);
216
217 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
218 type TYPE. */
219 tree gcc_expression_from_isl_expr_op (tree type,
220 __isl_take isl_ast_expr *expr,
221 ivs_params &ip);
222
223 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
224 induction variable for the new LOOP. New LOOP is attached to CFG
225 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
226 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
227 ISL's scattering name to the induction variable created for the
228 loop of STMT. The new induction variable is inserted in the NEWIVS
229 vector and is of type TYPE. */
230 struct loop *graphite_create_new_loop (edge entry_edge,
231 __isl_keep isl_ast_node *node_for,
232 loop_p outer, tree type,
233 tree lb, tree ub, ivs_params &ip);
234
235 /* All loops generated by create_empty_loop_on_edge have the form of
236 a post-test loop:
237
238 do
239
240 {
241 body of the loop;
242 } while (lower bound < upper bound);
243
244 We create a new if region protecting the loop to be executed, if
245 the execution count is zero (lower bound > upper bound). */
246 edge graphite_create_new_loop_guard (edge entry_edge,
247 __isl_keep isl_ast_node *node_for,
248 tree *type,
249 tree *lb, tree *ub, ivs_params &ip);
250
251 /* Creates a new if region corresponding to ISL's cond. */
252 edge graphite_create_new_guard (edge entry_edge,
253 __isl_take isl_ast_expr *if_cond,
254 ivs_params &ip);
255
256 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
257 variables of the loops around GBB in SESE.
258
259 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
260 chrec, we could consider using a map<int, tree> that maps loop ids to the
261 corresponding tree expressions. */
262 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
263 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
264 sese_l &region);
265 private:
266 sese_info_p region;
267 };
268
269 /* Return the tree variable that corresponds to the given isl ast identifier
270 expression (an isl_ast_expr of type isl_ast_expr_id).
271
272 FIXME: We should replace blind conversation of id's type with derivation
273 of the optimal type when we get the corresponding isl support. Blindly
274 converting type sizes may be problematic when we switch to smaller
275 types. */
276
277 tree
278 translate_isl_ast_to_gimple::
279 gcc_expression_from_isl_ast_expr_id (tree type,
280 __isl_keep isl_ast_expr *expr_id,
281 ivs_params &ip)
282 {
283 gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
284 isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
285 std::map<isl_id *, tree>::iterator res;
286 res = ip.find (tmp_isl_id);
287 isl_id_free (tmp_isl_id);
288 gcc_assert (res != ip.end () &&
289 "Could not map isl_id to tree expression");
290 isl_ast_expr_free (expr_id);
291 tree t = res->second;
292 tree *val = region->parameter_rename_map->get(t);
293
294 if (!val)
295 val = &t;
296 return fold_convert (type, *val);
297 }
298
299 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
300 type TYPE. */
301
302 tree
303 translate_isl_ast_to_gimple::
304 gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
305 {
306 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
307 isl_val *val = isl_ast_expr_get_val (expr);
308 mpz_t val_mpz_t;
309 mpz_init (val_mpz_t);
310 tree res;
311 if (isl_val_get_num_gmp (val, val_mpz_t) == -1)
312 res = NULL_TREE;
313 else
314 res = gmp_cst_to_tree (type, val_mpz_t);
315 isl_val_free (val);
316 isl_ast_expr_free (expr);
317 mpz_clear (val_mpz_t);
318 return res;
319 }
320
321 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
322 type TYPE. */
323
324 tree
325 translate_isl_ast_to_gimple::
326 binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
327 {
328 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
329 tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
330 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
331 tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
332 enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
333 isl_ast_expr_free (expr);
334 switch (expr_type)
335 {
336 case isl_ast_op_add:
337 return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
338
339 case isl_ast_op_sub:
340 return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
341
342 case isl_ast_op_mul:
343 return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
344
345 case isl_ast_op_div:
346 return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
347
348 case isl_ast_op_pdiv_q:
349 return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
350
351 case isl_ast_op_pdiv_r:
352 return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
353
354 case isl_ast_op_fdiv_q:
355 return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
356
357 case isl_ast_op_and:
358 return fold_build2 (TRUTH_ANDIF_EXPR, type,
359 tree_lhs_expr, tree_rhs_expr);
360
361 case isl_ast_op_or:
362 return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);
363
364 case isl_ast_op_eq:
365 return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);
366
367 case isl_ast_op_le:
368 return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
369
370 case isl_ast_op_lt:
371 return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
372
373 case isl_ast_op_ge:
374 return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
375
376 case isl_ast_op_gt:
377 return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
378
379 default:
380 gcc_unreachable ();
381 }
382 }
383
384 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
385 type TYPE. */
386
387 tree
388 translate_isl_ast_to_gimple::
389 ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
390 {
391 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
392 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
393 tree tree_first_expr
394 = gcc_expression_from_isl_expression (type, arg_expr, ip);
395 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
396 tree tree_second_expr
397 = gcc_expression_from_isl_expression (type, arg_expr, ip);
398 arg_expr = isl_ast_expr_get_op_arg (expr, 2);
399 tree tree_third_expr
400 = gcc_expression_from_isl_expression (type, arg_expr, ip);
401 isl_ast_expr_free (expr);
402 return fold_build3 (COND_EXPR, type, tree_first_expr,
403 tree_second_expr, tree_third_expr);
404 }
405
406 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
407 type TYPE. */
408
409 tree
410 translate_isl_ast_to_gimple::
411 unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
412 {
413 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
414 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
415 tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
416 isl_ast_expr_free (expr);
417 return fold_build1 (NEGATE_EXPR, type, tree_expr);
418 }
419
420 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
421 to a GCC expression tree of type TYPE. */
422
423 tree
424 translate_isl_ast_to_gimple::
425 nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
426 {
427 enum tree_code op_code;
428 switch (isl_ast_expr_get_op_type (expr))
429 {
430 case isl_ast_op_max:
431 op_code = MAX_EXPR;
432 break;
433
434 case isl_ast_op_min:
435 op_code = MIN_EXPR;
436 break;
437
438 default:
439 gcc_unreachable ();
440 }
441 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
442 tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);
443 int i;
444 for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
445 {
446 arg_expr = isl_ast_expr_get_op_arg (expr, i);
447 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
448 res = fold_build2 (op_code, type, res, t);
449 }
450 isl_ast_expr_free (expr);
451 return res;
452 }
453
454 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
455 type TYPE. */
456
457 tree
458 translate_isl_ast_to_gimple::
459 gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
460 ivs_params &ip)
461 {
462 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
463 switch (isl_ast_expr_get_op_type (expr))
464 {
465 /* These isl ast expressions are not supported yet. */
466 case isl_ast_op_error:
467 case isl_ast_op_call:
468 case isl_ast_op_and_then:
469 case isl_ast_op_or_else:
470 case isl_ast_op_select:
471 gcc_unreachable ();
472
473 case isl_ast_op_max:
474 case isl_ast_op_min:
475 return nary_op_to_tree (type, expr, ip);
476
477 case isl_ast_op_add:
478 case isl_ast_op_sub:
479 case isl_ast_op_mul:
480 case isl_ast_op_div:
481 case isl_ast_op_pdiv_q:
482 case isl_ast_op_pdiv_r:
483 case isl_ast_op_fdiv_q:
484 case isl_ast_op_and:
485 case isl_ast_op_or:
486 case isl_ast_op_eq:
487 case isl_ast_op_le:
488 case isl_ast_op_lt:
489 case isl_ast_op_ge:
490 case isl_ast_op_gt:
491 return binary_op_to_tree (type, expr, ip);
492
493 case isl_ast_op_minus:
494 return unary_op_to_tree (type, expr, ip);
495
496 case isl_ast_op_cond:
497 return ternary_op_to_tree (type, expr, ip);
498
499 default:
500 gcc_unreachable ();
501 }
502
503 return NULL_TREE;
504 }
505
506 /* Converts an ISL AST expression E back to a GCC expression tree of
507 type TYPE. */
508
509 tree
510 translate_isl_ast_to_gimple::
511 gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
512 ivs_params &ip)
513 {
514 switch (isl_ast_expr_get_type (expr))
515 {
516 case isl_ast_expr_id:
517 return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
518
519 case isl_ast_expr_int:
520 return gcc_expression_from_isl_expr_int (type, expr);
521
522 case isl_ast_expr_op:
523 return gcc_expression_from_isl_expr_op (type, expr, ip);
524
525 default:
526 gcc_unreachable ();
527 }
528
529 return NULL_TREE;
530 }
531
532 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
533 induction variable for the new LOOP. New LOOP is attached to CFG
534 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
535 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
536 ISL's scattering name to the induction variable created for the
537 loop of STMT. The new induction variable is inserted in the NEWIVS
538 vector and is of type TYPE. */
539
540 struct loop *
541 translate_isl_ast_to_gimple::
542 graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
543 loop_p outer, tree type, tree lb, tree ub,
544 ivs_params &ip)
545 {
546 isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
547 tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
548 tree ivvar = create_tmp_var (type, "graphite_IV");
549 tree iv, iv_after_increment;
550 loop_p loop = create_empty_loop_on_edge
551 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
552 outer ? outer : entry_edge->src->loop_father);
553
554 isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
555 isl_id *id = isl_ast_expr_get_id (for_iterator);
556 std::map<isl_id *, tree>::iterator res;
557 res = ip.find (id);
558 if (ip.count (id))
559 isl_id_free (res->first);
560 ip[id] = iv;
561 isl_ast_expr_free (for_iterator);
562 return loop;
563 }
564
565 /* Create the loop for a isl_ast_node_for.
566
567 - NEXT_E is the edge where new generated code should be attached. */
568
569 edge
570 translate_isl_ast_to_gimple::
571 translate_isl_ast_for_loop (loop_p context_loop,
572 __isl_keep isl_ast_node *node_for, edge next_e,
573 tree type, tree lb, tree ub,
574 ivs_params &ip)
575 {
576 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
577 struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
578 type, lb, ub, ip);
579 edge last_e = single_exit (loop);
580 edge to_body = single_succ_edge (loop->header);
581 basic_block after = to_body->dest;
582
583 /* Create a basic block for loop close phi nodes. */
584 last_e = single_succ_edge (split_edge (last_e));
585
586 /* Translate the body of the loop. */
587 isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
588 next_e = translate_isl_ast (loop, for_body, to_body, ip);
589 isl_ast_node_free (for_body);
590 redirect_edge_succ_nodup (next_e, after);
591 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
592
593 if (flag_loop_parallelize_all)
594 {
595 isl_id *id = isl_ast_node_get_annotation (node_for);
596 gcc_assert (id);
597 ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
598 loop->can_be_parallel = for_info->is_parallelizable;
599 free (for_info);
600 isl_id_free (id);
601 }
602
603 return last_e;
604 }
605
606 /* We use this function to get the upper bound because of the form,
607 which is used by isl to represent loops:
608
609 for (iterator = init; cond; iterator += inc)
610
611 {
612
613 ...
614
615 }
616
617 The loop condition is an arbitrary expression, which contains the
618 current loop iterator.
619
620 (e.g. iterator + 3 < B && C > iterator + A)
621
622 We have to know the upper bound of the iterator to generate a loop
623 in Gimple form. It can be obtained from the special representation
624 of the loop condition, which is generated by isl,
625 if the ast_build_atomic_upper_bound option is set. In this case,
626 isl generates a loop condition that consists of the current loop
627 iterator, + an operator (< or <=) and an expression not involving
628 the iterator, which is processed and returned by this function.
629
630 (e.g iterator <= upper-bound-expression-without-iterator) */
631
632 static __isl_give isl_ast_expr *
633 get_upper_bound (__isl_keep isl_ast_node *node_for)
634 {
635 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
636 isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
637 gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
638 isl_ast_expr *res;
639 switch (isl_ast_expr_get_op_type (for_cond))
640 {
641 case isl_ast_op_le:
642 res = isl_ast_expr_get_op_arg (for_cond, 1);
643 break;
644
645 case isl_ast_op_lt:
646 {
647 // (iterator < ub) => (iterator <= ub - 1)
648 isl_val *one =
649 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
650 isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
651 res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
652 break;
653 }
654
655 default:
656 gcc_unreachable ();
657 }
658 isl_ast_expr_free (for_cond);
659 return res;
660 }
661
662 /* All loops generated by create_empty_loop_on_edge have the form of
663 a post-test loop:
664
665 do
666
667 {
668 body of the loop;
669 } while (lower bound < upper bound);
670
671 We create a new if region protecting the loop to be executed, if
672 the execution count is zero (lower bound > upper bound). */
673
674 edge
675 translate_isl_ast_to_gimple::
676 graphite_create_new_loop_guard (edge entry_edge,
677 __isl_keep isl_ast_node *node_for, tree *type,
678 tree *lb, tree *ub, ivs_params &ip)
679 {
680 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
681 tree cond_expr;
682 edge exit_edge;
683
684 *type =
685 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
686 isl_ast_expr *for_init = isl_ast_node_for_get_init (node_for);
687 *lb = gcc_expression_from_isl_expression (*type, for_init, ip);
688 isl_ast_expr *upper_bound = get_upper_bound (node_for);
689 *ub = gcc_expression_from_isl_expression (*type, upper_bound, ip);
690
691 /* When ub is simply a constant or a parameter, use lb <= ub. */
692 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
693 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
694 else
695 {
696 tree one = (POINTER_TYPE_P (*type)
697 ? convert_to_ptrofftype (integer_one_node)
698 : fold_convert (*type, integer_one_node));
699 /* Adding +1 and using LT_EXPR helps with loop latches that have a
700 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this
701 becomes 2^k-1 due to integer overflow, and the condition lb <= ub
702 is true, even if we do not want this. However lb < ub + 1 is false,
703 as expected. */
704 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
705 : PLUS_EXPR, *type, *ub, one);
706
707 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
708 }
709
710 if (integer_onep (cond_expr))
711 exit_edge = entry_edge;
712 else
713 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
714
715 return exit_edge;
716 }
717
718 /* Translates an isl_ast_node_for to Gimple. */
719
720 edge
721 translate_isl_ast_to_gimple::
722 translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
723 edge next_e, ivs_params &ip)
724 {
725 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
726 tree type, lb, ub;
727 edge last_e = graphite_create_new_loop_guard (next_e, node, &type,
728 &lb, &ub, ip);
729
730 if (last_e == next_e)
731 /* There was no guard generated. */
732 return translate_isl_ast_for_loop (context_loop, node, last_e,
733 type, lb, ub, ip);
734
735 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
736 translate_isl_ast_for_loop (context_loop, node, true_e, type, lb, ub, ip);
737 return last_e;
738 }
739
740 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
741 variables of the loops around GBB in SESE.
742
743 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
744 chrec, we could consider using a map<int, tree> that maps loop ids to the
745 corresponding tree expressions. */
746
747 void
748 translate_isl_ast_to_gimple::
749 build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
750 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
751 sese_l &region)
752 {
753 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
754 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
755 int i;
756 isl_ast_expr *arg_expr;
757 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
758 {
759 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
760 tree type =
761 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
762 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
763 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
764 iv_map[old_loop->num] = t;
765 }
766 }
767
768 /* Translates an isl_ast_node_user to Gimple.
769
770 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
771
772 edge
773 translate_isl_ast_to_gimple::
774 translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
775 edge next_e, ivs_params &ip)
776 {
777 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
778 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
779 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
780 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
781 isl_id *name_id = isl_ast_expr_get_id (name_expr);
782 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
783 gcc_assert (pbb);
784 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
785 vec<tree> iv_map;
786 isl_ast_expr_free (name_expr);
787 isl_id_free (name_id);
788
789 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
790 "The entry block should not even appear within a scop");
791
792 int nb_loops = number_of_loops (cfun);
793 iv_map.create (nb_loops);
794 iv_map.safe_grow_cleared (nb_loops);
795
796 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
797 isl_ast_expr_free (user_expr);
798 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb),
799 pbb->scop->scop_info, next_e,
800 iv_map,
801 &graphite_regenerate_error);
802 iv_map.release ();
803 mark_virtual_operands_for_renaming (cfun);
804 update_ssa (TODO_update_ssa);
805 return next_e;
806 }
807
808 /* Translates an isl_ast_node_block to Gimple. */
809
810 edge
811 translate_isl_ast_to_gimple::
812 translate_isl_ast_node_block (loop_p context_loop,
813 __isl_keep isl_ast_node *node,
814 edge next_e, ivs_params &ip)
815 {
816 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
817 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
818 int i;
819 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
820 {
821 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
822 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
823 isl_ast_node_free (tmp_node);
824 }
825 isl_ast_node_list_free (node_list);
826 return next_e;
827 }
828
829 /* Creates a new if region corresponding to ISL's cond. */
830
831 edge
832 translate_isl_ast_to_gimple::
833 graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
834 ivs_params &ip)
835 {
836 tree type =
837 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
838 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
839 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
840 return exit_edge;
841 }
842
843 /* Translates an isl_ast_node_if to Gimple. */
844
845 edge
846 translate_isl_ast_to_gimple::
847 translate_isl_ast_node_if (loop_p context_loop,
848 __isl_keep isl_ast_node *node,
849 edge next_e, ivs_params &ip)
850 {
851 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
852 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
853 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
854
855 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
856 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
857 translate_isl_ast (context_loop, then_node, true_e, ip);
858 isl_ast_node_free (then_node);
859
860 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
861 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
862 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
863 translate_isl_ast (context_loop, else_node, false_e, ip);
864 isl_ast_node_free (else_node);
865 return last_e;
866 }
867
868 /* Translates an ISL AST node NODE to GCC representation in the
869 context of a SESE. */
870
871 edge
872 translate_isl_ast_to_gimple::translate_isl_ast (loop_p context_loop,
873 __isl_keep isl_ast_node *node,
874 edge next_e, ivs_params &ip)
875 {
876 switch (isl_ast_node_get_type (node))
877 {
878 case isl_ast_node_error:
879 gcc_unreachable ();
880
881 case isl_ast_node_for:
882 return translate_isl_ast_node_for (context_loop, node,
883 next_e, ip);
884
885 case isl_ast_node_if:
886 return translate_isl_ast_node_if (context_loop, node,
887 next_e, ip);
888
889 case isl_ast_node_user:
890 return translate_isl_ast_node_user (node, next_e, ip);
891
892 case isl_ast_node_block:
893 return translate_isl_ast_node_block (context_loop, node,
894 next_e, ip);
895
896 default:
897 gcc_unreachable ();
898 }
899 }
900
901 /* Prints NODE to FILE. */
902
903 void
904 print_isl_ast_node (FILE *file, __isl_keep isl_ast_node *node,
905 __isl_keep isl_ctx *ctx)
906 {
907 isl_printer *prn = isl_printer_to_file (ctx, file);
908 prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
909 prn = isl_printer_print_ast_node (prn, node);
910 prn = isl_printer_print_str (prn, "\n");
911 isl_printer_free (prn);
912 }
913
914 /* Add ISL's parameter identifiers and corresponding.trees to ivs_params */
915
916 static void
917 add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
918 {
919 sese_info_p region = scop->scop_info;
920 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
921 gcc_assert (nb_parameters == SESE_PARAMS (region).length ());
922 unsigned i;
923 for (i = 0; i < nb_parameters; i++)
924 {
925 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
926 isl_dim_param, i);
927 ip[tmp_id] = SESE_PARAMS (region)[i];
928 }
929 }
930
931
932 /* Generates a build, which specifies the constraints on the parameters. */
933
934 static __isl_give isl_ast_build *
935 generate_isl_context (scop_p scop)
936 {
937 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
938 return isl_ast_build_from_context (context_isl);
939 }
940
941 /* Get the maximal number of schedule dimensions in the scop SCOP. */
942
943 static
944 int get_max_schedule_dimensions (scop_p scop)
945 {
946 int i;
947 poly_bb_p pbb;
948 int schedule_dims = 0;
949
950 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
951 {
952 int pbb_schedule_dims = isl_map_dim (pbb->transformed, isl_dim_out);
953 if (pbb_schedule_dims > schedule_dims)
954 schedule_dims = pbb_schedule_dims;
955 }
956
957 return schedule_dims;
958 }
959
960 /* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
961
962 For schedules with different dimensionality, the isl AST generator can not
963 define an order and will just randomly choose an order. The solution to this
964 problem is to extend all schedules to the maximal number of schedule
965 dimensions (using '0's for the remaining values). */
966
967 static __isl_give isl_map *
968 extend_schedule (__isl_take isl_map *schedule, int nb_schedule_dims)
969 {
970 int tmp_dims = isl_map_dim (schedule, isl_dim_out);
971 schedule =
972 isl_map_add_dims (schedule, isl_dim_out, nb_schedule_dims - tmp_dims);
973 isl_val *zero =
974 isl_val_int_from_si (isl_map_get_ctx (schedule), 0);
975 int i;
976 for (i = tmp_dims; i < nb_schedule_dims; i++)
977 {
978 schedule =
979 isl_map_fix_val (schedule, isl_dim_out, i, isl_val_copy (zero));
980 }
981 isl_val_free (zero);
982 return schedule;
983 }
984
985 /* Generates a schedule, which specifies an order used to
986 visit elements in a domain. */
987
988 static __isl_give isl_union_map *
989 generate_isl_schedule (scop_p scop)
990 {
991 int nb_schedule_dims = get_max_schedule_dimensions (scop);
992 int i;
993 poly_bb_p pbb;
994 isl_union_map *schedule_isl =
995 isl_union_map_empty (isl_set_get_space (scop->param_context));
996
997 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
998 {
999 /* Dead code elimination: when the domain of a PBB is empty,
1000 don't generate code for the PBB. */
1001 if (isl_set_is_empty (pbb->domain))
1002 continue;
1003
1004 isl_map *bb_schedule = isl_map_copy (pbb->transformed);
1005 bb_schedule = isl_map_intersect_domain (bb_schedule,
1006 isl_set_copy (pbb->domain));
1007 bb_schedule = extend_schedule (bb_schedule, nb_schedule_dims);
1008 schedule_isl =
1009 isl_union_map_union (schedule_isl,
1010 isl_union_map_from_map (bb_schedule));
1011 }
1012 return schedule_isl;
1013 }
1014
1015 /* This method is executed before the construction of a for node. */
1016 static __isl_give isl_id *
1017 ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
1018 {
1019 isl_union_map *dependences = (isl_union_map *) user;
1020 ast_build_info *for_info = XNEW (struct ast_build_info);
1021 isl_union_map *schedule = isl_ast_build_get_schedule (build);
1022 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
1023 int dimension = isl_space_dim (schedule_space, isl_dim_out);
1024 for_info->is_parallelizable =
1025 !carries_deps (schedule, dependences, dimension);
1026 isl_union_map_free (schedule);
1027 isl_space_free (schedule_space);
1028 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
1029 return id;
1030 }
1031
1032 /* Set the separate option for all dimensions.
1033 This helps to reduce control overhead. */
1034
1035 static __isl_give isl_ast_build *
1036 set_options (__isl_take isl_ast_build *control,
1037 __isl_keep isl_union_map *schedule)
1038 {
1039 isl_ctx *ctx = isl_union_map_get_ctx (schedule);
1040 isl_space *range_space = isl_space_set_alloc (ctx, 0, 1);
1041 range_space =
1042 isl_space_set_tuple_name (range_space, isl_dim_set, "separate");
1043 isl_union_set *range =
1044 isl_union_set_from_set (isl_set_universe (range_space));
1045 isl_union_set *domain = isl_union_map_range (isl_union_map_copy (schedule));
1046 domain = isl_union_set_universe (domain);
1047 isl_union_map *options = isl_union_map_from_domain_and_range (domain, range);
1048 return isl_ast_build_set_options (control, options);
1049 }
1050
1051 static __isl_give isl_ast_node *
1052 scop_to_isl_ast (scop_p scop, ivs_params &ip)
1053 {
1054 /* Generate loop upper bounds that consist of the current loop iterator,
1055 an operator (< or <=) and an expression not involving the iterator.
1056 If this option is not set, then the current loop iterator may appear several
1057 times in the upper bound. See the isl manual for more details. */
1058 isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, true);
1059
1060 add_parameters_to_ivs_params (scop, ip);
1061 isl_union_map *schedule_isl = generate_isl_schedule (scop);
1062 isl_ast_build *context_isl = generate_isl_context (scop);
1063 context_isl = set_options (context_isl, schedule_isl);
1064 isl_union_map *dependences = NULL;
1065 if (flag_loop_parallelize_all)
1066 {
1067 dependences = scop_get_dependences (scop);
1068 context_isl =
1069 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
1070 dependences);
1071 }
1072 isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
1073 schedule_isl);
1074 if(dependences)
1075 isl_union_map_free (dependences);
1076 isl_ast_build_free (context_isl);
1077 return ast_isl;
1078 }
1079
1080 /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
1081 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
1082
1083 static void
1084 copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
1085 gimple_stmt_iterator *gsi)
1086 {
1087 if (!defined_in_sese_p (tr, region->region))
1088 return;
1089
1090 ssa_op_iter iter;
1091 use_operand_p use_p;
1092 FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
1093 {
1094 tree use_tr = USE_FROM_PTR (use_p);
1095
1096 /* Do not copy parameters that have been generated in the header of the
1097 scop. */
1098 if (region->parameter_rename_map->get(use_tr))
1099 continue;
1100
1101 gimple *def_of_use = SSA_NAME_DEF_STMT (use_tr);
1102 if (!def_of_use)
1103 continue;
1104
1105 copy_def (use_tr, def_of_use, region, to_region, gsi);
1106 }
1107
1108 gimple *copy = gimple_copy (def_stmt);
1109 gsi_insert_after (gsi, copy, GSI_NEW_STMT);
1110
1111 /* Create new names for all the definitions created by COPY and
1112 add replacement mappings for each new name. */
1113 def_operand_p def_p;
1114 ssa_op_iter op_iter;
1115 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
1116 {
1117 tree old_name = DEF_FROM_PTR (def_p);
1118 tree new_name = create_new_def_for (old_name, copy, def_p);
1119 region->parameter_rename_map->put(old_name, new_name);
1120 }
1121
1122 update_stmt (copy);
1123 }
1124
1125 static void
1126 copy_internal_parameters (sese_info_p region, sese_info_p to_region)
1127 {
1128 /* For all the parameters which definitino is in the if_region->false_region,
1129 insert code on true_region (if_region->true_region->entry). */
1130
1131 int i;
1132 tree tr;
1133 gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
1134
1135 FOR_EACH_VEC_ELT (region->params, i, tr)
1136 {
1137 // If def is not in region.
1138 gimple *def_stmt = SSA_NAME_DEF_STMT (tr);
1139 if (def_stmt)
1140 copy_def (tr, def_stmt, region, to_region, &gsi);
1141 }
1142 }
1143
1144 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1145 the given SCOP. Return true if code generation succeeded.
1146
1147 FIXME: This is not yet a full implementation of the code generator
1148 with ISL ASTs. Generation of GIMPLE code has to be completed. */
1149
1150 bool
1151 graphite_regenerate_ast_isl (scop_p scop)
1152 {
1153 loop_p context_loop;
1154 sese_info_p region = scop->scop_info;
1155 ifsese if_region = NULL;
1156 isl_ast_node *root_node;
1157 ivs_params ip;
1158
1159 timevar_push (TV_GRAPHITE_CODE_GEN);
1160 graphite_regenerate_error = false;
1161 root_node = scop_to_isl_ast (scop, ip);
1162
1163 if (dump_file && (dump_flags & TDF_DETAILS))
1164 {
1165 fprintf (dump_file, "\nISL AST generated by ISL: \n");
1166 print_isl_ast_node (dump_file, root_node, scop->isl_context);
1167 fprintf (dump_file, "\n");
1168 }
1169
1170 recompute_all_dominators ();
1171 graphite_verify ();
1172
1173 if_region = move_sese_in_condition (region);
1174 sese_insert_phis_for_liveouts (region,
1175 if_region->region->region.exit->src,
1176 if_region->false_region->region.exit,
1177 if_region->true_region->region.exit);
1178 recompute_all_dominators ();
1179 graphite_verify ();
1180
1181 context_loop = region->region.entry->src->loop_father;
1182
1183 /* Copy all the parameters which are defined in the region. */
1184 copy_internal_parameters(if_region->false_region, if_region->true_region);
1185
1186 translate_isl_ast_to_gimple t(region);
1187 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
1188 split_edge (e);
1189 t.translate_isl_ast (context_loop, root_node, e, ip);
1190
1191 mark_virtual_operands_for_renaming (cfun);
1192 update_ssa (TODO_update_ssa);
1193
1194 graphite_verify ();
1195 scev_reset ();
1196 recompute_all_dominators ();
1197 graphite_verify ();
1198
1199 if (graphite_regenerate_error)
1200 set_ifsese_condition (if_region, integer_zero_node);
1201
1202 free (if_region->true_region);
1203 free (if_region->region);
1204 free (if_region);
1205
1206 ivs_params_clear (ip);
1207 isl_ast_node_free (root_node);
1208 timevar_pop (TV_GRAPHITE_CODE_GEN);
1209
1210 if (dump_file && (dump_flags & TDF_DETAILS))
1211 {
1212 loop_p loop;
1213 int num_no_dependency = 0;
1214
1215 FOR_EACH_LOOP (loop, 0)
1216 if (loop->can_be_parallel)
1217 num_no_dependency++;
1218
1219 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1220 num_no_dependency);
1221 }
1222
1223 return !graphite_regenerate_error;
1224 }
1225 #endif /* HAVE_isl */