]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/graphite-isl-ast-to-gimple.c
gather bbs and conditions in a single walk through dominators
[thirdparty/gcc.git] / gcc / graphite-isl-ast-to-gimple.c
CommitLineData
f6cc3103 1/* Translation of ISL AST to Gimple.
5624e564 2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
f6cc3103
RG
3 Contributed by Roman Gareev <gareevroman@gmail.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"
22
eae1a5d4 23#ifdef HAVE_isl
4bc190dc
JW
24/* Workaround for GMP 5.1.3 bug, see PR56019. */
25#include <stddef.h>
26
32400032 27#include <isl/constraint.h>
f6cc3103 28#include <isl/set.h>
32400032 29#include <isl/union_set.h>
f6cc3103
RG
30#include <isl/map.h>
31#include <isl/union_map.h>
32#include <isl/ast_build.h>
797d8858
TB
33
34/* Since ISL-0.13, the extern is in val_gmp.h. */
35#if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
a78cfa7f
RG
36extern "C" {
37#endif
38#include <isl/val_gmp.h>
797d8858 39#if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
a78cfa7f
RG
40}
41#endif
f6cc3103
RG
42
43#include "system.h"
44#include "coretypes.h"
c7131fb2 45#include "backend.h"
9fdcd34e 46#include "cfghooks.h"
40e23961 47#include "tree.h"
c7131fb2 48#include "gimple.h"
49b8fe6c 49#include "params.h"
c7131fb2 50#include "fold-const.h"
f6cc3103
RG
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"
9c358739 56#include "graphite-poly.h"
a78cfa7f
RG
57#include "tree-ssa-loop-manip.h"
58#include "tree-scalar-evolution.h"
5493d313 59#include "gimple-ssa.h"
74032f47 60#include "tree-phinodes.h"
5493d313 61#include "tree-into-ssa.h"
74032f47 62#include "ssa-iterators.h"
a78cfa7f 63#include <map>
f6cc3103
RG
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
69static bool graphite_regenerate_error;
70
55d1bd59
RG
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. */
a78cfa7f 74
55d1bd59
RG
75static int max_mode_int_precision =
76 GET_MODE_PRECISION (mode_for_size (MAX_FIXED_MODE_SIZE, MODE_INT, 0));
77static int graphite_expression_type_precision = 128 <= max_mode_int_precision ?
78 128 : max_mode_int_precision;
a78cfa7f 79
574921c2
RG
80struct ast_build_info
81{
82 ast_build_info()
83 : is_parallelizable(false)
84 { };
85 bool is_parallelizable;
86};
87
a78cfa7f
RG
88/* Converts a GMP constant VAL to a tree and returns it. */
89
90static tree
91gmp_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
106static inline void
107graphite_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
118typedef std::map<isl_id *, tree> ivs_params;
119
120/* Free all memory allocated for ISL's identifiers. */
121
122void 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
050e1371
AK
132class translate_isl_ast_to_gimple
133{
134 public:
bafcb153 135 translate_isl_ast_to_gimple (sese_info_p r)
050e1371
AK
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. */
65ef70d6 262 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
050e1371 263 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
bafcb153 264 sese_l &region);
050e1371 265private:
bafcb153 266 sese_info_p region;
050e1371 267};
a78cfa7f
RG
268
269/* Return the tree variable that corresponds to the given isl ast identifier
6a7d8936
RG
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. */
a78cfa7f 276
050e1371
AK
277tree
278translate_isl_ast_to_gimple::
6a7d8936
RG
279gcc_expression_from_isl_ast_expr_id (tree type,
280 __isl_keep isl_ast_expr *expr_id,
a78cfa7f
RG
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 () &&
050e1371 289 "Could not map isl_id to tree expression");
a78cfa7f 290 isl_ast_expr_free (expr_id);
74032f47
AK
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);
a78cfa7f
RG
297}
298
299/* Converts an isl_ast_expr_int expression E to a GCC expression tree of
300 type TYPE. */
301
050e1371
AK
302tree
303translate_isl_ast_to_gimple::
a78cfa7f
RG
304gcc_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
050e1371
AK
324tree
325translate_isl_ast_to_gimple::
a78cfa7f
RG
326binary_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
c4bc3399
RG
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
a78cfa7f
RG
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
050e1371
AK
387tree
388translate_isl_ast_to_gimple::
a78cfa7f
RG
389ternary_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
050e1371
AK
409tree
410translate_isl_ast_to_gimple::
a78cfa7f
RG
411unary_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
050e1371
AK
423tree
424translate_isl_ast_to_gimple::
a78cfa7f
RG
425nary_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
a78cfa7f
RG
454/* Converts an isl_ast_expr_op expression E to a GCC expression tree of
455 type TYPE. */
456
050e1371
AK
457tree
458translate_isl_ast_to_gimple::
a78cfa7f
RG
459gcc_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:
a78cfa7f
RG
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:
c4bc3399
RG
481 case isl_ast_op_pdiv_q:
482 case isl_ast_op_pdiv_r:
a78cfa7f
RG
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
050e1371
AK
509tree
510translate_isl_ast_to_gimple::
a78cfa7f
RG
511gcc_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:
6a7d8936 517 return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
a78cfa7f
RG
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
050e1371
AK
540struct loop *
541translate_isl_ast_to_gimple::
a78cfa7f
RG
542graphite_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);
a6631027
RG
556 std::map<isl_id *, tree>::iterator res;
557 res = ip.find (id);
558 if (ip.count (id))
559 isl_id_free (res->first);
a78cfa7f
RG
560 ip[id] = iv;
561 isl_ast_expr_free (for_iterator);
562 return loop;
563}
564
a78cfa7f
RG
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
050e1371
AK
569edge
570translate_isl_ast_to_gimple::
a78cfa7f
RG
571translate_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
574921c2
RG
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 }
a78cfa7f
RG
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
632static __isl_give isl_ast_expr *
633get_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)
2a466686
RG
648 isl_val *one =
649 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
a78cfa7f
RG
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
050e1371
AK
674edge
675translate_isl_ast_to_gimple::
a78cfa7f
RG
676graphite_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
55d1bd59
RG
684 *type =
685 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
a78cfa7f
RG
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 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
711
712 return exit_edge;
713}
714
715/* Translates an isl_ast_node_for to Gimple. */
716
050e1371
AK
717edge
718translate_isl_ast_to_gimple::
a78cfa7f
RG
719translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
720 edge next_e, ivs_params &ip)
721{
722 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
723 tree type, lb, ub;
724 edge last_e = graphite_create_new_loop_guard (next_e, node, &type,
725 &lb, &ub, ip);
726 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
727
728 translate_isl_ast_for_loop (context_loop, node, true_e,
729 type, lb, ub, ip);
730 return last_e;
731}
732
5493d313
RG
733/* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
734 variables of the loops around GBB in SESE.
735
736 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
737 chrec, we could consider using a map<int, tree> that maps loop ids to the
738 corresponding tree expressions. */
739
050e1371
AK
740void
741translate_isl_ast_to_gimple::
65ef70d6 742build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
5493d313 743 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
bafcb153 744 sese_l &region)
5493d313
RG
745{
746 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
050e1371 747 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
5493d313
RG
748 int i;
749 isl_ast_expr *arg_expr;
750 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
751 {
752 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
753 tree type =
050e1371 754 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
5493d313
RG
755 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
756 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
757 iv_map[old_loop->num] = t;
758 }
5493d313
RG
759}
760
761/* Translates an isl_ast_node_user to Gimple.
762
763 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
764
050e1371
AK
765edge
766translate_isl_ast_to_gimple::
5493d313
RG
767translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
768 edge next_e, ivs_params &ip)
769{
770 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
771 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
772 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
773 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
774 isl_id *name_id = isl_ast_expr_get_id (name_expr);
775 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
776 gcc_assert (pbb);
65ef70d6 777 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
5493d313
RG
778 vec<tree> iv_map;
779 isl_ast_expr_free (name_expr);
780 isl_id_free (name_id);
781
782 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
783 "The entry block should not even appear within a scop");
784
b5bdf598
RG
785 int nb_loops = number_of_loops (cfun);
786 iv_map.create (nb_loops);
787 iv_map.safe_grow_cleared (nb_loops);
5493d313 788
bafcb153 789 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->region->region);
5493d313
RG
790 isl_ast_expr_free (user_expr);
791 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb),
bafcb153 792 pbb->scop->region, next_e,
5493d313
RG
793 iv_map,
794 &graphite_regenerate_error);
795 iv_map.release ();
796 mark_virtual_operands_for_renaming (cfun);
797 update_ssa (TODO_update_ssa);
798 return next_e;
799}
800
322a0b39
RG
801/* Translates an isl_ast_node_block to Gimple. */
802
050e1371
AK
803edge
804translate_isl_ast_to_gimple::
322a0b39
RG
805translate_isl_ast_node_block (loop_p context_loop,
806 __isl_keep isl_ast_node *node,
807 edge next_e, ivs_params &ip)
808{
809 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
810 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
811 int i;
812 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
813 {
814 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
815 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
816 isl_ast_node_free (tmp_node);
817 }
818 isl_ast_node_list_free (node_list);
819 return next_e;
820}
333cc518
RG
821
822/* Creates a new if region corresponding to ISL's cond. */
823
050e1371
AK
824edge
825translate_isl_ast_to_gimple::
333cc518
RG
826graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
827 ivs_params &ip)
828{
829 tree type =
830 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
831 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
832 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
833 return exit_edge;
834}
835
836/* Translates an isl_ast_node_if to Gimple. */
837
050e1371
AK
838edge
839translate_isl_ast_to_gimple::
333cc518
RG
840translate_isl_ast_node_if (loop_p context_loop,
841 __isl_keep isl_ast_node *node,
842 edge next_e, ivs_params &ip)
843{
844 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
845 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
846 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
847
848 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
849 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
850 translate_isl_ast (context_loop, then_node, true_e, ip);
851 isl_ast_node_free (then_node);
852
853 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
854 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
855 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
856 translate_isl_ast (context_loop, else_node, false_e, ip);
857 isl_ast_node_free (else_node);
858 return last_e;
859}
322a0b39 860
a78cfa7f
RG
861/* Translates an ISL AST node NODE to GCC representation in the
862 context of a SESE. */
863
050e1371
AK
864edge
865translate_isl_ast_to_gimple::translate_isl_ast (loop_p context_loop,
866 __isl_keep isl_ast_node *node,
867 edge next_e, ivs_params &ip)
a78cfa7f
RG
868{
869 switch (isl_ast_node_get_type (node))
870 {
871 case isl_ast_node_error:
872 gcc_unreachable ();
873
874 case isl_ast_node_for:
875 return translate_isl_ast_node_for (context_loop, node,
876 next_e, ip);
877
878 case isl_ast_node_if:
333cc518
RG
879 return translate_isl_ast_node_if (context_loop, node,
880 next_e, ip);
a78cfa7f
RG
881
882 case isl_ast_node_user:
5493d313 883 return translate_isl_ast_node_user (node, next_e, ip);
a78cfa7f
RG
884
885 case isl_ast_node_block:
322a0b39
RG
886 return translate_isl_ast_node_block (context_loop, node,
887 next_e, ip);
a78cfa7f
RG
888
889 default:
890 gcc_unreachable ();
891 }
892}
893
f6cc3103
RG
894/* Prints NODE to FILE. */
895
896void
897print_isl_ast_node (FILE *file, __isl_keep isl_ast_node *node,
898 __isl_keep isl_ctx *ctx)
899{
900 isl_printer *prn = isl_printer_to_file (ctx, file);
901 prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
902 prn = isl_printer_print_ast_node (prn, node);
903 prn = isl_printer_print_str (prn, "\n");
904 isl_printer_free (prn);
905}
906
a78cfa7f
RG
907/* Add ISL's parameter identifiers and corresponding.trees to ivs_params */
908
909static void
910add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
911{
bafcb153 912 sese_info_p region = scop->region;
8e4dc590 913 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
a78cfa7f
RG
914 gcc_assert (nb_parameters == SESE_PARAMS (region).length ());
915 unsigned i;
916 for (i = 0; i < nb_parameters; i++)
917 {
8e4dc590
AK
918 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
919 isl_dim_param, i);
a78cfa7f
RG
920 ip[tmp_id] = SESE_PARAMS (region)[i];
921 }
922}
923
924
f6cc3103
RG
925/* Generates a build, which specifies the constraints on the parameters. */
926
e4a452b2 927static __isl_give isl_ast_build *
f6cc3103
RG
928generate_isl_context (scop_p scop)
929{
8e4dc590 930 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
f6cc3103
RG
931 return isl_ast_build_from_context (context_isl);
932}
933
fb3764d1
RG
934/* Get the maximal number of schedule dimensions in the scop SCOP. */
935
936static
937int get_max_schedule_dimensions (scop_p scop)
938{
939 int i;
940 poly_bb_p pbb;
941 int schedule_dims = 0;
942
b0b5710c 943 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
fb3764d1
RG
944 {
945 int pbb_schedule_dims = isl_map_dim (pbb->transformed, isl_dim_out);
946 if (pbb_schedule_dims > schedule_dims)
947 schedule_dims = pbb_schedule_dims;
948 }
949
950 return schedule_dims;
951}
952
953/* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
954
955 For schedules with different dimensionality, the isl AST generator can not
956 define an order and will just randomly choose an order. The solution to this
957 problem is to extend all schedules to the maximal number of schedule
958 dimensions (using '0's for the remaining values). */
959
960static __isl_give isl_map *
961extend_schedule (__isl_take isl_map *schedule, int nb_schedule_dims)
962{
963 int tmp_dims = isl_map_dim (schedule, isl_dim_out);
964 schedule =
965 isl_map_add_dims (schedule, isl_dim_out, nb_schedule_dims - tmp_dims);
966 isl_val *zero =
967 isl_val_int_from_si (isl_map_get_ctx (schedule), 0);
968 int i;
969 for (i = tmp_dims; i < nb_schedule_dims; i++)
970 {
971 schedule =
972 isl_map_fix_val (schedule, isl_dim_out, i, isl_val_copy (zero));
973 }
974 isl_val_free (zero);
975 return schedule;
976}
977
f6cc3103
RG
978/* Generates a schedule, which specifies an order used to
979 visit elements in a domain. */
980
e4a452b2 981static __isl_give isl_union_map *
f6cc3103
RG
982generate_isl_schedule (scop_p scop)
983{
fb3764d1 984 int nb_schedule_dims = get_max_schedule_dimensions (scop);
f6cc3103
RG
985 int i;
986 poly_bb_p pbb;
987 isl_union_map *schedule_isl =
8e4dc590 988 isl_union_map_empty (isl_set_get_space (scop->param_context));
f6cc3103 989
b0b5710c 990 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
f6cc3103
RG
991 {
992 /* Dead code elimination: when the domain of a PBB is empty,
993 don't generate code for the PBB. */
994 if (isl_set_is_empty (pbb->domain))
995 continue;
996
997 isl_map *bb_schedule = isl_map_copy (pbb->transformed);
998 bb_schedule = isl_map_intersect_domain (bb_schedule,
999 isl_set_copy (pbb->domain));
fb3764d1 1000 bb_schedule = extend_schedule (bb_schedule, nb_schedule_dims);
f6cc3103
RG
1001 schedule_isl =
1002 isl_union_map_union (schedule_isl,
1003 isl_union_map_from_map (bb_schedule));
1004 }
1005 return schedule_isl;
1006}
1007
574921c2
RG
1008/* This method is executed before the construction of a for node. */
1009static __isl_give isl_id *
1010ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
1011{
1012 isl_union_map *dependences = (isl_union_map *) user;
1013 ast_build_info *for_info = XNEW (struct ast_build_info);
1014 isl_union_map *schedule = isl_ast_build_get_schedule (build);
1015 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
1016 int dimension = isl_space_dim (schedule_space, isl_dim_out);
1017 for_info->is_parallelizable =
1018 !carries_deps (schedule, dependences, dimension);
1019 isl_union_map_free (schedule);
1020 isl_space_free (schedule_space);
1021 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
1022 return id;
1023}
1024
6a12a004 1025/* Set the separate option for all dimensions.
a5e5ea0c 1026 This helps to reduce control overhead. */
6a12a004
RG
1027
1028static __isl_give isl_ast_build *
1029set_options (__isl_take isl_ast_build *control,
a5e5ea0c 1030 __isl_keep isl_union_map *schedule)
6a12a004
RG
1031{
1032 isl_ctx *ctx = isl_union_map_get_ctx (schedule);
1033 isl_space *range_space = isl_space_set_alloc (ctx, 0, 1);
1034 range_space =
1035 isl_space_set_tuple_name (range_space, isl_dim_set, "separate");
1036 isl_union_set *range =
1037 isl_union_set_from_set (isl_set_universe (range_space));
1038 isl_union_set *domain = isl_union_map_range (isl_union_map_copy (schedule));
1039 domain = isl_union_set_universe (domain);
1040 isl_union_map *options = isl_union_map_from_domain_and_range (domain, range);
1041 return isl_ast_build_set_options (control, options);
1042}
1043
e4a452b2 1044static __isl_give isl_ast_node *
a78cfa7f 1045scop_to_isl_ast (scop_p scop, ivs_params &ip)
f6cc3103 1046{
a78cfa7f
RG
1047 /* Generate loop upper bounds that consist of the current loop iterator,
1048 an operator (< or <=) and an expression not involving the iterator.
1049 If this option is not set, then the current loop iterator may appear several
1050 times in the upper bound. See the isl manual for more details. */
8e4dc590 1051 isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, true);
a78cfa7f
RG
1052
1053 add_parameters_to_ivs_params (scop, ip);
f6cc3103
RG
1054 isl_union_map *schedule_isl = generate_isl_schedule (scop);
1055 isl_ast_build *context_isl = generate_isl_context (scop);
a5e5ea0c 1056 context_isl = set_options (context_isl, schedule_isl);
574921c2
RG
1057 isl_union_map *dependences = NULL;
1058 if (flag_loop_parallelize_all)
1059 {
1060 dependences = scop_get_dependences (scop);
1061 context_isl =
1062 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
1063 dependences);
1064 }
f6cc3103
RG
1065 isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
1066 schedule_isl);
574921c2
RG
1067 if(dependences)
1068 isl_union_map_free (dependences);
f6cc3103
RG
1069 isl_ast_build_free (context_isl);
1070 return ast_isl;
1071}
1072
74032f47
AK
1073/* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
1074 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
1075
1076static void
bafcb153
AK
1077copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
1078 gimple_stmt_iterator *gsi)
74032f47 1079{
bafcb153 1080 if (!defined_in_sese_p (tr, region->region))
74032f47 1081 return;
bafcb153 1082
74032f47
AK
1083 ssa_op_iter iter;
1084 use_operand_p use_p;
74032f47
AK
1085 FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
1086 {
1087 tree use_tr = USE_FROM_PTR (use_p);
1088
1089 /* Do not copy parameters that have been generated in the header of the
1090 scop. */
1091 if (region->parameter_rename_map->get(use_tr))
1092 continue;
1093
355fe088 1094 gimple *def_of_use = SSA_NAME_DEF_STMT (use_tr);
74032f47
AK
1095 if (!def_of_use)
1096 continue;
1097
1098 copy_def (use_tr, def_of_use, region, to_region, gsi);
1099 }
1100
355fe088 1101 gimple *copy = gimple_copy (def_stmt);
74032f47
AK
1102 gsi_insert_after (gsi, copy, GSI_NEW_STMT);
1103
1104 /* Create new names for all the definitions created by COPY and
1105 add replacement mappings for each new name. */
1106 def_operand_p def_p;
1107 ssa_op_iter op_iter;
1108 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
1109 {
1110 tree old_name = DEF_FROM_PTR (def_p);
1111 tree new_name = create_new_def_for (old_name, copy, def_p);
1112 region->parameter_rename_map->put(old_name, new_name);
1113 }
1114
1115 update_stmt (copy);
1116}
1117
1118static void
bafcb153 1119copy_internal_parameters (sese_info_p region, sese_info_p to_region)
74032f47
AK
1120{
1121 /* For all the parameters which definitino is in the if_region->false_region,
1122 insert code on true_region (if_region->true_region->entry). */
1123
1124 int i;
1125 tree tr;
bafcb153 1126 gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
74032f47
AK
1127
1128 FOR_EACH_VEC_ELT (region->params, i, tr)
1129 {
1130 // If def is not in region.
355fe088 1131 gimple *def_stmt = SSA_NAME_DEF_STMT (tr);
74032f47
AK
1132 if (def_stmt)
1133 copy_def (tr, def_stmt, region, to_region, &gsi);
1134 }
1135}
1136
f6cc3103
RG
1137/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1138 the given SCOP. Return true if code generation succeeded.
1139
1140 FIXME: This is not yet a full implementation of the code generator
a78cfa7f 1141 with ISL ASTs. Generation of GIMPLE code has to be completed. */
f6cc3103
RG
1142
1143bool
1144graphite_regenerate_ast_isl (scop_p scop)
1145{
a78cfa7f 1146 loop_p context_loop;
bafcb153 1147 sese_info_p region = scop->region;
a78cfa7f
RG
1148 ifsese if_region = NULL;
1149 isl_ast_node *root_node;
1150 ivs_params ip;
1151
f6cc3103
RG
1152 timevar_push (TV_GRAPHITE_CODE_GEN);
1153 graphite_regenerate_error = false;
a78cfa7f
RG
1154 root_node = scop_to_isl_ast (scop, ip);
1155
f6cc3103
RG
1156 if (dump_file && (dump_flags & TDF_DETAILS))
1157 {
1158 fprintf (dump_file, "\nISL AST generated by ISL: \n");
8e4dc590 1159 print_isl_ast_node (dump_file, root_node, scop->isl_context);
a78cfa7f 1160 fprintf (dump_file, "\n");
f6cc3103 1161 }
a78cfa7f
RG
1162
1163 recompute_all_dominators ();
1164 graphite_verify ();
1165
1166 if_region = move_sese_in_condition (region);
1167 sese_insert_phis_for_liveouts (region,
bafcb153
AK
1168 if_region->region->region.exit->src,
1169 if_region->false_region->region.exit,
1170 if_region->true_region->region.exit);
a78cfa7f
RG
1171 recompute_all_dominators ();
1172 graphite_verify ();
1173
bafcb153 1174 context_loop = region->region.entry->src->loop_father;
a78cfa7f 1175
74032f47
AK
1176 /* Copy all the parameters which are defined in the region. */
1177 copy_internal_parameters(if_region->false_region, if_region->true_region);
050e1371 1178
74032f47 1179 translate_isl_ast_to_gimple t(region);
bafcb153 1180 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
74032f47
AK
1181 split_edge (e);
1182 t.translate_isl_ast (context_loop, root_node, e, ip);
d819fedb
RB
1183
1184 mark_virtual_operands_for_renaming (cfun);
1185 update_ssa (TODO_update_ssa);
1186
a78cfa7f
RG
1187 graphite_verify ();
1188 scev_reset ();
1189 recompute_all_dominators ();
1190 graphite_verify ();
1191
1192 if (graphite_regenerate_error)
1193 set_ifsese_condition (if_region, integer_zero_node);
1194
1195 free (if_region->true_region);
1196 free (if_region->region);
1197 free (if_region);
1198
1199 ivs_params_clear (ip);
f6cc3103
RG
1200 isl_ast_node_free (root_node);
1201 timevar_pop (TV_GRAPHITE_CODE_GEN);
574921c2
RG
1202
1203 if (dump_file && (dump_flags & TDF_DETAILS))
1204 {
1205 loop_p loop;
1206 int num_no_dependency = 0;
1207
1208 FOR_EACH_LOOP (loop, 0)
1209 if (loop->can_be_parallel)
1210 num_no_dependency++;
1211
1212 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1213 num_no_dependency);
1214 }
1215
f6cc3103
RG
1216 return !graphite_regenerate_error;
1217}
9c358739 1218#endif /* HAVE_isl */