]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/graphite-isl-ast-to-gimple.c
freebsd.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Bring in the commit from r125920 for FreeBSD.
[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 64#include "graphite-isl-ast-to-gimple.h"
1b38d3ec 65#include "tree-cfg.h"
65b016eb 66#include "gimple-pretty-print.h"
f6cc3103 67
55d1bd59
RG
68/* We always try to use signed 128 bit types, but fall back to smaller types
69 in case a platform does not provide types of these sizes. In the future we
70 should use isl to derive the optimal type for each subexpression. */
a78cfa7f 71
55d1bd59
RG
72static int max_mode_int_precision =
73 GET_MODE_PRECISION (mode_for_size (MAX_FIXED_MODE_SIZE, MODE_INT, 0));
74static int graphite_expression_type_precision = 128 <= max_mode_int_precision ?
75 128 : max_mode_int_precision;
a78cfa7f 76
574921c2
RG
77struct ast_build_info
78{
79 ast_build_info()
80 : is_parallelizable(false)
81 { };
82 bool is_parallelizable;
83};
84
a78cfa7f
RG
85/* Converts a GMP constant VAL to a tree and returns it. */
86
87static tree
88gmp_cst_to_tree (tree type, mpz_t val)
89{
90 tree t = type ? type : integer_type_node;
91 mpz_t tmp;
92
93 mpz_init (tmp);
94 mpz_set (tmp, val);
95 wide_int wi = wi::from_mpz (t, tmp, true);
96 mpz_clear (tmp);
97
98 return wide_int_to_tree (t, wi);
99}
100
101/* Verifies properties that GRAPHITE should maintain during translation. */
102
103static inline void
104graphite_verify (void)
105{
b2b29377
MM
106 checking_verify_loop_structure ();
107 checking_verify_loop_closed_ssa (true);
a78cfa7f
RG
108}
109
110/* IVS_PARAMS maps ISL's scattering and parameter identifiers
111 to corresponding trees. */
112
113typedef std::map<isl_id *, tree> ivs_params;
114
115/* Free all memory allocated for ISL's identifiers. */
116
117void ivs_params_clear (ivs_params &ip)
118{
119 std::map<isl_id *, tree>::iterator it;
120 for (it = ip.begin ();
121 it != ip.end (); it++)
122 {
123 isl_id_free (it->first);
124 }
125}
126
050e1371
AK
127class translate_isl_ast_to_gimple
128{
129 public:
bafcb153 130 translate_isl_ast_to_gimple (sese_info_p r)
65b016eb 131 : region (r), codegen_error (false)
050e1371
AK
132 { }
133
134 /* Translates an ISL AST node NODE to GCC representation in the
135 context of a SESE. */
136 edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
137 edge next_e, ivs_params &ip);
138
139 /* Translates an isl_ast_node_for to Gimple. */
140 edge translate_isl_ast_node_for (loop_p context_loop,
141 __isl_keep isl_ast_node *node,
142 edge next_e, ivs_params &ip);
143
144 /* Create the loop for a isl_ast_node_for.
145
146 - NEXT_E is the edge where new generated code should be attached. */
147 edge translate_isl_ast_for_loop (loop_p context_loop,
148 __isl_keep isl_ast_node *node_for,
149 edge next_e,
150 tree type, tree lb, tree ub,
151 ivs_params &ip);
152
153 /* Translates an isl_ast_node_if to Gimple. */
154 edge translate_isl_ast_node_if (loop_p context_loop,
155 __isl_keep isl_ast_node *node,
156 edge next_e, ivs_params &ip);
157
158 /* Translates an isl_ast_node_user to Gimple.
159
160 FIXME: We should remove iv_map.create (loop->num + 1), if it is
161 possible. */
162 edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
163 edge next_e, ivs_params &ip);
164
165 /* Translates an isl_ast_node_block to Gimple. */
166 edge translate_isl_ast_node_block (loop_p context_loop,
167 __isl_keep isl_ast_node *node,
168 edge next_e, ivs_params &ip);
169
170 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
171 type TYPE. */
172 tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
173 ivs_params &ip);
174
175 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
176 type TYPE. */
177 tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
178 ivs_params &ip);
179
180 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
181 type TYPE. */
182 tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
183 ivs_params &ip);
184
185 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
186 to a GCC expression tree of type TYPE. */
187 tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
188 ivs_params &ip);
189
190 /* Converts an ISL AST expression E back to a GCC expression tree of
191 type TYPE. */
192 tree gcc_expression_from_isl_expression (tree type,
193 __isl_take isl_ast_expr *,
194 ivs_params &ip);
195
196 /* Return the tree variable that corresponds to the given isl ast identifier
197 expression (an isl_ast_expr of type isl_ast_expr_id).
198
199 FIXME: We should replace blind conversation of id's type with derivation
200 of the optimal type when we get the corresponding isl support. Blindly
201 converting type sizes may be problematic when we switch to smaller
202 types. */
203 tree gcc_expression_from_isl_ast_expr_id (tree type,
204 __isl_keep isl_ast_expr *expr_id,
205 ivs_params &ip);
206
207 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
208 type TYPE. */
209 tree gcc_expression_from_isl_expr_int (tree type,
210 __isl_take isl_ast_expr *expr);
211
212 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
213 type TYPE. */
214 tree gcc_expression_from_isl_expr_op (tree type,
215 __isl_take isl_ast_expr *expr,
216 ivs_params &ip);
217
218 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
219 induction variable for the new LOOP. New LOOP is attached to CFG
220 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
221 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
222 ISL's scattering name to the induction variable created for the
223 loop of STMT. The new induction variable is inserted in the NEWIVS
224 vector and is of type TYPE. */
225 struct loop *graphite_create_new_loop (edge entry_edge,
226 __isl_keep isl_ast_node *node_for,
227 loop_p outer, tree type,
228 tree lb, tree ub, ivs_params &ip);
229
230 /* All loops generated by create_empty_loop_on_edge have the form of
231 a post-test loop:
232
233 do
234
235 {
236 body of the loop;
237 } while (lower bound < upper bound);
238
239 We create a new if region protecting the loop to be executed, if
240 the execution count is zero (lower bound > upper bound). */
241 edge graphite_create_new_loop_guard (edge entry_edge,
242 __isl_keep isl_ast_node *node_for,
243 tree *type,
244 tree *lb, tree *ub, ivs_params &ip);
245
246 /* Creates a new if region corresponding to ISL's cond. */
247 edge graphite_create_new_guard (edge entry_edge,
248 __isl_take isl_ast_expr *if_cond,
249 ivs_params &ip);
250
251 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
252 variables of the loops around GBB in SESE.
253
254 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
255 chrec, we could consider using a map<int, tree> that maps loop ids to the
256 corresponding tree expressions. */
65ef70d6 257 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
050e1371 258 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
bafcb153 259 sese_l &region);
65b016eb
AK
260
261 void translate_pending_phi_nodes (void);
262
263 bool codegen_error_p () { return codegen_error; }
264
050e1371 265private:
bafcb153 266 sese_info_p region;
65b016eb
AK
267
268 /* This flag is set when an error occurred during the translation of ISL AST
269 to Gimple. */
270 bool codegen_error;
050e1371 271};
a78cfa7f
RG
272
273/* Return the tree variable that corresponds to the given isl ast identifier
6a7d8936
RG
274 expression (an isl_ast_expr of type isl_ast_expr_id).
275
276 FIXME: We should replace blind conversation of id's type with derivation
277 of the optimal type when we get the corresponding isl support. Blindly
278 converting type sizes may be problematic when we switch to smaller
279 types. */
a78cfa7f 280
050e1371
AK
281tree
282translate_isl_ast_to_gimple::
6a7d8936
RG
283gcc_expression_from_isl_ast_expr_id (tree type,
284 __isl_keep isl_ast_expr *expr_id,
a78cfa7f
RG
285 ivs_params &ip)
286{
287 gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
288 isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
289 std::map<isl_id *, tree>::iterator res;
290 res = ip.find (tmp_isl_id);
291 isl_id_free (tmp_isl_id);
292 gcc_assert (res != ip.end () &&
050e1371 293 "Could not map isl_id to tree expression");
a78cfa7f 294 isl_ast_expr_free (expr_id);
74032f47 295 tree t = res->second;
24bc7503 296 return fold_convert (type, t);
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
a78cfa7f
RG
583 /* Translate the body of the loop. */
584 isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
585 next_e = translate_isl_ast (loop, for_body, to_body, ip);
586 isl_ast_node_free (for_body);
65b016eb
AK
587
588 /* Early return if we failed to translate loop body. */
589 if (!next_e || codegen_error)
590 return NULL;
591
a78cfa7f
RG
592 redirect_edge_succ_nodup (next_e, after);
593 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
594
574921c2
RG
595 if (flag_loop_parallelize_all)
596 {
597 isl_id *id = isl_ast_node_get_annotation (node_for);
598 gcc_assert (id);
599 ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
600 loop->can_be_parallel = for_info->is_parallelizable;
601 free (for_info);
602 isl_id_free (id);
603 }
a78cfa7f
RG
604
605 return last_e;
606}
607
608/* We use this function to get the upper bound because of the form,
609 which is used by isl to represent loops:
610
611 for (iterator = init; cond; iterator += inc)
612
613 {
614
615 ...
616
617 }
618
619 The loop condition is an arbitrary expression, which contains the
620 current loop iterator.
621
622 (e.g. iterator + 3 < B && C > iterator + A)
623
624 We have to know the upper bound of the iterator to generate a loop
625 in Gimple form. It can be obtained from the special representation
626 of the loop condition, which is generated by isl,
627 if the ast_build_atomic_upper_bound option is set. In this case,
628 isl generates a loop condition that consists of the current loop
629 iterator, + an operator (< or <=) and an expression not involving
630 the iterator, which is processed and returned by this function.
631
632 (e.g iterator <= upper-bound-expression-without-iterator) */
633
634static __isl_give isl_ast_expr *
635get_upper_bound (__isl_keep isl_ast_node *node_for)
636{
637 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
638 isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
639 gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
640 isl_ast_expr *res;
641 switch (isl_ast_expr_get_op_type (for_cond))
642 {
643 case isl_ast_op_le:
644 res = isl_ast_expr_get_op_arg (for_cond, 1);
645 break;
646
647 case isl_ast_op_lt:
648 {
649 // (iterator < ub) => (iterator <= ub - 1)
2a466686
RG
650 isl_val *one =
651 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
a78cfa7f
RG
652 isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
653 res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
654 break;
655 }
656
657 default:
658 gcc_unreachable ();
659 }
660 isl_ast_expr_free (for_cond);
661 return res;
662}
663
664/* All loops generated by create_empty_loop_on_edge have the form of
665 a post-test loop:
666
667 do
668
669 {
670 body of the loop;
671 } while (lower bound < upper bound);
672
673 We create a new if region protecting the loop to be executed, if
674 the execution count is zero (lower bound > upper bound). */
675
050e1371
AK
676edge
677translate_isl_ast_to_gimple::
a78cfa7f
RG
678graphite_create_new_loop_guard (edge entry_edge,
679 __isl_keep isl_ast_node *node_for, tree *type,
680 tree *lb, tree *ub, ivs_params &ip)
681{
682 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
683 tree cond_expr;
684 edge exit_edge;
685
55d1bd59
RG
686 *type =
687 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
a78cfa7f
RG
688 isl_ast_expr *for_init = isl_ast_node_for_get_init (node_for);
689 *lb = gcc_expression_from_isl_expression (*type, for_init, ip);
690 isl_ast_expr *upper_bound = get_upper_bound (node_for);
691 *ub = gcc_expression_from_isl_expression (*type, upper_bound, ip);
692
693 /* When ub is simply a constant or a parameter, use lb <= ub. */
694 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
695 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
696 else
697 {
698 tree one = (POINTER_TYPE_P (*type)
699 ? convert_to_ptrofftype (integer_one_node)
700 : fold_convert (*type, integer_one_node));
701 /* Adding +1 and using LT_EXPR helps with loop latches that have a
702 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this
703 becomes 2^k-1 due to integer overflow, and the condition lb <= ub
704 is true, even if we do not want this. However lb < ub + 1 is false,
705 as expected. */
706 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
707 : PLUS_EXPR, *type, *ub, one);
708
709 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
710 }
711
77ec8b8c
AK
712 if (integer_onep (cond_expr))
713 exit_edge = entry_edge;
714 else
715 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
a78cfa7f
RG
716
717 return exit_edge;
718}
719
720/* Translates an isl_ast_node_for to Gimple. */
721
050e1371
AK
722edge
723translate_isl_ast_to_gimple::
a78cfa7f
RG
724translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
725 edge next_e, ivs_params &ip)
726{
727 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
728 tree type, lb, ub;
729 edge last_e = graphite_create_new_loop_guard (next_e, node, &type,
730 &lb, &ub, ip);
a78cfa7f 731
77ec8b8c
AK
732 if (last_e == next_e)
733 /* There was no guard generated. */
734 return translate_isl_ast_for_loop (context_loop, node, last_e,
735 type, lb, ub, ip);
736
737 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
738 translate_isl_ast_for_loop (context_loop, node, true_e, type, lb, ub, ip);
a78cfa7f
RG
739 return last_e;
740}
741
5493d313
RG
742/* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
743 variables of the loops around GBB in SESE.
744
745 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
746 chrec, we could consider using a map<int, tree> that maps loop ids to the
747 corresponding tree expressions. */
748
050e1371
AK
749void
750translate_isl_ast_to_gimple::
65ef70d6 751build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
5493d313 752 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
bafcb153 753 sese_l &region)
5493d313
RG
754{
755 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
050e1371 756 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
5493d313
RG
757 int i;
758 isl_ast_expr *arg_expr;
759 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
760 {
761 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
762 tree type =
050e1371 763 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
5493d313
RG
764 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
765 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
766 iv_map[old_loop->num] = t;
767 }
5493d313
RG
768}
769
770/* Translates an isl_ast_node_user to Gimple.
771
772 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
773
050e1371
AK
774edge
775translate_isl_ast_to_gimple::
5493d313
RG
776translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
777 edge next_e, ivs_params &ip)
778{
779 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
65b016eb 780
5493d313
RG
781 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
782 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
783 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
65b016eb 784
5493d313
RG
785 isl_id *name_id = isl_ast_expr_get_id (name_expr);
786 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
787 gcc_assert (pbb);
65b016eb 788
65ef70d6 789 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
65b016eb 790
5493d313
RG
791 isl_ast_expr_free (name_expr);
792 isl_id_free (name_id);
793
794 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
795 "The entry block should not even appear within a scop");
796
b5bdf598 797 int nb_loops = number_of_loops (cfun);
65b016eb 798 vec<tree> iv_map;
b5bdf598
RG
799 iv_map.create (nb_loops);
800 iv_map.safe_grow_cleared (nb_loops);
5493d313 801
d37fc3aa 802 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
5493d313 803 isl_ast_expr_free (user_expr);
1b38d3ec
AK
804
805 if (dump_file)
806 {
65b016eb 807 fprintf (dump_file, "[codegen] copying from basic block\n");
1b38d3ec 808 print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
65b016eb
AK
809 fprintf (dump_file, "\n[codegen] to new basic block\n");
810 print_loops_bb (dump_file, next_e->src, 0, 3);
1b38d3ec
AK
811 }
812
5493d313 813 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb),
d37fc3aa 814 pbb->scop->scop_info, next_e,
5493d313 815 iv_map,
65b016eb
AK
816 &codegen_error);
817 if (codegen_error)
818 return NULL;
819
1b38d3ec
AK
820 if (dump_file)
821 {
65b016eb 822 fprintf (dump_file, "\n[codegen] (after copy) new basic block\n");
1b38d3ec
AK
823 print_loops_bb (dump_file, next_e->src, 0, 3);
824 }
825
5493d313
RG
826 iv_map.release ();
827 mark_virtual_operands_for_renaming (cfun);
828 update_ssa (TODO_update_ssa);
65b016eb
AK
829
830 if (dump_file)
831 {
832 fprintf (dump_file, "\n[codegen] (after update SSA) new basic block\n");
833 print_loops_bb (dump_file, next_e->src, 0, 3);
834 }
835
5493d313
RG
836 return next_e;
837}
838
322a0b39
RG
839/* Translates an isl_ast_node_block to Gimple. */
840
050e1371
AK
841edge
842translate_isl_ast_to_gimple::
322a0b39
RG
843translate_isl_ast_node_block (loop_p context_loop,
844 __isl_keep isl_ast_node *node,
845 edge next_e, ivs_params &ip)
846{
847 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
848 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
849 int i;
850 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
851 {
852 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
853 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
854 isl_ast_node_free (tmp_node);
855 }
856 isl_ast_node_list_free (node_list);
857 return next_e;
858}
333cc518
RG
859
860/* Creates a new if region corresponding to ISL's cond. */
861
050e1371
AK
862edge
863translate_isl_ast_to_gimple::
333cc518
RG
864graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
865 ivs_params &ip)
866{
867 tree type =
868 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
869 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
870 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
871 return exit_edge;
872}
873
874/* Translates an isl_ast_node_if to Gimple. */
875
050e1371
AK
876edge
877translate_isl_ast_to_gimple::
333cc518
RG
878translate_isl_ast_node_if (loop_p context_loop,
879 __isl_keep isl_ast_node *node,
880 edge next_e, ivs_params &ip)
881{
882 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
883 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
884 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
885
886 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
887 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
888 translate_isl_ast (context_loop, then_node, true_e, ip);
889 isl_ast_node_free (then_node);
890
891 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
892 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
893 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
894 translate_isl_ast (context_loop, else_node, false_e, ip);
895 isl_ast_node_free (else_node);
896 return last_e;
897}
322a0b39 898
a78cfa7f
RG
899/* Translates an ISL AST node NODE to GCC representation in the
900 context of a SESE. */
901
050e1371
AK
902edge
903translate_isl_ast_to_gimple::translate_isl_ast (loop_p context_loop,
904 __isl_keep isl_ast_node *node,
905 edge next_e, ivs_params &ip)
a78cfa7f 906{
65b016eb
AK
907 if (codegen_error)
908 return NULL;
909
a78cfa7f
RG
910 switch (isl_ast_node_get_type (node))
911 {
912 case isl_ast_node_error:
913 gcc_unreachable ();
914
915 case isl_ast_node_for:
916 return translate_isl_ast_node_for (context_loop, node,
917 next_e, ip);
918
919 case isl_ast_node_if:
333cc518
RG
920 return translate_isl_ast_node_if (context_loop, node,
921 next_e, ip);
a78cfa7f
RG
922
923 case isl_ast_node_user:
5493d313 924 return translate_isl_ast_node_user (node, next_e, ip);
a78cfa7f
RG
925
926 case isl_ast_node_block:
322a0b39
RG
927 return translate_isl_ast_node_block (context_loop, node,
928 next_e, ip);
a78cfa7f
RG
929
930 default:
931 gcc_unreachable ();
932 }
933}
934
65b016eb
AK
935/* Patch the missing arguments of the phi nodes. */
936
937void
938translate_isl_ast_to_gimple::translate_pending_phi_nodes ()
939{
940 int i;
941 phi_rename *rename;
942 FOR_EACH_VEC_ELT (region->incomplete_phis, i, rename)
943 {
944 gphi *old_phi = rename->first;
945 gphi *new_phi = rename->second;
946 basic_block old_bb = gimple_bb (old_phi);
947 basic_block new_bb = gimple_bb (new_phi);
948
949 /* First edge is the init edge and second is the back edge. */
950 init_back_edge_pair_t ibp_old_bb = get_edges (old_bb);
951 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
952
953 if (dump_file)
954 {
955 fprintf (dump_file, "\n[codegen] translating pending old-phi: ");
956 print_gimple_stmt (dump_file, old_phi, 0, 0);
957 }
958
959 auto_vec <tree, 1> iv_map;
960 if (bb_contains_loop_phi_nodes (new_bb))
961 copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
962 ibp_new_bb, region, false);
963 else if (bb_contains_loop_close_phi_nodes (new_bb))
964 copy_loop_close_phi_args (old_bb, new_bb, region, false);
965 else if (!copy_cond_phi_args (old_phi, new_phi, iv_map, region, false))
966 gcc_unreachable ();
967
968 if (dump_file)
969 {
970 fprintf (dump_file, "[codegen] to new-phi: ");
971 print_gimple_stmt (dump_file, new_phi, 0, 0);
972 }
973 }
974}
975
f6cc3103
RG
976/* Prints NODE to FILE. */
977
978void
979print_isl_ast_node (FILE *file, __isl_keep isl_ast_node *node,
980 __isl_keep isl_ctx *ctx)
981{
982 isl_printer *prn = isl_printer_to_file (ctx, file);
983 prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
984 prn = isl_printer_print_ast_node (prn, node);
985 prn = isl_printer_print_str (prn, "\n");
986 isl_printer_free (prn);
987}
988
a78cfa7f
RG
989/* Add ISL's parameter identifiers and corresponding.trees to ivs_params */
990
991static void
992add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
993{
d37fc3aa 994 sese_info_p region = scop->scop_info;
8e4dc590 995 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
65b016eb 996 gcc_assert (nb_parameters == region->params.length ());
a78cfa7f
RG
997 unsigned i;
998 for (i = 0; i < nb_parameters; i++)
999 {
8e4dc590
AK
1000 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
1001 isl_dim_param, i);
65b016eb 1002 ip[tmp_id] = region->params[i];
a78cfa7f
RG
1003 }
1004}
1005
1006
f6cc3103
RG
1007/* Generates a build, which specifies the constraints on the parameters. */
1008
e4a452b2 1009static __isl_give isl_ast_build *
f6cc3103
RG
1010generate_isl_context (scop_p scop)
1011{
8e4dc590 1012 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
f6cc3103
RG
1013 return isl_ast_build_from_context (context_isl);
1014}
1015
fb3764d1
RG
1016/* Get the maximal number of schedule dimensions in the scop SCOP. */
1017
1018static
1019int get_max_schedule_dimensions (scop_p scop)
1020{
1021 int i;
1022 poly_bb_p pbb;
1023 int schedule_dims = 0;
1024
b0b5710c 1025 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
fb3764d1
RG
1026 {
1027 int pbb_schedule_dims = isl_map_dim (pbb->transformed, isl_dim_out);
1028 if (pbb_schedule_dims > schedule_dims)
1029 schedule_dims = pbb_schedule_dims;
1030 }
1031
1032 return schedule_dims;
1033}
1034
1035/* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
1036
1037 For schedules with different dimensionality, the isl AST generator can not
1038 define an order and will just randomly choose an order. The solution to this
1039 problem is to extend all schedules to the maximal number of schedule
1040 dimensions (using '0's for the remaining values). */
1041
1042static __isl_give isl_map *
1043extend_schedule (__isl_take isl_map *schedule, int nb_schedule_dims)
1044{
1045 int tmp_dims = isl_map_dim (schedule, isl_dim_out);
1046 schedule =
1047 isl_map_add_dims (schedule, isl_dim_out, nb_schedule_dims - tmp_dims);
1048 isl_val *zero =
1049 isl_val_int_from_si (isl_map_get_ctx (schedule), 0);
1050 int i;
1051 for (i = tmp_dims; i < nb_schedule_dims; i++)
1052 {
1053 schedule =
1054 isl_map_fix_val (schedule, isl_dim_out, i, isl_val_copy (zero));
1055 }
1056 isl_val_free (zero);
1057 return schedule;
1058}
1059
f6cc3103
RG
1060/* Generates a schedule, which specifies an order used to
1061 visit elements in a domain. */
1062
e4a452b2 1063static __isl_give isl_union_map *
f6cc3103
RG
1064generate_isl_schedule (scop_p scop)
1065{
fb3764d1 1066 int nb_schedule_dims = get_max_schedule_dimensions (scop);
f6cc3103
RG
1067 int i;
1068 poly_bb_p pbb;
1069 isl_union_map *schedule_isl =
8e4dc590 1070 isl_union_map_empty (isl_set_get_space (scop->param_context));
f6cc3103 1071
b0b5710c 1072 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
f6cc3103
RG
1073 {
1074 /* Dead code elimination: when the domain of a PBB is empty,
1075 don't generate code for the PBB. */
1076 if (isl_set_is_empty (pbb->domain))
1077 continue;
1078
1079 isl_map *bb_schedule = isl_map_copy (pbb->transformed);
1080 bb_schedule = isl_map_intersect_domain (bb_schedule,
1081 isl_set_copy (pbb->domain));
fb3764d1 1082 bb_schedule = extend_schedule (bb_schedule, nb_schedule_dims);
f6cc3103
RG
1083 schedule_isl =
1084 isl_union_map_union (schedule_isl,
1085 isl_union_map_from_map (bb_schedule));
1086 }
1087 return schedule_isl;
1088}
1089
574921c2
RG
1090/* This method is executed before the construction of a for node. */
1091static __isl_give isl_id *
1092ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
1093{
1094 isl_union_map *dependences = (isl_union_map *) user;
1095 ast_build_info *for_info = XNEW (struct ast_build_info);
1096 isl_union_map *schedule = isl_ast_build_get_schedule (build);
1097 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
1098 int dimension = isl_space_dim (schedule_space, isl_dim_out);
1099 for_info->is_parallelizable =
1100 !carries_deps (schedule, dependences, dimension);
1101 isl_union_map_free (schedule);
1102 isl_space_free (schedule_space);
1103 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
1104 return id;
1105}
1106
6a12a004 1107/* Set the separate option for all dimensions.
a5e5ea0c 1108 This helps to reduce control overhead. */
6a12a004
RG
1109
1110static __isl_give isl_ast_build *
1111set_options (__isl_take isl_ast_build *control,
a5e5ea0c 1112 __isl_keep isl_union_map *schedule)
6a12a004
RG
1113{
1114 isl_ctx *ctx = isl_union_map_get_ctx (schedule);
1115 isl_space *range_space = isl_space_set_alloc (ctx, 0, 1);
1116 range_space =
1117 isl_space_set_tuple_name (range_space, isl_dim_set, "separate");
1118 isl_union_set *range =
1119 isl_union_set_from_set (isl_set_universe (range_space));
1120 isl_union_set *domain = isl_union_map_range (isl_union_map_copy (schedule));
1121 domain = isl_union_set_universe (domain);
1122 isl_union_map *options = isl_union_map_from_domain_and_range (domain, range);
1123 return isl_ast_build_set_options (control, options);
1124}
1125
e4a452b2 1126static __isl_give isl_ast_node *
a78cfa7f 1127scop_to_isl_ast (scop_p scop, ivs_params &ip)
f6cc3103 1128{
a78cfa7f
RG
1129 /* Generate loop upper bounds that consist of the current loop iterator,
1130 an operator (< or <=) and an expression not involving the iterator.
1131 If this option is not set, then the current loop iterator may appear several
1132 times in the upper bound. See the isl manual for more details. */
8e4dc590 1133 isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, true);
a78cfa7f
RG
1134
1135 add_parameters_to_ivs_params (scop, ip);
f6cc3103
RG
1136 isl_union_map *schedule_isl = generate_isl_schedule (scop);
1137 isl_ast_build *context_isl = generate_isl_context (scop);
a5e5ea0c 1138 context_isl = set_options (context_isl, schedule_isl);
574921c2
RG
1139 isl_union_map *dependences = NULL;
1140 if (flag_loop_parallelize_all)
1141 {
1142 dependences = scop_get_dependences (scop);
1143 context_isl =
1144 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
1145 dependences);
1146 }
f6cc3103
RG
1147 isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
1148 schedule_isl);
574921c2
RG
1149 if(dependences)
1150 isl_union_map_free (dependences);
f6cc3103
RG
1151 isl_ast_build_free (context_isl);
1152 return ast_isl;
1153}
1154
1155/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1156 the given SCOP. Return true if code generation succeeded.
1157
1158 FIXME: This is not yet a full implementation of the code generator
a78cfa7f 1159 with ISL ASTs. Generation of GIMPLE code has to be completed. */
f6cc3103
RG
1160
1161bool
1162graphite_regenerate_ast_isl (scop_p scop)
1163{
a78cfa7f 1164 loop_p context_loop;
d37fc3aa 1165 sese_info_p region = scop->scop_info;
a78cfa7f
RG
1166 ifsese if_region = NULL;
1167 isl_ast_node *root_node;
1168 ivs_params ip;
1169
f6cc3103 1170 timevar_push (TV_GRAPHITE_CODE_GEN);
a78cfa7f
RG
1171 root_node = scop_to_isl_ast (scop, ip);
1172
f6cc3103
RG
1173 if (dump_file && (dump_flags & TDF_DETAILS))
1174 {
1175 fprintf (dump_file, "\nISL AST generated by ISL: \n");
8e4dc590 1176 print_isl_ast_node (dump_file, root_node, scop->isl_context);
a78cfa7f 1177 fprintf (dump_file, "\n");
f6cc3103 1178 }
a78cfa7f
RG
1179
1180 recompute_all_dominators ();
1181 graphite_verify ();
1182
1183 if_region = move_sese_in_condition (region);
65b016eb 1184 region->if_region = if_region;
a78cfa7f 1185 recompute_all_dominators ();
a78cfa7f 1186
bafcb153 1187 context_loop = region->region.entry->src->loop_father;
a78cfa7f 1188
74032f47 1189 translate_isl_ast_to_gimple t(region);
bafcb153 1190 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
65b016eb
AK
1191 basic_block bb = split_edge (e);
1192 /* Update the true_region exit edge. */
1193 region->if_region->true_region->region.exit = single_succ_edge (bb);
d819fedb 1194
65b016eb
AK
1195 t.translate_isl_ast (context_loop, root_node, e, ip);
1196 if (t.codegen_error_p ())
1197 {
1198 if (dump_file)
1199 fprintf (dump_file, "\n[codegen] unsuccessful, "
1200 "reverting back to the original code.");
1201 set_ifsese_condition (if_region, integer_zero_node);
1202 }
1203 else
1204 {
1205 t.translate_pending_phi_nodes ();
1206 if (!t.codegen_error_p ())
1207 {
1208 sese_insert_phis_for_liveouts (region,
1209 if_region->region->region.exit->src,
1210 if_region->false_region->region.exit,
1211 if_region->true_region->region.exit);
1212 mark_virtual_operands_for_renaming (cfun);
1213 update_ssa (TODO_update_ssa);
1214
1215
1216 graphite_verify ();
1217 scev_reset ();
1218 recompute_all_dominators ();
1219 graphite_verify ();
1220 }
1221 else if (dump_file)
1222 fprintf (dump_file, "\n[codegen] unsuccessful in translating "
1223 "pending phis, reverting back to the original code.");
1224 }
a78cfa7f
RG
1225
1226 free (if_region->true_region);
1227 free (if_region->region);
1228 free (if_region);
1229
1230 ivs_params_clear (ip);
f6cc3103
RG
1231 isl_ast_node_free (root_node);
1232 timevar_pop (TV_GRAPHITE_CODE_GEN);
574921c2
RG
1233
1234 if (dump_file && (dump_flags & TDF_DETAILS))
1235 {
1236 loop_p loop;
1237 int num_no_dependency = 0;
1238
1239 FOR_EACH_LOOP (loop, 0)
1240 if (loop->can_be_parallel)
1241 num_no_dependency++;
1242
1243 fprintf (dump_file, "\n%d loops carried no dependency.\n",
1244 num_no_dependency);
1245 }
1246
65b016eb 1247 return !t.codegen_error_p ();
f6cc3103 1248}
9c358739 1249#endif /* HAVE_isl */