]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/graphite-isl-ast-to-gimple.c
[AARCH64] Adding constant folding for __builtin_fmulx* with scalar 32 and 64 bit...
[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"
2ecf4eca 51#include "gimple-fold.h"
f6cc3103 52#include "gimple-iterator.h"
2ecf4eca
AK
53#include "gimplify.h"
54#include "gimplify-me.h"
55#include "tree-eh.h"
f6cc3103 56#include "tree-ssa-loop.h"
2ecf4eca
AK
57#include "tree-ssa-operands.h"
58#include "tree-ssa-propagate.h"
f6cc3103
RG
59#include "tree-pass.h"
60#include "cfgloop.h"
61#include "tree-data-ref.h"
9c358739 62#include "graphite-poly.h"
a78cfa7f
RG
63#include "tree-ssa-loop-manip.h"
64#include "tree-scalar-evolution.h"
5493d313 65#include "gimple-ssa.h"
74032f47 66#include "tree-phinodes.h"
5493d313 67#include "tree-into-ssa.h"
74032f47 68#include "ssa-iterators.h"
f6cc3103 69#include "graphite-isl-ast-to-gimple.h"
1b38d3ec 70#include "tree-cfg.h"
65b016eb 71#include "gimple-pretty-print.h"
2ecf4eca
AK
72#include "cfganal.h"
73#include "value-prof.h"
74
75#include <map>
f6cc3103 76
55d1bd59
RG
77/* We always try to use signed 128 bit types, but fall back to smaller types
78 in case a platform does not provide types of these sizes. In the future we
79 should use isl to derive the optimal type for each subexpression. */
a78cfa7f 80
55d1bd59
RG
81static int max_mode_int_precision =
82 GET_MODE_PRECISION (mode_for_size (MAX_FIXED_MODE_SIZE, MODE_INT, 0));
83static int graphite_expression_type_precision = 128 <= max_mode_int_precision ?
84 128 : max_mode_int_precision;
a78cfa7f 85
574921c2
RG
86struct ast_build_info
87{
88 ast_build_info()
89 : is_parallelizable(false)
2ecf4eca 90 { }
574921c2
RG
91 bool is_parallelizable;
92};
93
a78cfa7f
RG
94/* Converts a GMP constant VAL to a tree and returns it. */
95
96static tree
97gmp_cst_to_tree (tree type, mpz_t val)
98{
99 tree t = type ? type : integer_type_node;
100 mpz_t tmp;
101
102 mpz_init (tmp);
103 mpz_set (tmp, val);
104 wide_int wi = wi::from_mpz (t, tmp, true);
105 mpz_clear (tmp);
106
107 return wide_int_to_tree (t, wi);
108}
109
110/* Verifies properties that GRAPHITE should maintain during translation. */
111
112static inline void
113graphite_verify (void)
114{
b2b29377
MM
115 checking_verify_loop_structure ();
116 checking_verify_loop_closed_ssa (true);
a78cfa7f
RG
117}
118
119/* IVS_PARAMS maps ISL's scattering and parameter identifiers
120 to corresponding trees. */
121
122typedef std::map<isl_id *, tree> ivs_params;
123
124/* Free all memory allocated for ISL's identifiers. */
125
126void ivs_params_clear (ivs_params &ip)
127{
128 std::map<isl_id *, tree>::iterator it;
129 for (it = ip.begin ();
130 it != ip.end (); it++)
131 {
132 isl_id_free (it->first);
133 }
134}
135
050e1371
AK
136class translate_isl_ast_to_gimple
137{
138 public:
bafcb153 139 translate_isl_ast_to_gimple (sese_info_p r)
65b016eb 140 : region (r), codegen_error (false)
2ecf4eca 141 { }
050e1371
AK
142
143 /* Translates an ISL AST node NODE to GCC representation in the
144 context of a SESE. */
145 edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
146 edge next_e, ivs_params &ip);
147
148 /* Translates an isl_ast_node_for to Gimple. */
149 edge translate_isl_ast_node_for (loop_p context_loop,
150 __isl_keep isl_ast_node *node,
151 edge next_e, ivs_params &ip);
152
153 /* Create the loop for a isl_ast_node_for.
154
155 - NEXT_E is the edge where new generated code should be attached. */
156 edge translate_isl_ast_for_loop (loop_p context_loop,
157 __isl_keep isl_ast_node *node_for,
158 edge next_e,
159 tree type, tree lb, tree ub,
160 ivs_params &ip);
161
162 /* Translates an isl_ast_node_if to Gimple. */
163 edge translate_isl_ast_node_if (loop_p context_loop,
164 __isl_keep isl_ast_node *node,
165 edge next_e, ivs_params &ip);
166
167 /* Translates an isl_ast_node_user to Gimple.
168
169 FIXME: We should remove iv_map.create (loop->num + 1), if it is
170 possible. */
171 edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
172 edge next_e, ivs_params &ip);
173
174 /* Translates an isl_ast_node_block to Gimple. */
175 edge translate_isl_ast_node_block (loop_p context_loop,
176 __isl_keep isl_ast_node *node,
177 edge next_e, ivs_params &ip);
178
179 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
180 type TYPE. */
181 tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
182 ivs_params &ip);
183
184 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
185 type TYPE. */
186 tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
187 ivs_params &ip);
188
189 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
190 type TYPE. */
191 tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
192 ivs_params &ip);
193
194 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
195 to a GCC expression tree of type TYPE. */
196 tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
197 ivs_params &ip);
198
199 /* Converts an ISL AST expression E back to a GCC expression tree of
200 type TYPE. */
201 tree gcc_expression_from_isl_expression (tree type,
202 __isl_take isl_ast_expr *,
203 ivs_params &ip);
204
205 /* Return the tree variable that corresponds to the given isl ast identifier
206 expression (an isl_ast_expr of type isl_ast_expr_id).
207
208 FIXME: We should replace blind conversation of id's type with derivation
209 of the optimal type when we get the corresponding isl support. Blindly
210 converting type sizes may be problematic when we switch to smaller
211 types. */
212 tree gcc_expression_from_isl_ast_expr_id (tree type,
213 __isl_keep isl_ast_expr *expr_id,
214 ivs_params &ip);
215
216 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
217 type TYPE. */
218 tree gcc_expression_from_isl_expr_int (tree type,
219 __isl_take isl_ast_expr *expr);
220
221 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
222 type TYPE. */
223 tree gcc_expression_from_isl_expr_op (tree type,
224 __isl_take isl_ast_expr *expr,
225 ivs_params &ip);
226
227 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
228 induction variable for the new LOOP. New LOOP is attached to CFG
229 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
230 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
231 ISL's scattering name to the induction variable created for the
232 loop of STMT. The new induction variable is inserted in the NEWIVS
233 vector and is of type TYPE. */
234 struct loop *graphite_create_new_loop (edge entry_edge,
235 __isl_keep isl_ast_node *node_for,
236 loop_p outer, tree type,
237 tree lb, tree ub, ivs_params &ip);
238
239 /* All loops generated by create_empty_loop_on_edge have the form of
240 a post-test loop:
241
242 do
243
244 {
245 body of the loop;
246 } while (lower bound < upper bound);
247
248 We create a new if region protecting the loop to be executed, if
249 the execution count is zero (lower bound > upper bound). */
250 edge graphite_create_new_loop_guard (edge entry_edge,
251 __isl_keep isl_ast_node *node_for,
252 tree *type,
253 tree *lb, tree *ub, ivs_params &ip);
254
255 /* Creates a new if region corresponding to ISL's cond. */
256 edge graphite_create_new_guard (edge entry_edge,
257 __isl_take isl_ast_expr *if_cond,
258 ivs_params &ip);
259
260 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
261 variables of the loops around GBB in SESE.
262
263 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
264 chrec, we could consider using a map<int, tree> that maps loop ids to the
265 corresponding tree expressions. */
65ef70d6 266 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
050e1371 267 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
bafcb153 268 sese_l &region);
65b016eb 269
2ecf4eca
AK
270 /* Patch the missing arguments of the phi nodes. */
271
65b016eb
AK
272 void translate_pending_phi_nodes (void);
273
2ecf4eca
AK
274 /* Add ISL's parameter identifiers and corresponding trees to ivs_params. */
275
276 void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
277
278 /* Get the maximal number of schedule dimensions in the scop SCOP. */
279
280 int get_max_schedule_dimensions (scop_p scop);
281
282 /* Generates a build, which specifies the constraints on the parameters. */
283
284 __isl_give isl_ast_build *generate_isl_context (scop_p scop);
285
286 /* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
287
288 For schedules with different dimensionality, the isl AST generator can not
289 define an order and will just randomly choose an order. The solution to
290 this problem is to extend all schedules to the maximal number of schedule
291 dimensions (using '0's for the remaining values). */
292
293 __isl_give isl_map *extend_schedule (__isl_take isl_map *schedule,
294 int nb_schedule_dims);
295
296 /* Generates a schedule, which specifies an order used to
297 visit elements in a domain. */
298
299 __isl_give isl_union_map *generate_isl_schedule (scop_p scop);
300
301 /* Set the separate option for all dimensions.
302 This helps to reduce control overhead. */
303
304 __isl_give isl_ast_build * set_options (__isl_take isl_ast_build *control,
305 __isl_keep isl_union_map *schedule);
306
307 /* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in
308 IP. */
309
310 __isl_give isl_ast_node * scop_to_isl_ast (scop_p scop, ivs_params &ip);
311
312
313 /* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
314 definition should flow into use, and the use should respect the loop-closed
315 SSA form. */
316
317 bool is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
318 bool loop_phi, tree old_name, basic_block old_bb) const;
319
320 /* Returns the expression associated to OLD_NAME (which is used in OLD_BB), in
321 NEW_BB from RENAME_MAP. LOOP_PHI is true when we want to rename OLD_NAME
322 within a loop PHI instruction. */
323
324 tree get_rename (basic_block new_bb, tree old_name,
325 basic_block old_bb, bool loop_phi) const;
326
327 /* For ops which are scev_analyzeable, we can regenerate a new name from
328 its scalar evolution around LOOP. */
329
330 tree get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
331 basic_block new_bb, basic_block old_bb,
332 vec<tree> iv_map);
333
334 /* Returns a basic block that could correspond to where a constant was defined
335 in the original code. In the original code OLD_BB had the definition, we
336 need to find which basic block out of the copies of old_bb, in the new
337 region, should a definition correspond to if it has to reach BB. */
338
339 basic_block get_def_bb_for_const (basic_block bb, basic_block old_bb) const;
340
341 /* Get the new name of OP (from OLD_BB) to be used in NEW_BB. LOOP_PHI is
342 true when we want to rename an OP within a loop PHI instruction. */
343
344 tree get_new_name (basic_block new_bb, tree op,
345 basic_block old_bb, bool loop_phi) const;
346
347 /* Collect all the operands of NEW_EXPR by recursively visiting each
348 operand. */
349
350 void collect_all_ssa_names (tree new_expr, vec<tree> *vec_ssa);
351
352 /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to
353 NEW_PHI must be found unless they can be POSTPONEd for later. */
354
21c7259c 355 bool copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
2ecf4eca
AK
356 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
357 bool postpone);
358
359 /* Copy loop phi nodes from BB to NEW_BB. */
360
361 bool copy_loop_phi_nodes (basic_block bb, basic_block new_bb);
362
363 /* Copy all the loop-close phi args from BB to NEW_BB. */
364
365 bool copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
366 bool postpone);
367
368 /* Copy loop close phi nodes from BB to NEW_BB. */
369
370 bool copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb);
371
372 /* Copy the arguments of cond-phi node PHI, to NEW_PHI in the codegenerated
373 region. If postpone is true and it isn't possible to copy any arg of PHI,
374 the PHI is added to the REGION->INCOMPLETE_PHIS to be codegenerated later.
375 Returns false if the copying was unsuccessful. */
376
377 bool copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map,
378 bool postpone);
379
380 /* Copy cond phi nodes from BB to NEW_BB. A cond-phi node is a basic block
381 containing phi nodes coming from two predecessors, and none of them are back
382 edges. */
383
384 bool copy_cond_phi_nodes (basic_block bb, basic_block new_bb,
385 vec<tree> iv_map);
386
387 /* Duplicates the statements of basic block BB into basic block NEW_BB
388 and compute the new induction variables according to the IV_MAP.
389 CODEGEN_ERROR is set when the code generation cannot continue. */
390
391 bool graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
392 vec<tree> iv_map);
393
394 /* Copies BB and includes in the copied BB all the statements that can
395 be reached following the use-def chains from the memory accesses,
396 and returns the next edge following this new block. codegen_error is
397 set when the code generation cannot continue. */
398
399 edge copy_bb_and_scalar_dependences (basic_block bb, edge next_e,
400 vec<tree> iv_map);
401
2927ca4b
AK
402 /* Given a basic block containing close-phi it returns the new basic block
403 where to insert a copy of the close-phi nodes. All the uses in close phis
404 should come from a single loop otherwise it returns NULL. */
405 edge edge_for_new_close_phis (basic_block bb);
406
2ecf4eca
AK
407 /* Add NEW_NAME as the ARGNUM-th arg of NEW_PHI which is in NEW_BB.
408 DOMINATING_PRED is the predecessor basic block of OLD_BB which dominates
409 the other pred of OLD_BB as well. If no such basic block exists then it is
410 NULL. NON_DOMINATING_PRED is a pred which does not dominate OLD_BB, it
411 cannot be NULL.
412
413 Case1: OLD_BB->preds {BB1, BB2} and BB1 does not dominate BB2 and vice
414 versa. In this case DOMINATING_PRED = NULL.
415
416 Case2: OLD_BB->preds {BB1, BB2} and BB1 dominates BB2.
417
418 Returns true on successful copy of the args, false otherwise. */
419
420 bool add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
421 edge old_bb_dominating_edge,
422 edge old_bb_non_dominating_edge,
423 gphi *phi, gphi *new_phi,
424 basic_block new_bb);
425
426 /* Renames the scalar uses of the statement COPY, using the substitution map
427 RENAME_MAP, inserting the gimplification code at GSI_TGT, for the
428 translation REGION, with the original copied statement in LOOP, and using
429 the induction variable renaming map IV_MAP. Returns true when something
430 has been renamed. codegen_error is set when the code generation cannot
431 continue. */
432
433 bool rename_uses (gimple *copy, gimple_stmt_iterator *gsi_tgt,
434 basic_block old_bb, loop_p loop, vec<tree> iv_map);
435
436 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
437 When OLD_NAME and EXPR are the same we assert. */
438
439 void set_rename (tree old_name, tree expr);
440
441 /* Create new names for all the definitions created by COPY and add
442 replacement mappings for each new name. */
443
444 void set_rename_for_each_def (gimple *stmt);
445
446 /* Insert each statement from SEQ at its earliest insertion p. */
447
448 void gsi_insert_earliest (gimple_seq seq);
449
450 /* Rename all the operands of NEW_EXPR by recursively visiting each
451 operand. */
452
453 tree rename_all_uses (tree new_expr, basic_block new_bb, basic_block old_bb);
454
455 bool codegen_error_p () const
456 { return codegen_error; }
457
458 /* Prints NODE to FILE. */
459
460 void print_isl_ast_node (FILE *file, __isl_keep isl_ast_node *node,
461 __isl_keep isl_ctx *ctx) const;
65b016eb 462
050e1371 463private:
bafcb153 464 sese_info_p region;
65b016eb
AK
465
466 /* This flag is set when an error occurred during the translation of ISL AST
467 to Gimple. */
468 bool codegen_error;
050e1371 469};
a78cfa7f
RG
470
471/* Return the tree variable that corresponds to the given isl ast identifier
6a7d8936
RG
472 expression (an isl_ast_expr of type isl_ast_expr_id).
473
474 FIXME: We should replace blind conversation of id's type with derivation
475 of the optimal type when we get the corresponding isl support. Blindly
476 converting type sizes may be problematic when we switch to smaller
477 types. */
a78cfa7f 478
050e1371
AK
479tree
480translate_isl_ast_to_gimple::
6a7d8936
RG
481gcc_expression_from_isl_ast_expr_id (tree type,
482 __isl_keep isl_ast_expr *expr_id,
a78cfa7f
RG
483 ivs_params &ip)
484{
485 gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
486 isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
487 std::map<isl_id *, tree>::iterator res;
488 res = ip.find (tmp_isl_id);
489 isl_id_free (tmp_isl_id);
490 gcc_assert (res != ip.end () &&
050e1371 491 "Could not map isl_id to tree expression");
a78cfa7f 492 isl_ast_expr_free (expr_id);
74032f47 493 tree t = res->second;
24bc7503 494 return fold_convert (type, t);
a78cfa7f
RG
495}
496
497/* Converts an isl_ast_expr_int expression E to a GCC expression tree of
498 type TYPE. */
499
050e1371
AK
500tree
501translate_isl_ast_to_gimple::
a78cfa7f
RG
502gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
503{
504 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
505 isl_val *val = isl_ast_expr_get_val (expr);
506 mpz_t val_mpz_t;
507 mpz_init (val_mpz_t);
508 tree res;
509 if (isl_val_get_num_gmp (val, val_mpz_t) == -1)
510 res = NULL_TREE;
511 else
512 res = gmp_cst_to_tree (type, val_mpz_t);
513 isl_val_free (val);
514 isl_ast_expr_free (expr);
515 mpz_clear (val_mpz_t);
516 return res;
517}
518
519/* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
520 type TYPE. */
521
050e1371
AK
522tree
523translate_isl_ast_to_gimple::
a78cfa7f
RG
524binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
525{
526 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
527 tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
528 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
529 tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
530 enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
531 isl_ast_expr_free (expr);
532 switch (expr_type)
533 {
534 case isl_ast_op_add:
535 return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
536
537 case isl_ast_op_sub:
538 return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
539
540 case isl_ast_op_mul:
541 return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
542
543 case isl_ast_op_div:
544 return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
545
c4bc3399
RG
546 case isl_ast_op_pdiv_q:
547 return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
548
549 case isl_ast_op_pdiv_r:
550 return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
551
a78cfa7f
RG
552 case isl_ast_op_fdiv_q:
553 return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
554
555 case isl_ast_op_and:
556 return fold_build2 (TRUTH_ANDIF_EXPR, type,
557 tree_lhs_expr, tree_rhs_expr);
558
559 case isl_ast_op_or:
560 return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);
561
562 case isl_ast_op_eq:
563 return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);
564
565 case isl_ast_op_le:
566 return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
567
568 case isl_ast_op_lt:
569 return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
570
571 case isl_ast_op_ge:
572 return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
573
574 case isl_ast_op_gt:
575 return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
576
577 default:
578 gcc_unreachable ();
579 }
580}
581
582/* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
583 type TYPE. */
584
050e1371
AK
585tree
586translate_isl_ast_to_gimple::
a78cfa7f
RG
587ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
588{
589 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
590 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
591 tree tree_first_expr
592 = gcc_expression_from_isl_expression (type, arg_expr, ip);
593 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
594 tree tree_second_expr
595 = gcc_expression_from_isl_expression (type, arg_expr, ip);
596 arg_expr = isl_ast_expr_get_op_arg (expr, 2);
597 tree tree_third_expr
598 = gcc_expression_from_isl_expression (type, arg_expr, ip);
599 isl_ast_expr_free (expr);
600 return fold_build3 (COND_EXPR, type, tree_first_expr,
601 tree_second_expr, tree_third_expr);
602}
603
604/* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
605 type TYPE. */
606
050e1371
AK
607tree
608translate_isl_ast_to_gimple::
a78cfa7f
RG
609unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
610{
611 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
612 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
613 tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
614 isl_ast_expr_free (expr);
615 return fold_build1 (NEGATE_EXPR, type, tree_expr);
616}
617
618/* Converts an isl_ast_expr_op expression E with unknown number of arguments
619 to a GCC expression tree of type TYPE. */
620
050e1371
AK
621tree
622translate_isl_ast_to_gimple::
a78cfa7f
RG
623nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
624{
625 enum tree_code op_code;
626 switch (isl_ast_expr_get_op_type (expr))
627 {
628 case isl_ast_op_max:
629 op_code = MAX_EXPR;
630 break;
631
632 case isl_ast_op_min:
633 op_code = MIN_EXPR;
634 break;
635
636 default:
637 gcc_unreachable ();
638 }
639 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
640 tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);
641 int i;
642 for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
643 {
644 arg_expr = isl_ast_expr_get_op_arg (expr, i);
645 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
646 res = fold_build2 (op_code, type, res, t);
647 }
648 isl_ast_expr_free (expr);
649 return res;
650}
651
a78cfa7f
RG
652/* Converts an isl_ast_expr_op expression E to a GCC expression tree of
653 type TYPE. */
654
050e1371
AK
655tree
656translate_isl_ast_to_gimple::
a78cfa7f
RG
657gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
658 ivs_params &ip)
659{
660 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
661 switch (isl_ast_expr_get_op_type (expr))
662 {
663 /* These isl ast expressions are not supported yet. */
664 case isl_ast_op_error:
665 case isl_ast_op_call:
666 case isl_ast_op_and_then:
667 case isl_ast_op_or_else:
a78cfa7f
RG
668 case isl_ast_op_select:
669 gcc_unreachable ();
670
671 case isl_ast_op_max:
672 case isl_ast_op_min:
673 return nary_op_to_tree (type, expr, ip);
674
675 case isl_ast_op_add:
676 case isl_ast_op_sub:
677 case isl_ast_op_mul:
678 case isl_ast_op_div:
c4bc3399
RG
679 case isl_ast_op_pdiv_q:
680 case isl_ast_op_pdiv_r:
a78cfa7f
RG
681 case isl_ast_op_fdiv_q:
682 case isl_ast_op_and:
683 case isl_ast_op_or:
684 case isl_ast_op_eq:
685 case isl_ast_op_le:
686 case isl_ast_op_lt:
687 case isl_ast_op_ge:
688 case isl_ast_op_gt:
689 return binary_op_to_tree (type, expr, ip);
690
691 case isl_ast_op_minus:
692 return unary_op_to_tree (type, expr, ip);
693
694 case isl_ast_op_cond:
695 return ternary_op_to_tree (type, expr, ip);
696
697 default:
698 gcc_unreachable ();
699 }
700
701 return NULL_TREE;
702}
703
704/* Converts an ISL AST expression E back to a GCC expression tree of
705 type TYPE. */
706
050e1371
AK
707tree
708translate_isl_ast_to_gimple::
a78cfa7f
RG
709gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
710 ivs_params &ip)
711{
712 switch (isl_ast_expr_get_type (expr))
713 {
714 case isl_ast_expr_id:
6a7d8936 715 return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
a78cfa7f
RG
716
717 case isl_ast_expr_int:
718 return gcc_expression_from_isl_expr_int (type, expr);
719
720 case isl_ast_expr_op:
721 return gcc_expression_from_isl_expr_op (type, expr, ip);
722
723 default:
724 gcc_unreachable ();
725 }
726
727 return NULL_TREE;
728}
729
730/* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
731 induction variable for the new LOOP. New LOOP is attached to CFG
732 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
733 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
734 ISL's scattering name to the induction variable created for the
735 loop of STMT. The new induction variable is inserted in the NEWIVS
736 vector and is of type TYPE. */
737
050e1371
AK
738struct loop *
739translate_isl_ast_to_gimple::
a78cfa7f
RG
740graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
741 loop_p outer, tree type, tree lb, tree ub,
742 ivs_params &ip)
743{
744 isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
745 tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
746 tree ivvar = create_tmp_var (type, "graphite_IV");
747 tree iv, iv_after_increment;
748 loop_p loop = create_empty_loop_on_edge
749 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
750 outer ? outer : entry_edge->src->loop_father);
751
752 isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
753 isl_id *id = isl_ast_expr_get_id (for_iterator);
a6631027
RG
754 std::map<isl_id *, tree>::iterator res;
755 res = ip.find (id);
756 if (ip.count (id))
757 isl_id_free (res->first);
a78cfa7f
RG
758 ip[id] = iv;
759 isl_ast_expr_free (for_iterator);
760 return loop;
761}
762
a78cfa7f
RG
763/* Create the loop for a isl_ast_node_for.
764
765 - NEXT_E is the edge where new generated code should be attached. */
766
050e1371
AK
767edge
768translate_isl_ast_to_gimple::
a78cfa7f
RG
769translate_isl_ast_for_loop (loop_p context_loop,
770 __isl_keep isl_ast_node *node_for, edge next_e,
771 tree type, tree lb, tree ub,
772 ivs_params &ip)
773{
774 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
775 struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
776 type, lb, ub, ip);
777 edge last_e = single_exit (loop);
778 edge to_body = single_succ_edge (loop->header);
779 basic_block after = to_body->dest;
780
a78cfa7f
RG
781 /* Translate the body of the loop. */
782 isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
783 next_e = translate_isl_ast (loop, for_body, to_body, ip);
784 isl_ast_node_free (for_body);
65b016eb
AK
785
786 /* Early return if we failed to translate loop body. */
2ecf4eca 787 if (!next_e || codegen_error_p ())
65b016eb
AK
788 return NULL;
789
a78cfa7f
RG
790 redirect_edge_succ_nodup (next_e, after);
791 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
792
574921c2 793 if (flag_loop_parallelize_all)
2ecf4eca
AK
794 {
795 isl_id *id = isl_ast_node_get_annotation (node_for);
796 gcc_assert (id);
797 ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
798 loop->can_be_parallel = for_info->is_parallelizable;
799 free (for_info);
800 isl_id_free (id);
801 }
a78cfa7f
RG
802
803 return last_e;
804}
805
806/* We use this function to get the upper bound because of the form,
807 which is used by isl to represent loops:
808
809 for (iterator = init; cond; iterator += inc)
810
811 {
812
2ecf4eca 813 ...
a78cfa7f
RG
814
815 }
816
817 The loop condition is an arbitrary expression, which contains the
818 current loop iterator.
819
820 (e.g. iterator + 3 < B && C > iterator + A)
821
822 We have to know the upper bound of the iterator to generate a loop
823 in Gimple form. It can be obtained from the special representation
824 of the loop condition, which is generated by isl,
825 if the ast_build_atomic_upper_bound option is set. In this case,
826 isl generates a loop condition that consists of the current loop
827 iterator, + an operator (< or <=) and an expression not involving
828 the iterator, which is processed and returned by this function.
829
830 (e.g iterator <= upper-bound-expression-without-iterator) */
831
832static __isl_give isl_ast_expr *
833get_upper_bound (__isl_keep isl_ast_node *node_for)
834{
835 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
836 isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
837 gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
838 isl_ast_expr *res;
839 switch (isl_ast_expr_get_op_type (for_cond))
840 {
841 case isl_ast_op_le:
842 res = isl_ast_expr_get_op_arg (for_cond, 1);
843 break;
844
845 case isl_ast_op_lt:
846 {
2ecf4eca 847 /* (iterator < ub) => (iterator <= ub - 1). */
2a466686
RG
848 isl_val *one =
849 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
a78cfa7f
RG
850 isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
851 res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
852 break;
853 }
854
855 default:
856 gcc_unreachable ();
857 }
858 isl_ast_expr_free (for_cond);
859 return res;
860}
861
862/* All loops generated by create_empty_loop_on_edge have the form of
863 a post-test loop:
864
865 do
866
867 {
868 body of the loop;
869 } while (lower bound < upper bound);
870
871 We create a new if region protecting the loop to be executed, if
872 the execution count is zero (lower bound > upper bound). */
873
050e1371
AK
874edge
875translate_isl_ast_to_gimple::
a78cfa7f
RG
876graphite_create_new_loop_guard (edge entry_edge,
877 __isl_keep isl_ast_node *node_for, tree *type,
878 tree *lb, tree *ub, ivs_params &ip)
879{
880 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
881 tree cond_expr;
882 edge exit_edge;
883
55d1bd59
RG
884 *type =
885 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
a78cfa7f
RG
886 isl_ast_expr *for_init = isl_ast_node_for_get_init (node_for);
887 *lb = gcc_expression_from_isl_expression (*type, for_init, ip);
888 isl_ast_expr *upper_bound = get_upper_bound (node_for);
889 *ub = gcc_expression_from_isl_expression (*type, upper_bound, ip);
890
891 /* When ub is simply a constant or a parameter, use lb <= ub. */
892 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
893 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
894 else
895 {
896 tree one = (POINTER_TYPE_P (*type)
897 ? convert_to_ptrofftype (integer_one_node)
898 : fold_convert (*type, integer_one_node));
899 /* Adding +1 and using LT_EXPR helps with loop latches that have a
900 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this
901 becomes 2^k-1 due to integer overflow, and the condition lb <= ub
902 is true, even if we do not want this. However lb < ub + 1 is false,
903 as expected. */
904 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
905 : PLUS_EXPR, *type, *ub, one);
906
907 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
908 }
909
77ec8b8c
AK
910 if (integer_onep (cond_expr))
911 exit_edge = entry_edge;
912 else
913 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
a78cfa7f
RG
914
915 return exit_edge;
916}
917
918/* Translates an isl_ast_node_for to Gimple. */
919
050e1371
AK
920edge
921translate_isl_ast_to_gimple::
a78cfa7f
RG
922translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
923 edge next_e, ivs_params &ip)
924{
925 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
926 tree type, lb, ub;
927 edge last_e = graphite_create_new_loop_guard (next_e, node, &type,
928 &lb, &ub, ip);
a78cfa7f 929
77ec8b8c
AK
930 if (last_e == next_e)
931 /* There was no guard generated. */
932 return translate_isl_ast_for_loop (context_loop, node, last_e,
933 type, lb, ub, ip);
934
935 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
936 translate_isl_ast_for_loop (context_loop, node, true_e, type, lb, ub, ip);
a78cfa7f
RG
937 return last_e;
938}
939
5493d313
RG
940/* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
941 variables of the loops around GBB in SESE.
942
943 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
944 chrec, we could consider using a map<int, tree> that maps loop ids to the
945 corresponding tree expressions. */
946
050e1371
AK
947void
948translate_isl_ast_to_gimple::
65ef70d6 949build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
5493d313 950 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
bafcb153 951 sese_l &region)
5493d313
RG
952{
953 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
050e1371 954 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
5493d313
RG
955 int i;
956 isl_ast_expr *arg_expr;
957 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
958 {
959 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
960 tree type =
050e1371 961 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
5493d313
RG
962 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
963 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
964 iv_map[old_loop->num] = t;
965 }
5493d313
RG
966}
967
968/* Translates an isl_ast_node_user to Gimple.
969
970 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
971
050e1371
AK
972edge
973translate_isl_ast_to_gimple::
5493d313
RG
974translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
975 edge next_e, ivs_params &ip)
976{
977 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
65b016eb 978
5493d313
RG
979 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
980 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
981 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
65b016eb 982
5493d313
RG
983 isl_id *name_id = isl_ast_expr_get_id (name_expr);
984 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
985 gcc_assert (pbb);
65b016eb 986
65ef70d6 987 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
65b016eb 988
5493d313
RG
989 isl_ast_expr_free (name_expr);
990 isl_id_free (name_id);
991
992 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
993 "The entry block should not even appear within a scop");
994
2ecf4eca 995 const int nb_loops = number_of_loops (cfun);
65b016eb 996 vec<tree> iv_map;
b5bdf598
RG
997 iv_map.create (nb_loops);
998 iv_map.safe_grow_cleared (nb_loops);
5493d313 999
d37fc3aa 1000 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
5493d313 1001 isl_ast_expr_free (user_expr);
1b38d3ec
AK
1002
1003 if (dump_file)
1004 {
65b016eb 1005 fprintf (dump_file, "[codegen] copying from basic block\n");
1b38d3ec 1006 print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
65b016eb
AK
1007 fprintf (dump_file, "\n[codegen] to new basic block\n");
1008 print_loops_bb (dump_file, next_e->src, 0, 3);
1b38d3ec
AK
1009 }
1010
2ecf4eca
AK
1011 next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), next_e,
1012 iv_map);
1013
1014 iv_map.release ();
1015
1016 if (codegen_error_p ())
65b016eb
AK
1017 return NULL;
1018
1b38d3ec
AK
1019 if (dump_file)
1020 {
65b016eb 1021 fprintf (dump_file, "\n[codegen] (after copy) new basic block\n");
1b38d3ec
AK
1022 print_loops_bb (dump_file, next_e->src, 0, 3);
1023 }
1024
5493d313
RG
1025 mark_virtual_operands_for_renaming (cfun);
1026 update_ssa (TODO_update_ssa);
65b016eb
AK
1027
1028 if (dump_file)
1029 {
1030 fprintf (dump_file, "\n[codegen] (after update SSA) new basic block\n");
1031 print_loops_bb (dump_file, next_e->src, 0, 3);
1032 }
1033
5493d313
RG
1034 return next_e;
1035}
1036
322a0b39
RG
1037/* Translates an isl_ast_node_block to Gimple. */
1038
050e1371
AK
1039edge
1040translate_isl_ast_to_gimple::
322a0b39
RG
1041translate_isl_ast_node_block (loop_p context_loop,
1042 __isl_keep isl_ast_node *node,
1043 edge next_e, ivs_params &ip)
1044{
1045 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
1046 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
1047 int i;
1048 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
1049 {
1050 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
1051 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
1052 isl_ast_node_free (tmp_node);
1053 }
1054 isl_ast_node_list_free (node_list);
1055 return next_e;
1056}
333cc518
RG
1057
1058/* Creates a new if region corresponding to ISL's cond. */
1059
050e1371
AK
1060edge
1061translate_isl_ast_to_gimple::
333cc518
RG
1062graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
1063 ivs_params &ip)
1064{
1065 tree type =
1066 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
1067 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
1068 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
1069 return exit_edge;
1070}
1071
1072/* Translates an isl_ast_node_if to Gimple. */
1073
050e1371
AK
1074edge
1075translate_isl_ast_to_gimple::
333cc518
RG
1076translate_isl_ast_node_if (loop_p context_loop,
1077 __isl_keep isl_ast_node *node,
1078 edge next_e, ivs_params &ip)
1079{
1080 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
1081 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
1082 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
1083
1084 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1085 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
1086 translate_isl_ast (context_loop, then_node, true_e, ip);
1087 isl_ast_node_free (then_node);
1088
1089 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
1090 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
1091 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
1092 translate_isl_ast (context_loop, else_node, false_e, ip);
1093 isl_ast_node_free (else_node);
1094 return last_e;
1095}
322a0b39 1096
a78cfa7f
RG
1097/* Translates an ISL AST node NODE to GCC representation in the
1098 context of a SESE. */
1099
050e1371
AK
1100edge
1101translate_isl_ast_to_gimple::translate_isl_ast (loop_p context_loop,
1102 __isl_keep isl_ast_node *node,
1103 edge next_e, ivs_params &ip)
a78cfa7f 1104{
2ecf4eca 1105 if (codegen_error_p ())
65b016eb
AK
1106 return NULL;
1107
a78cfa7f
RG
1108 switch (isl_ast_node_get_type (node))
1109 {
1110 case isl_ast_node_error:
1111 gcc_unreachable ();
1112
1113 case isl_ast_node_for:
1114 return translate_isl_ast_node_for (context_loop, node,
1115 next_e, ip);
1116
1117 case isl_ast_node_if:
333cc518
RG
1118 return translate_isl_ast_node_if (context_loop, node,
1119 next_e, ip);
a78cfa7f
RG
1120
1121 case isl_ast_node_user:
5493d313 1122 return translate_isl_ast_node_user (node, next_e, ip);
a78cfa7f
RG
1123
1124 case isl_ast_node_block:
322a0b39
RG
1125 return translate_isl_ast_node_block (context_loop, node,
1126 next_e, ip);
a78cfa7f
RG
1127
1128 default:
1129 gcc_unreachable ();
1130 }
1131}
1132
2ecf4eca
AK
1133/* Return true when BB contains loop close phi nodes. A loop close phi node is
1134 at the exit of loop which takes one argument that is the last value of the
1135 variable being used out of the loop. */
a78cfa7f 1136
2ecf4eca
AK
1137bool
1138bb_contains_loop_close_phi_nodes (basic_block bb)
f6cc3103 1139{
2ecf4eca
AK
1140 return single_pred_p (bb)
1141 && bb->loop_father != single_pred_edge (bb)->src->loop_father;
f6cc3103
RG
1142}
1143
2ecf4eca
AK
1144/* Return true when BB contains loop phi nodes. A loop phi node is the loop
1145 header containing phi nodes which has one init-edge and one back-edge. */
fb3764d1 1146
2ecf4eca
AK
1147bool
1148bb_contains_loop_phi_nodes (basic_block bb)
fb3764d1 1149{
2ecf4eca 1150 gcc_assert (EDGE_COUNT (bb->preds) <= 2);
fb3764d1 1151
2ecf4eca
AK
1152 if (bb->preds->length () == 1)
1153 return false;
fb3764d1 1154
2ecf4eca 1155 unsigned depth = loop_depth (bb->loop_father);
fb3764d1 1156
2ecf4eca 1157 edge preds[2] = { (*bb->preds)[0], (*bb->preds)[1] };
fb3764d1 1158
2ecf4eca
AK
1159 if (depth > loop_depth (preds[0]->src->loop_father)
1160 || depth > loop_depth (preds[1]->src->loop_father))
1161 return true;
fb3764d1 1162
2ecf4eca
AK
1163 /* When one of the edges correspond to the same loop father and other
1164 doesn't. */
1165 if (bb->loop_father != preds[0]->src->loop_father
1166 && bb->loop_father == preds[1]->src->loop_father)
1167 return true;
1168
1169 if (bb->loop_father != preds[1]->src->loop_father
1170 && bb->loop_father == preds[0]->src->loop_father)
1171 return true;
1172
1173 return false;
fb3764d1
RG
1174}
1175
2ecf4eca
AK
1176/* Check if USE is defined in a basic block from where the definition of USE can
1177 propagate from all the paths. FIXME: Verify checks for virtual operands. */
f6cc3103 1178
2ecf4eca
AK
1179static bool
1180is_loop_closed_ssa_use (basic_block bb, tree use)
f6cc3103 1181{
2ecf4eca
AK
1182 if (TREE_CODE (use) != SSA_NAME || virtual_operand_p (use))
1183 return true;
f6cc3103 1184
2ecf4eca
AK
1185 /* For close-phi nodes def always comes from a loop which has a back-edge. */
1186 if (bb_contains_loop_close_phi_nodes (bb))
1187 return true;
f6cc3103 1188
2ecf4eca
AK
1189 gimple *def = SSA_NAME_DEF_STMT (use);
1190 basic_block def_bb = gimple_bb (def);
1191 return (!def_bb
1192 || flow_bb_inside_loop_p (def_bb->loop_father, bb));
f6cc3103
RG
1193}
1194
2ecf4eca
AK
1195/* Return the number of phi nodes in BB. */
1196
1197static int
1198number_of_phi_nodes (basic_block bb)
574921c2 1199{
2ecf4eca
AK
1200 int num_phis = 0;
1201 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1202 gsi_next (&psi))
1203 num_phis++;
1204 return num_phis;
574921c2
RG
1205}
1206
2ecf4eca 1207/* Returns true if BB uses name in one of its PHIs. */
6a12a004 1208
2ecf4eca
AK
1209static bool
1210phi_uses_name (basic_block bb, tree name)
6a12a004 1211{
2ecf4eca
AK
1212 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1213 gsi_next (&psi))
1214 {
1215 gphi *phi = psi.phi ();
1216 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
1217 {
1218 tree use_arg = gimple_phi_arg_def (phi, i);
1219 if (use_arg == name)
1220 return true;
1221 }
1222 }
1223 return false;
6a12a004
RG
1224}
1225
2ecf4eca
AK
1226/* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
1227 definition should flow into use, and the use should respect the loop-closed
1228 SSA form. */
1229
1230bool
1231translate_isl_ast_to_gimple::
1232is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
1233 bool loop_phi, tree old_name, basic_block old_bb) const
f6cc3103 1234{
2ecf4eca
AK
1235 /* The def of the rename must either dominate the uses or come from a
1236 back-edge. Also the def must respect the loop closed ssa form. */
1237 if (!is_loop_closed_ssa_use (use_bb, rename))
1238 {
1239 if (dump_file)
1240 {
1241 fprintf (dump_file, "\n[codegen] rename not in loop closed ssa:");
1242 print_generic_expr (dump_file, rename, 0);
1243 }
1244 return false;
1245 }
a78cfa7f 1246
2ecf4eca
AK
1247 if (dominated_by_p (CDI_DOMINATORS, use_bb, def_bb))
1248 return true;
f6cc3103 1249
2ecf4eca
AK
1250 if (bb_contains_loop_phi_nodes (use_bb) && loop_phi)
1251 {
1252 /* The loop-header dominates the loop-body. */
1253 if (!dominated_by_p (CDI_DOMINATORS, def_bb, use_bb))
1254 return false;
1255
1256 /* RENAME would be used in loop-phi. */
1257 gcc_assert (number_of_phi_nodes (use_bb));
1258
1259 /* For definitions coming from back edges, we should check that
1260 old_name is used in a loop PHI node.
1261 FIXME: Verify if this is true. */
1262 if (phi_uses_name (old_bb, old_name))
1263 return true;
1264 }
1265 return false;
1266}
f6cc3103 1267
2ecf4eca
AK
1268/* Returns the expression associated to OLD_NAME (which is used in OLD_BB), in
1269 NEW_BB from RENAME_MAP. LOOP_PHI is true when we want to rename OLD_NAME
1270 within a loop PHI instruction. */
f6cc3103 1271
2ecf4eca
AK
1272tree
1273translate_isl_ast_to_gimple::get_rename (basic_block new_bb,
1274 tree old_name,
1275 basic_block old_bb,
1276 bool loop_phi) const
f6cc3103 1277{
2ecf4eca
AK
1278 gcc_assert (TREE_CODE (old_name) == SSA_NAME);
1279 vec <tree> *renames = region->rename_map->get (old_name);
a78cfa7f 1280
2ecf4eca
AK
1281 if (!renames || renames->is_empty ())
1282 return NULL_TREE;
a78cfa7f 1283
2ecf4eca 1284 if (1 == renames->length ())
f6cc3103 1285 {
2ecf4eca
AK
1286 tree rename = (*renames)[0];
1287 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (rename));
1288 if (is_valid_rename (rename, bb, new_bb, loop_phi, old_name, old_bb))
1289 return rename;
1290 return NULL_TREE;
f6cc3103 1291 }
a78cfa7f 1292
2ecf4eca
AK
1293 /* More than one renames corresponding to the old_name. Find the rename for
1294 which the definition flows into usage at new_bb. */
1295 int i;
1296 tree t1 = NULL_TREE, t2;
1297 basic_block t1_bb = NULL;
1298 FOR_EACH_VEC_ELT (*renames, i, t2)
1299 {
1300 basic_block t2_bb = gimple_bb (SSA_NAME_DEF_STMT (t2));
a78cfa7f 1301
2ecf4eca
AK
1302 /* Defined in the same basic block as used. */
1303 if (t2_bb == new_bb)
1304 return t2;
a78cfa7f 1305
2ecf4eca
AK
1306 /* NEW_BB and T2_BB are in two unrelated if-clauses. */
1307 if (!dominated_by_p (CDI_DOMINATORS, new_bb, t2_bb))
1308 continue;
1309
1310 /* Compute the nearest dominator. */
1311 if (!t1 || dominated_by_p (CDI_DOMINATORS, t2_bb, t1_bb))
1312 {
1313 t1_bb = t2_bb;
1314 t1 = t2;
1315 }
1316 }
1317
1318 return t1;
1319}
1320
1321/* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
1322 When OLD_NAME and EXPR are the same we assert. */
1323
1324void
1325translate_isl_ast_to_gimple::set_rename (tree old_name, tree expr)
1326{
1327 if (dump_file)
1328 {
1329 fprintf (dump_file, "\n[codegen] setting rename: old_name = ");
1330 print_generic_expr (dump_file, old_name, 0);
1331 fprintf (dump_file, ", new_name = ");
1332 print_generic_expr (dump_file, expr, 0);
1333 }
1334
1335 if (old_name == expr)
1336 return;
1337
1338 vec <tree> *renames = region->rename_map->get (old_name);
1339
1340 if (renames)
1341 renames->safe_push (expr);
1342 else
1343 {
1344 vec<tree> r;
1345 r.create (2);
1346 r.safe_push (expr);
1347 region->rename_map->put (old_name, r);
1348 }
1349}
1350
1351/* Return an iterator to the instructions comes last in the execution order.
1352 Either GSI1 and GSI2 should belong to the same basic block or one of their
1353 respective basic blocks should dominate the other. */
1354
1355gimple_stmt_iterator
1356later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
1357{
1358 basic_block bb1 = gsi_bb (gsi1);
1359 basic_block bb2 = gsi_bb (gsi2);
1360
1361 /* Find the iterator which is the latest. */
1362 if (bb1 == bb2)
1363 {
1364 /* For empty basic blocks gsis point to the end of the sequence. Since
1365 there is no operator== defined for gimple_stmt_iterator and for gsis
1366 not pointing to a valid statement gsi_next would assert. */
1367 gimple_stmt_iterator gsi = gsi1;
1368 do {
1369 if (gsi_stmt (gsi) == gsi_stmt (gsi2))
1370 return gsi2;
1371 gsi_next (&gsi);
1372 } while (!gsi_end_p (gsi));
1373
1374 return gsi1;
1375 }
1376
1377 /* Find the basic block closest to the basic block which defines stmt. */
1378 if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
1379 return gsi1;
1380
1381 gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
1382 return gsi2;
1383}
1384
1385/* Insert each statement from SEQ at its earliest insertion p. */
1386
1387void
1388translate_isl_ast_to_gimple::gsi_insert_earliest (gimple_seq seq)
1389{
1390 update_modified_stmts (seq);
1391 sese_l &codegen_region = region->if_region->true_region->region;
1392 basic_block begin_bb = get_entry_bb (codegen_region);
1393
1394 /* Inserting the gimple statements in a vector because gimple_seq behave
1395 in strage ways when inserting the stmts from it into different basic
1396 blocks one at a time. */
1397 auto_vec<gimple *, 3> stmts;
1398 for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
1399 gsi_next (&gsi))
1400 stmts.safe_push (gsi_stmt (gsi));
1401
1402 int i;
1403 gimple *use_stmt;
1404 FOR_EACH_VEC_ELT (stmts, i, use_stmt)
1405 {
1406 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1407 gimple_stmt_iterator gsi_def_stmt = gsi_start_bb_nondebug (begin_bb);
1408
1409 use_operand_p use_p;
1410 ssa_op_iter op_iter;
1411 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
1412 {
1413 /* Iterator to the current def of use_p. For function parameters or
1414 anything where def is not found, insert at the beginning of the
1415 generated region. */
1416 gimple_stmt_iterator gsi_stmt = gsi_def_stmt;
1417
1418 tree op = USE_FROM_PTR (use_p);
1419 gimple *stmt = SSA_NAME_DEF_STMT (op);
1420 if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
1421 gsi_stmt = gsi_for_stmt (stmt);
1422
1423 /* For region parameters, insert at the beginning of the generated
1424 region. */
1425 if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
1426 gsi_stmt = gsi_def_stmt;
1427
1428 gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
1429 }
1430
1431 if (!gsi_stmt (gsi_def_stmt))
1432 {
1433 gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
1434 gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
1435 }
1436 else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
1437 {
1438 gimple_stmt_iterator bsi
1439 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt));
1440 /* Insert right after the PHI statements. */
1441 gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
1442 }
1443 else
1444 gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);
1445
1446 if (dump_file)
1447 {
1448 fprintf (dump_file, "\n[codegen] inserting statement: ");
1449 print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
1450 print_loops_bb (dump_file, gimple_bb (use_stmt), 0, 3);
1451 }
1452 }
1453}
1454
1455/* Collect all the operands of NEW_EXPR by recursively visiting each
1456 operand. */
1457
1458void
1459translate_isl_ast_to_gimple::collect_all_ssa_names (tree new_expr,
1460 vec<tree> *vec_ssa)
1461{
1462
1463 /* Rename all uses in new_expr. */
1464 if (TREE_CODE (new_expr) == SSA_NAME)
1465 {
1466 vec_ssa->safe_push (new_expr);
1467 return;
1468 }
1469
1470 /* Iterate over SSA_NAMES in NEW_EXPR. */
1471 for (int i = 0; i < (TREE_CODE_LENGTH (TREE_CODE (new_expr))); i++)
1472 {
1473 tree op = TREE_OPERAND (new_expr, i);
1474 collect_all_ssa_names (op, vec_ssa);
1475 }
1476}
1477
1478/* This is abridged version of the function:
1479 tree.c:substitute_in_expr (tree exp, tree f, tree r). */
1480
1481static tree
1482substitute_ssa_name (tree exp, tree f, tree r)
1483{
1484 enum tree_code code = TREE_CODE (exp);
1485 tree op0, op1, op2, op3;
1486 tree new_tree;
1487
1488 /* We handle TREE_LIST and COMPONENT_REF separately. */
1489 if (code == TREE_LIST)
1490 {
1491 op0 = substitute_ssa_name (TREE_CHAIN (exp), f, r);
1492 op1 = substitute_ssa_name (TREE_VALUE (exp), f, r);
1493 if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
1494 return exp;
1495
1496 return tree_cons (TREE_PURPOSE (exp), op1, op0);
1497 }
1498 else if (code == COMPONENT_REF)
1499 {
1500 tree inner;
1501
1502 /* If this expression is getting a value from a PLACEHOLDER_EXPR
1503 and it is the right field, replace it with R. */
1504 for (inner = TREE_OPERAND (exp, 0);
1505 REFERENCE_CLASS_P (inner);
1506 inner = TREE_OPERAND (inner, 0))
1507 ;
1508
1509 /* The field. */
1510 op1 = TREE_OPERAND (exp, 1);
1511
1512 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
1513 return r;
1514
1515 /* If this expression hasn't been completed let, leave it alone. */
1516 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
1517 return exp;
1518
1519 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1520 if (op0 == TREE_OPERAND (exp, 0))
1521 return exp;
1522
1523 new_tree
1524 = fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
1525 }
1526 else
1527 switch (TREE_CODE_CLASS (code))
1528 {
1529 case tcc_constant:
1530 return exp;
1531
1532 case tcc_declaration:
1533 if (exp == f)
1534 return r;
1535 else
1536 return exp;
1537
1538 case tcc_expression:
1539 if (exp == f)
1540 return r;
1541
1542 /* Fall through... */
1543
1544 case tcc_exceptional:
1545 case tcc_unary:
1546 case tcc_binary:
1547 case tcc_comparison:
1548 case tcc_reference:
1549 switch (TREE_CODE_LENGTH (code))
1550 {
1551 case 0:
1552 if (exp == f)
1553 return r;
1554 return exp;
1555
1556 case 1:
1557 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1558 if (op0 == TREE_OPERAND (exp, 0))
1559 return exp;
1560
1561 new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
1562 break;
1563
1564 case 2:
1565 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1566 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1567
1568 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
1569 return exp;
1570
1571 new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
1572 break;
1573
1574 case 3:
1575 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1576 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1577 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1578
1579 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1580 && op2 == TREE_OPERAND (exp, 2))
1581 return exp;
1582
1583 new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
1584 break;
1585
1586 case 4:
1587 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1588 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1589 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1590 op3 = substitute_ssa_name (TREE_OPERAND (exp, 3), f, r);
1591
1592 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1593 && op2 == TREE_OPERAND (exp, 2)
1594 && op3 == TREE_OPERAND (exp, 3))
1595 return exp;
1596
1597 new_tree
1598 = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
1599 break;
1600
1601 default:
1602 gcc_unreachable ();
1603 }
1604 break;
1605
1606 case tcc_vl_exp:
1607 default:
1608 gcc_unreachable ();
1609 }
1610
1611 TREE_READONLY (new_tree) |= TREE_READONLY (exp);
1612
1613 if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
1614 TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
1615
1616 return new_tree;
1617}
1618
1619/* Rename all the operands of NEW_EXPR by recursively visiting each operand. */
1620
1621tree
1622translate_isl_ast_to_gimple::rename_all_uses (tree new_expr, basic_block new_bb,
1623 basic_block old_bb)
1624{
1625 auto_vec<tree, 2> ssa_names;
1626 collect_all_ssa_names (new_expr, &ssa_names);
1627 tree t;
1628 int i;
1629 FOR_EACH_VEC_ELT (ssa_names, i, t)
1630 if (tree r = get_rename (new_bb, t, old_bb, false))
1631 new_expr = substitute_ssa_name (new_expr, t, r);
1632
1633 return new_expr;
1634}
1635
2927ca4b
AK
1636/* For ops which are scev_analyzeable, we can regenerate a new name from its
1637 scalar evolution around LOOP. */
2ecf4eca
AK
1638
1639tree
1640translate_isl_ast_to_gimple::
1641get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
1642 basic_block new_bb, basic_block old_bb,
1643 vec<tree> iv_map)
1644{
1645 tree scev = scalar_evolution_in_region (region->region, loop, old_name);
1646
1647 /* At this point we should know the exact scev for each
1648 scalar SSA_NAME used in the scop: all the other scalar
1649 SSA_NAMEs should have been translated out of SSA using
1650 arrays with one element. */
1651 tree new_expr;
1652 if (chrec_contains_undetermined (scev))
1653 {
1654 codegen_error = true;
1655 return build_zero_cst (TREE_TYPE (old_name));
1656 }
1657
1658 new_expr = chrec_apply_map (scev, iv_map);
1659
1660 /* The apply should produce an expression tree containing
1661 the uses of the new induction variables. We should be
1662 able to use new_expr instead of the old_name in the newly
1663 generated loop nest. */
1664 if (chrec_contains_undetermined (new_expr)
1665 || tree_contains_chrecs (new_expr, NULL))
1666 {
1667 codegen_error = true;
1668 return build_zero_cst (TREE_TYPE (old_name));
1669 }
1670
1671 /* We should check all the operands and all of them should dominate the use at
1672 new_expr. */
1673 if (TREE_CODE (new_expr) == SSA_NAME)
1674 {
1675 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_expr));
1676 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1677 {
2ecf4eca 1678 codegen_error = true;
2ecf4eca
AK
1679 return build_zero_cst (TREE_TYPE (old_name));
1680 }
1681 }
1682
1683 new_expr = rename_all_uses (new_expr, new_bb, old_bb);
1684 /* We should check all the operands and all of them should dominate the use at
1685 new_expr. */
1686 if (TREE_CODE (new_expr) == SSA_NAME)
1687 {
1688 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_expr));
1689 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1690 {
2ecf4eca 1691 codegen_error = true;
2ecf4eca
AK
1692 return build_zero_cst (TREE_TYPE (old_name));
1693 }
1694 }
1695
1696 /* Replace the old_name with the new_expr. */
1697 return force_gimple_operand (unshare_expr (new_expr), stmts,
1698 true, NULL_TREE);
1699}
1700
1701/* Renames the scalar uses of the statement COPY, using the
1702 substitution map RENAME_MAP, inserting the gimplification code at
1703 GSI_TGT, for the translation REGION, with the original copied
1704 statement in LOOP, and using the induction variable renaming map
1705 IV_MAP. Returns true when something has been renamed. codegen_error
1706 is set when the code generation cannot continue. */
1707
1708bool
1709translate_isl_ast_to_gimple::rename_uses (gimple *copy,
1710 gimple_stmt_iterator *gsi_tgt,
1711 basic_block old_bb,
1712 loop_p loop, vec<tree> iv_map)
1713{
1714 bool changed = false;
1715
1716 if (is_gimple_debug (copy))
1717 {
1718 if (gimple_debug_bind_p (copy))
1719 gimple_debug_bind_reset_value (copy);
1720 else if (gimple_debug_source_bind_p (copy))
1721 return false;
1722 else
1723 gcc_unreachable ();
1724
1725 return false;
1726 }
1727
1728 if (dump_file)
1729 {
1730 fprintf (dump_file, "\n[codegen] renaming uses of stmt: ");
1731 print_gimple_stmt (dump_file, copy, 0, 0);
1732 }
1733
1734 use_operand_p use_p;
1735 ssa_op_iter op_iter;
1736 FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_USE)
1737 {
1738 tree old_name = USE_FROM_PTR (use_p);
1739
1740 if (dump_file)
1741 {
1742 fprintf (dump_file, "\n[codegen] renaming old_name = ");
1743 print_generic_expr (dump_file, old_name, 0);
1744 }
1745
1746 if (TREE_CODE (old_name) != SSA_NAME
1747 || SSA_NAME_IS_DEFAULT_DEF (old_name))
1748 continue;
1749
1750 changed = true;
1751 tree new_expr = get_rename (gsi_tgt->bb, old_name,
1752 old_bb, false);
1753
1754 if (new_expr)
1755 {
1756 tree type_old_name = TREE_TYPE (old_name);
1757 tree type_new_expr = TREE_TYPE (new_expr);
1758
1759 if (dump_file)
1760 {
1761 fprintf (dump_file, "\n[codegen] from rename_map: new_name = ");
1762 print_generic_expr (dump_file, new_expr, 0);
1763 }
1764
1765 if (type_old_name != type_new_expr
1766 || TREE_CODE (new_expr) != SSA_NAME)
1767 {
1768 tree var = create_tmp_var (type_old_name, "var");
1769
1770 if (!useless_type_conversion_p (type_old_name, type_new_expr))
1771 new_expr = fold_convert (type_old_name, new_expr);
1772
1773 gimple_seq stmts;
1774 new_expr = force_gimple_operand (new_expr, &stmts, true, var);
1775 gsi_insert_earliest (stmts);
1776 }
1777
1778 replace_exp (use_p, new_expr);
1779 continue;
1780 }
1781
1782 gimple_seq stmts;
1783 new_expr = get_rename_from_scev (old_name, &stmts, loop, gimple_bb (copy),
1784 old_bb, iv_map);
1785 if (!new_expr || codegen_error_p ())
1786 return false;
1787
1788 if (dump_file)
1789 {
1790 fprintf (dump_file, "\n[codegen] not in rename map, scev: ");
1791 print_generic_expr (dump_file, new_expr, 0);
1792 }
1793
1794 gsi_insert_earliest (stmts);
1795 replace_exp (use_p, new_expr);
1796
1797 if (TREE_CODE (new_expr) == INTEGER_CST
1798 && is_gimple_assign (copy))
1799 {
1800 tree rhs = gimple_assign_rhs1 (copy);
1801
1802 if (TREE_CODE (rhs) == ADDR_EXPR)
1803 recompute_tree_invariant_for_addr_expr (rhs);
1804 }
1805
1806 set_rename (old_name, new_expr);
1807 }
1808
1809 return changed;
1810}
1811
1812/* Returns a basic block that could correspond to where a constant was defined
1813 in the original code. In the original code OLD_BB had the definition, we
1814 need to find which basic block out of the copies of old_bb, in the new
1815 region, should a definition correspond to if it has to reach BB. */
1816
1817basic_block
1818translate_isl_ast_to_gimple::get_def_bb_for_const (basic_block bb,
1819 basic_block old_bb) const
1820{
1821 vec <basic_block> *bbs = region->copied_bb_map->get (old_bb);
1822
1823 if (!bbs || bbs->is_empty ())
1824 return NULL;
1825
1826 if (1 == bbs->length ())
1827 return (*bbs)[0];
1828
1829 int i;
1830 basic_block b1 = NULL, b2;
1831 FOR_EACH_VEC_ELT (*bbs, i, b2)
1832 {
1833 if (b2 == bb)
1834 return bb;
1835
1836 /* BB and B2 are in two unrelated if-clauses. */
1837 if (!dominated_by_p (CDI_DOMINATORS, bb, b2))
1838 continue;
1839
1840 /* Compute the nearest dominator. */
1841 if (!b1 || dominated_by_p (CDI_DOMINATORS, b2, b1))
1842 b1 = b2;
1843 }
1844
1845 gcc_assert (b1);
1846 return b1;
1847}
1848
1849/* Get the new name of OP (from OLD_BB) to be used in NEW_BB. LOOP_PHI is true
1850 when we want to rename an OP within a loop PHI instruction. */
1851
1852tree
1853translate_isl_ast_to_gimple::
1854get_new_name (basic_block new_bb, tree op,
1855 basic_block old_bb, bool loop_phi) const
1856{
1857 /* For constants the names are the same. */
1858 if (TREE_CODE (op) == INTEGER_CST
1859 || TREE_CODE (op) == REAL_CST
1860 || TREE_CODE (op) == COMPLEX_CST
1861 || TREE_CODE (op) == VECTOR_CST)
1862 return op;
1863
1864 return get_rename (new_bb, op, old_bb, loop_phi);
1865}
1866
1867/* Return a debug location for OP. */
1868
1869static location_t
1870get_loc (tree op)
1871{
1872 location_t loc = UNKNOWN_LOCATION;
1873
1874 if (TREE_CODE (op) == SSA_NAME)
1875 loc = gimple_location (SSA_NAME_DEF_STMT (op));
1876 return loc;
1877}
1878
1879/* Returns the incoming edges of basic_block BB in the pair. The first edge is
1880 the init edge (from outside the loop) and the second one is the back edge
1881 from the same loop. */
1882
1883std::pair<edge, edge>
1884get_edges (basic_block bb)
1885{
1886 std::pair<edge, edge> edges;
1887 edge e;
1888 edge_iterator ei;
1889 FOR_EACH_EDGE (e, ei, bb->preds)
1890 if (bb->loop_father != e->src->loop_father)
1891 edges.first = e;
1892 else
1893 edges.second = e;
1894 return edges;
1895}
1896
1897/* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI
1898 must be found unless they can be POSTPONEd for later. */
1899
21c7259c 1900bool
2ecf4eca
AK
1901translate_isl_ast_to_gimple::
1902copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
1903 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
1904 bool postpone)
1905{
1906 gcc_assert (gimple_phi_num_args (old_phi) == gimple_phi_num_args (new_phi));
1907
1908 basic_block new_bb = gimple_bb (new_phi);
1909 for (unsigned i = 0; i < gimple_phi_num_args (old_phi); i++)
1910 {
1911 edge e;
1912 if (gimple_phi_arg_edge (old_phi, i) == ibp_old_bb.first)
1913 e = ibp_new_bb.first;
1914 else
1915 e = ibp_new_bb.second;
1916
1917 tree old_name = gimple_phi_arg_def (old_phi, i);
1918 tree new_name = get_new_name (new_bb, old_name,
1919 gimple_bb (old_phi), true);
1920 if (new_name)
1921 {
1922 add_phi_arg (new_phi, new_name, e, get_loc (old_name));
1923 continue;
1924 }
1925
1926 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
1927 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
1928 /* If the phi arg was a function arg, or wasn't defined, just use the
1929 old name. */
1930 add_phi_arg (new_phi, old_name, e, get_loc (old_name));
1931 else if (postpone)
1932 {
1933 /* Postpone code gen for later for those back-edges we don't have the
1934 names yet. */
1935 region->incomplete_phis.safe_push (std::make_pair (old_phi, new_phi));
1936 if (dump_file)
1937 fprintf (dump_file, "\n[codegen] postpone loop phi nodes: ");
1938 }
1939 else
1940 /* Either we should add the arg to phi or, we should postpone. */
21c7259c 1941 return false;
2ecf4eca 1942 }
21c7259c 1943 return true;
2ecf4eca
AK
1944}
1945
1946/* Copy loop phi nodes from BB to NEW_BB. */
1947
1948bool
1949translate_isl_ast_to_gimple::copy_loop_phi_nodes (basic_block bb,
1950 basic_block new_bb)
1951{
1952 if (dump_file)
1953 fprintf (dump_file, "\n[codegen] copying loop phi nodes in bb_%d.",
1954 new_bb->index);
1955
1956 /* Loop phi nodes should have only two arguments. */
1957 gcc_assert (2 == EDGE_COUNT (bb->preds));
1958
1959 /* First edge is the init edge and second is the back edge. */
1960 init_back_edge_pair_t ibp_old_bb = get_edges (bb);
1961
1962 /* First edge is the init edge and second is the back edge. */
1963 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
1964
1965 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1966 gsi_next (&psi))
1967 {
1968 gphi *phi = psi.phi ();
1969 tree res = gimple_phi_result (phi);
1970 if (virtual_operand_p (res))
1971 continue;
1972 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
1973 continue;
1974
1975 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
1976 tree new_res = create_new_def_for (res, new_phi,
1977 gimple_phi_result_ptr (new_phi));
1978 set_rename (res, new_res);
21c7259c
AK
1979 codegen_error = !copy_loop_phi_args (phi, ibp_old_bb, new_phi,
1980 ibp_new_bb, true);
2ecf4eca
AK
1981 update_stmt (new_phi);
1982 }
1983
1984 return true;
1985}
1986
1987/* Return the init value of PHI, the value coming from outside the loop. */
1988
1989static tree
1990get_loop_init_value (gphi *phi)
1991{
1992
1993 loop_p loop = gimple_bb (phi)->loop_father;
1994
1995 edge e;
1996 edge_iterator ei;
1997 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
1998 if (e->src->loop_father != loop)
1999 return gimple_phi_arg_def (phi, e->dest_idx);
2000
2001 return NULL_TREE;
2002}
2003
2004/* Find the init value (the value which comes from outside the loop), of one of
2005 the operands of DEF which is defined by a loop phi. */
2006
2007static tree
2008find_init_value (gimple *def)
2009{
2010 if (gimple_code (def) == GIMPLE_PHI)
2011 return get_loop_init_value (as_a <gphi*> (def));
2012
2013 if (gimple_vuse (def))
2014 return NULL_TREE;
2015
2016 ssa_op_iter iter;
2017 use_operand_p use_p;
2018 FOR_EACH_SSA_USE_OPERAND (use_p, def, iter, SSA_OP_USE)
2019 {
2020 tree use = USE_FROM_PTR (use_p);
2021 if (TREE_CODE (use) == SSA_NAME)
2022 {
2023 if (tree res = find_init_value (SSA_NAME_DEF_STMT (use)))
2024 return res;
2025 }
2026 }
2027
2028 return NULL_TREE;
2029}
2030
2031/* Return the init value, the value coming from outside the loop. */
2032
2033static tree
2034find_init_value_close_phi (gphi *phi)
2035{
2036 gcc_assert (gimple_phi_num_args (phi) == 1);
2037 tree use_arg = gimple_phi_arg_def (phi, 0);
2038 gimple *def = SSA_NAME_DEF_STMT (use_arg);
2039 return find_init_value (def);
2040}
2041
2042/* Copy all the loop-close phi args from BB to NEW_BB. */
2043
2044bool
2045translate_isl_ast_to_gimple::copy_loop_close_phi_args (basic_block old_bb,
2046 basic_block new_bb,
2047 bool postpone)
2048{
2049 /* The successor of bb having close phi should be a merge of the diamond
2050 inserted to guard the loop during codegen. */
2927ca4b 2051 basic_block succ_new_bb = single_succ (new_bb);
2ecf4eca
AK
2052
2053 for (gphi_iterator psi = gsi_start_phis (old_bb); !gsi_end_p (psi);
2054 gsi_next (&psi))
2055 {
2056 gphi *phi = psi.phi ();
2057 tree res = gimple_phi_result (phi);
2058 if (virtual_operand_p (res))
2059 continue;
2060
2061 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2062 /* Loop close phi nodes should not be scev_analyzable_p. */
2063 gcc_unreachable ();
2064
2065 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
2066 tree new_res = create_new_def_for (res, new_phi,
2067 gimple_phi_result_ptr (new_phi));
2068 set_rename (res, new_res);
2069
2070 tree old_name = gimple_phi_arg_def (phi, 0);
2071 tree new_name = get_new_name (new_bb, old_name, old_bb, false);
2072
2073 /* Predecessor basic blocks of a loop close phi should have been code
2074 generated before. FIXME: This is fixable by merging PHIs from inner
2075 loops as well. See: gfortran.dg/graphite/interchange-3.f90. */
2076 if (!new_name)
2077 return false;
2078
2079 add_phi_arg (new_phi, new_name, single_pred_edge (new_bb),
2080 get_loc (old_name));
2081 if (dump_file)
2082 {
2083 fprintf (dump_file, "\n[codegen] Adding loop-closed phi: ");
2084 print_gimple_stmt (dump_file, new_phi, 0, 0);
2085 }
2086
2087 update_stmt (new_phi);
2088
2089 /* When there is no loop guard around this codegenerated loop, there is no
2090 need to collect the close-phi arg. */
2927ca4b
AK
2091 if (2 != EDGE_COUNT (succ_new_bb->preds)
2092 || bb_contains_loop_phi_nodes (succ_new_bb))
2ecf4eca
AK
2093 continue;
2094
2927ca4b 2095 /* Add a PHI in the succ_new_bb for each close phi of the loop. */
2ecf4eca
AK
2096 tree init = find_init_value_close_phi (new_phi);
2097
2098 /* A close phi must come from a loop-phi having an init value. */
2099 if (!init)
2100 {
21c7259c
AK
2101 if (!postpone)
2102 return false;
2103
2ecf4eca
AK
2104 region->incomplete_phis.safe_push (std::make_pair (phi, new_phi));
2105 if (dump_file)
2106 {
2107 fprintf (dump_file, "\n[codegen] postpone close phi nodes: ");
2108 print_gimple_stmt (dump_file, new_phi, 0, 0);
2109 }
2110 continue;
2111 }
2112
2927ca4b 2113 gphi *merge_phi = create_phi_node (SSA_NAME_VAR (res), succ_new_bb);
2ecf4eca
AK
2114 tree merge_res = create_new_def_for (res, merge_phi,
2115 gimple_phi_result_ptr (merge_phi));
2116 set_rename (res, merge_res);
2117
2118 edge from_loop = single_succ_edge (new_bb);
2119 add_phi_arg (merge_phi, new_res, from_loop, get_loc (old_name));
2120
2121 /* The edge coming from loop guard. */
2927ca4b
AK
2122 edge other = from_loop == (*succ_new_bb->preds)[0]
2123 ? (*succ_new_bb->preds)[1] : (*succ_new_bb->preds)[0];
2ecf4eca
AK
2124
2125 add_phi_arg (merge_phi, init, other, get_loc (old_name));
2126 if (dump_file)
2127 {
2128 fprintf (dump_file, "\n[codegen] Adding guard-phi: ");
2129 print_gimple_stmt (dump_file, merge_phi, 0, 0);
2130 }
2131
2132 update_stmt (new_phi);
2133 }
2134
2135 return true;
2136}
2137
2138/* Copy loop close phi nodes from BB to NEW_BB. */
2139
2140bool
2141translate_isl_ast_to_gimple::copy_loop_close_phi_nodes (basic_block old_bb,
2142 basic_block new_bb)
2143{
2144 if (dump_file)
2145 fprintf (dump_file, "\n[codegen] copying loop closed phi nodes in bb_%d.",
2146 new_bb->index);
2147 /* Loop close phi nodes should have only one argument. */
2148 gcc_assert (1 == EDGE_COUNT (old_bb->preds));
2149
2150 return copy_loop_close_phi_args (old_bb, new_bb, true);
2151}
2152
2153
2154/* Add NEW_NAME as the ARGNUM-th arg of NEW_PHI which is in NEW_BB.
2155 DOMINATING_PRED is the predecessor basic block of OLD_BB which dominates the
2156 other pred of OLD_BB as well. If no such basic block exists then it is NULL.
2157 NON_DOMINATING_PRED is a pred which does not dominate OLD_BB, it cannot be
2158 NULL.
2159
2160 Case1: OLD_BB->preds {BB1, BB2} and BB1 does not dominate BB2 and vice versa.
2161 In this case DOMINATING_PRED = NULL.
2162
2163 Case2: OLD_BB->preds {BB1, BB2} and BB1 dominates BB2.
2164
2165 Returns true on successful copy of the args, false otherwise. */
2166
2167bool
2168translate_isl_ast_to_gimple::
2169add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
2170 edge old_bb_dominating_edge,
2171 edge old_bb_non_dominating_edge,
2172 gphi *phi, gphi *new_phi,
2173 basic_block new_bb)
2174{
21c7259c 2175 basic_block def_pred[2] = { NULL, NULL };
2ecf4eca
AK
2176 int not_found_bb_index = -1;
2177 for (int i = 0; i < 2; i++)
2178 {
2179 /* If the corresponding def_bb could not be found the entry will be
2180 NULL. */
2181 if (TREE_CODE (old_phi_args[i]) == INTEGER_CST)
2182 def_pred[i] = get_def_bb_for_const (new_bb,
2183 gimple_phi_arg_edge (phi, i)->src);
21c7259c 2184 else if (new_phi_args[i] && (TREE_CODE (new_phi_args[i]) == SSA_NAME))
2ecf4eca 2185 def_pred[i] = gimple_bb (SSA_NAME_DEF_STMT (new_phi_args[i]));
21c7259c 2186
2ecf4eca
AK
2187 if (!def_pred[i])
2188 {
21c7259c
AK
2189 /* When non are available bail out. */
2190 if (not_found_bb_index != -1)
2191 return false;
2ecf4eca
AK
2192 not_found_bb_index = i;
2193 }
2194 }
2195
2196 /* Here we are pattern matching on the structure of CFG w.r.t. old one. */
2197 if (old_bb_dominating_edge)
2198 {
21c7259c
AK
2199 if (not_found_bb_index != -1)
2200 return false;
2201
2ecf4eca
AK
2202 basic_block new_pred1 = (*new_bb->preds)[0]->src;
2203 basic_block new_pred2 = (*new_bb->preds)[1]->src;
2204 vec <basic_block> *bbs
2205 = region->copied_bb_map->get (old_bb_non_dominating_edge->src);
21c7259c
AK
2206
2207 /* Could not find a mapping. */
2208 if (!bbs)
2209 return false;
2210
2ecf4eca
AK
2211 basic_block new_pred = NULL;
2212 basic_block b;
2213 int i;
2214 FOR_EACH_VEC_ELT (*bbs, i, b)
21c7259c
AK
2215 {
2216 if (dominated_by_p (CDI_DOMINATORS, new_pred1, b))
2217 {
2218 /* FIXME: If we have already found new_pred then we have to
2219 disambiguate, bail out for now. */
2220 if (new_pred)
2221 return false;
2222 new_pred = new_pred1;
2223 }
2224 if (dominated_by_p (CDI_DOMINATORS, new_pred2, b))
2225 {
2226 /* FIXME: If we have already found new_pred then we have to either
2227 it dominates both or we have to disambiguate, bail out. */
2228 if (new_pred)
2229 return false;
2230 new_pred = new_pred2;
2231 }
2232 }
2ecf4eca 2233
21c7259c
AK
2234 if (!new_pred)
2235 return false;
2ecf4eca
AK
2236
2237 edge new_non_dominating_edge = find_edge (new_pred, new_bb);
21c7259c
AK
2238 gcc_assert (new_non_dominating_edge);
2239 /* FIXME: Validate each args just like in loop-phis. */
2ecf4eca
AK
2240 /* By the process of elimination we first insert insert phi-edge for
2241 non-dominating pred which is computed above and then we insert the
2242 remaining one. */
2243 int inserted_edge = 0;
2244 for (; inserted_edge < 2; inserted_edge++)
2245 {
21c7259c 2246 edge new_bb_pred_edge = gimple_phi_arg_edge (new_phi, inserted_edge);
2ecf4eca
AK
2247 if (new_non_dominating_edge == new_bb_pred_edge)
2248 {
2249 add_phi_arg (new_phi, new_phi_args[inserted_edge],
2250 new_non_dominating_edge,
2251 get_loc (old_phi_args[inserted_edge]));
2252 break;
2253 }
2254 }
21c7259c
AK
2255 if (inserted_edge == 2)
2256 return false;
2ecf4eca 2257
21c7259c 2258 int edge_dominating = inserted_edge == 0 ? 1 : 0;
2ecf4eca
AK
2259
2260 edge new_dominating_edge = NULL;
21c7259c 2261 for (inserted_edge = 0; inserted_edge < 2; inserted_edge++)
2ecf4eca 2262 {
21c7259c 2263 edge e = gimple_phi_arg_edge (new_phi, inserted_edge);
2ecf4eca 2264 if (e != new_non_dominating_edge)
21c7259c
AK
2265 {
2266 new_dominating_edge = e;
2267 add_phi_arg (new_phi, new_phi_args[edge_dominating],
2268 new_dominating_edge,
2269 get_loc (old_phi_args[inserted_edge]));
2270 break;
2271 }
2ecf4eca 2272 }
21c7259c 2273 gcc_assert (new_dominating_edge);
2ecf4eca
AK
2274 }
2275 else
2276 {
2277 /* Classic diamond structure: both edges are non-dominating. We need to
2278 find one unique edge then the other can be found be elimination. If
2279 any definition (def_pred) dominates both the preds of new_bb then we
2280 bail out. Entries of def_pred maybe NULL, in that case we must
2281 uniquely find pred with help of only one entry. */
2282 edge new_e[2] = { NULL, NULL };
2283 for (int i = 0; i < 2; i++)
2284 {
2285 edge e;
2286 edge_iterator ei;
2287 FOR_EACH_EDGE (e, ei, new_bb->preds)
2288 if (def_pred[i]
2289 && dominated_by_p (CDI_DOMINATORS, e->src, def_pred[i]))
2290 {
2291 if (new_e[i])
2292 /* We do not know how to handle the case when def_pred
2293 dominates more than a predecessor. */
2294 return false;
2295 new_e[i] = e;
2296 }
2297 }
2298
2299 gcc_assert (new_e[0] || new_e[1]);
2300
2301 /* Find the other edge by process of elimination. */
2302 if (not_found_bb_index != -1)
2303 {
2304 gcc_assert (!new_e[not_found_bb_index]);
2305 int found_bb_index = not_found_bb_index == 1 ? 0 : 1;
2306 edge e;
2307 edge_iterator ei;
2308 FOR_EACH_EDGE (e, ei, new_bb->preds)
2309 {
2310 if (new_e[found_bb_index] == e)
2311 continue;
2312 new_e[not_found_bb_index] = e;
2313 }
2314 }
2315
2316 /* Add edges to phi args. */
2317 for (int i = 0; i < 2; i++)
2318 add_phi_arg (new_phi, new_phi_args[i], new_e[i],
2319 get_loc (old_phi_args[i]));
2320 }
2321
2322 return true;
2323}
2324
2325/* Copy the arguments of cond-phi node PHI, to NEW_PHI in the codegenerated
2326 region. If postpone is true and it isn't possible to copy any arg of PHI,
2327 the PHI is added to the REGION->INCOMPLETE_PHIS to be codegenerated later.
2328 Returns false if the copying was unsuccessful. */
2329
2330bool
2331translate_isl_ast_to_gimple::copy_cond_phi_args (gphi *phi, gphi *new_phi,
2332 vec<tree> iv_map,
2333 bool postpone)
2334{
2335 if (dump_file)
2336 fprintf (dump_file, "\n[codegen] copying cond phi args: ");
2337 gcc_assert (2 == gimple_phi_num_args (phi));
2338
2339 basic_block new_bb = gimple_bb (new_phi);
2340 loop_p loop = gimple_bb (phi)->loop_father;
2341
2342 basic_block old_bb = gimple_bb (phi);
2343 edge old_bb_non_dominating_edge = NULL, old_bb_dominating_edge = NULL;
2344
2345 edge e;
2346 edge_iterator ei;
2347 FOR_EACH_EDGE (e, ei, old_bb->preds)
2348 if (!dominated_by_p (CDI_DOMINATORS, old_bb, e->src))
2349 old_bb_non_dominating_edge = e;
2350 else
2351 old_bb_dominating_edge = e;
2352
2353 gcc_assert (!dominated_by_p (CDI_DOMINATORS, old_bb,
2354 old_bb_non_dominating_edge->src));
2355
2356 tree new_phi_args[2];
2357 tree old_phi_args[2];
2358
2359 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
2360 {
2361 tree old_name = gimple_phi_arg_def (phi, i);
2362 tree new_name = get_new_name (new_bb, old_name, old_bb, false);
2363 old_phi_args[i] = old_name;
2364 if (new_name)
2365 {
2366 new_phi_args [i] = new_name;
2367 continue;
2368 }
2369
2370 /* If the phi-arg was a parameter. */
21c7259c 2371 if (vec_find (region->params, old_name) != -1)
2ecf4eca
AK
2372 {
2373 new_phi_args [i] = old_name;
2374 if (dump_file)
2375 {
2376 fprintf (dump_file,
2377 "\n[codegen] parameter argument to phi, new_expr: ");
21c7259c 2378 print_generic_expr (dump_file, new_phi_args[i], 0);
2ecf4eca
AK
2379 }
2380 continue;
2381 }
2382
21c7259c
AK
2383 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
2384 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
2385 /* FIXME: If the phi arg was a function arg, or wasn't defined, just use
2386 the old name. */
2387 return false;
2ecf4eca 2388
21c7259c
AK
2389 if (postpone)
2390 {
2391 /* If the phi-arg is scev-analyzeable but only in the first stage. */
2392 if (is_gimple_reg (old_name)
2393 && scev_analyzable_p (old_name, region->region))
2ecf4eca 2394 {
21c7259c
AK
2395 gimple_seq stmts;
2396 tree new_expr = get_rename_from_scev (old_name, &stmts, loop,
2397 new_bb, old_bb, iv_map);
2398 if (codegen_error_p ())
2399 return false;
2400
2401 gcc_assert (new_expr);
2402 if (dump_file)
2403 {
2404 fprintf (dump_file,
2405 "\n[codegen] scev analyzeable, new_expr: ");
2406 print_generic_expr (dump_file, new_expr, 0);
2407 }
2408 gsi_insert_earliest (stmts);
2409 new_phi_args [i] = new_name;
2410 continue;
2ecf4eca 2411 }
2ecf4eca 2412
2ecf4eca
AK
2413 /* Postpone code gen for later for back-edges. */
2414 region->incomplete_phis.safe_push (std::make_pair (phi, new_phi));
2415
2416 if (dump_file)
2417 {
2418 fprintf (dump_file, "\n[codegen] postpone cond phi nodes: ");
2419 print_gimple_stmt (dump_file, new_phi, 0, 0);
2420 }
2421
2422 new_phi_args [i] = NULL_TREE;
2423 continue;
2424 }
2425 else
21c7259c
AK
2426 /* Either we should add the arg to phi or, we should postpone. */
2427 return false;
2ecf4eca
AK
2428 }
2429
21c7259c
AK
2430 /* If none of the args have been determined in the first stage then wait until
2431 later. */
2432 if (postpone && !new_phi_args[0] && !new_phi_args[1])
2433 return true;
2434
2ecf4eca
AK
2435 return add_phi_arg_for_new_expr (old_phi_args, new_phi_args,
2436 old_bb_dominating_edge,
2437 old_bb_non_dominating_edge,
2438 phi, new_phi, new_bb);
2439}
2440
2441/* Copy cond phi nodes from BB to NEW_BB. A cond-phi node is a basic block
2442 containing phi nodes coming from two predecessors, and none of them are back
2443 edges. */
2444
2445bool
2446translate_isl_ast_to_gimple::copy_cond_phi_nodes (basic_block bb,
2447 basic_block new_bb,
2448 vec<tree> iv_map)
2449{
2450
2451 gcc_assert (!bb_contains_loop_close_phi_nodes (bb));
2452
2453 if (dump_file)
2454 fprintf (dump_file, "\n[codegen] copying cond phi nodes in bb_%d:",
2455 new_bb->index);
2456
2457 /* Cond phi nodes should have exactly two arguments. */
2458 gcc_assert (2 == EDGE_COUNT (bb->preds));
2459
2460 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2461 gsi_next (&psi))
2462 {
2463 gphi *phi = psi.phi ();
2464 tree res = gimple_phi_result (phi);
2465 if (virtual_operand_p (res))
2466 continue;
2467 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2468 /* Cond phi nodes should not be scev_analyzable_p. */
2469 gcc_unreachable ();
2470
2471 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
2472 tree new_res = create_new_def_for (res, new_phi,
2473 gimple_phi_result_ptr (new_phi));
2474 set_rename (res, new_res);
2475
2476 if (!copy_cond_phi_args (phi, new_phi, iv_map, true))
2477 return false;
2478
2479 update_stmt (new_phi);
2480 }
2481
2482 return true;
2483}
2484
2485/* Return true if STMT should be copied from region to the new code-generated
2486 region. LABELs, CONDITIONS, induction-variables and region parameters need
2487 not be copied. */
2488
2489static bool
2490should_copy_to_new_region (gimple *stmt, sese_info_p region)
2491{
2492 /* Do not copy labels or conditions. */
2493 if (gimple_code (stmt) == GIMPLE_LABEL
2494 || gimple_code (stmt) == GIMPLE_COND)
2495 return false;
2496
2497 tree lhs;
2498 /* Do not copy induction variables. */
2499 if (is_gimple_assign (stmt)
2500 && (lhs = gimple_assign_lhs (stmt))
2501 && TREE_CODE (lhs) == SSA_NAME
2502 && is_gimple_reg (lhs)
2503 && scev_analyzable_p (lhs, region->region))
2504 return false;
2505
2506 return true;
2507}
2508
2509/* Create new names for all the definitions created by COPY and add replacement
2510 mappings for each new name. */
2511
2512void
2513translate_isl_ast_to_gimple::set_rename_for_each_def (gimple *stmt)
2514{
2515 def_operand_p def_p;
2516 ssa_op_iter op_iter;
2517 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
2518 {
2519 tree old_name = DEF_FROM_PTR (def_p);
2520 tree new_name = create_new_def_for (old_name, stmt, def_p);
2521 set_rename (old_name, new_name);
2522 }
2523}
2524
2525/* Duplicates the statements of basic block BB into basic block NEW_BB
2526 and compute the new induction variables according to the IV_MAP.
2527 CODEGEN_ERROR is set when the code generation cannot continue. */
2528
2529bool
2530translate_isl_ast_to_gimple::graphite_copy_stmts_from_block (basic_block bb,
2531 basic_block new_bb,
2532 vec<tree> iv_map)
2533{
2534 /* Iterator poining to the place where new statement (s) will be inserted. */
2535 gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
2536
2537 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
2538 gsi_next (&gsi))
2539 {
2540 gimple *stmt = gsi_stmt (gsi);
2541 if (!should_copy_to_new_region (stmt, region))
2542 continue;
2543
2544 /* Create a new copy of STMT and duplicate STMT's virtual
2545 operands. */
2546 gimple *copy = gimple_copy (stmt);
2547 gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
2548
2549 if (dump_file)
2550 {
2551 fprintf (dump_file, "\n[codegen] inserting statement: ");
2552 print_gimple_stmt (dump_file, copy, 0, 0);
2553 }
2554
2555 maybe_duplicate_eh_stmt (copy, stmt);
2556 gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
2557
2558 /* Crete new names for each def in the copied stmt. */
2559 set_rename_for_each_def (copy);
2560
2561 loop_p loop = bb->loop_father;
2562 if (rename_uses (copy, &gsi_tgt, bb, loop, iv_map))
2563 {
2564 fold_stmt_inplace (&gsi_tgt);
2565 gcc_assert (gsi_stmt (gsi_tgt) == copy);
2566 }
2567
2568 if (codegen_error_p ())
2569 return false;
2570
2571 update_stmt (copy);
2572 }
2573
2574 return true;
2575}
2576
2927ca4b
AK
2577
2578/* Given a basic block containing close-phi it returns the new basic block where
2579 to insert a copy of the close-phi nodes. All the uses in close phis should
2580 come from a single loop otherwise it returns NULL. */
2581
2582edge
2583translate_isl_ast_to_gimple::edge_for_new_close_phis (basic_block bb)
2584{
2585 /* Make sure that NEW_BB is the new_loop->exit->dest. We find the definition
2586 of close phi in the original code and then find the mapping of basic block
2587 defining that variable. If there are multiple close-phis and they are
2588 defined in different loops (in the original or in the new code) because of
2589 loop splitting, then we bail out. */
2590 loop_p new_loop = NULL;
2591 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2592 gsi_next (&psi))
2593 {
2594 gphi *phi = psi.phi ();
2595 tree name = gimple_phi_arg_def (phi, 0);
2596 basic_block old_loop_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
2597
2598 vec <basic_block> *bbs = region->copied_bb_map->get (old_loop_bb);
2599 if (!bbs || bbs->length () != 1)
2600 /* This is one of the places which shows preserving original structure
2601 is not always possible, as we may need to insert close PHI for a loop
2602 where the latch does not have any mapping, or the mapping is
2603 ambiguous. */
2604 return NULL;
2605
2606 if (!new_loop)
2607 new_loop = (*bbs)[0]->loop_father;
2608 else if (new_loop != (*bbs)[0]->loop_father)
2609 return NULL;
2610 }
2611
2612 if (!new_loop)
2613 return NULL;
2614
2615 return single_exit (new_loop);
2616}
2617
2ecf4eca
AK
2618/* Copies BB and includes in the copied BB all the statements that can
2619 be reached following the use-def chains from the memory accesses,
2620 and returns the next edge following this new block. codegen_error is
2621 set when the code generation cannot continue. */
2622
2623edge
2624translate_isl_ast_to_gimple::copy_bb_and_scalar_dependences (basic_block bb,
2625 edge next_e,
2626 vec<tree> iv_map)
2627{
2628 int num_phis = number_of_phi_nodes (bb);
2629
2630 if (region->copied_bb_map->get (bb))
2631 {
2632 /* FIXME: we should be able to handle phi nodes with args coming from
2633 outside the region. */
2634 if (num_phis)
2635 {
2636 codegen_error = true;
2637 return NULL;
2638 }
2639 }
2640
2641 basic_block new_bb = split_edge (next_e);
2642 if (num_phis > 0 && bb_contains_loop_phi_nodes (bb))
2643 {
2644 basic_block phi_bb = next_e->dest->loop_father->header;
2645
2646 /* At this point we are unable to codegenerate by still preserving the SSA
2647 structure because maybe the loop is completely unrolled and the PHIs
2648 and cross-bb scalar dependencies are untrackable w.r.t. the original
2649 code. See gfortran.dg/graphite/pr29832.f90. */
2650 if (EDGE_COUNT (bb->preds) != EDGE_COUNT (phi_bb->preds))
2651 {
2652 codegen_error = true;
2653 return NULL;
2654 }
2655
2656 if (dump_file)
2657 fprintf (dump_file, "\n[codegen] bb_%d contains loop phi nodes",
2658 bb->index);
2659 if (!copy_loop_phi_nodes (bb, phi_bb))
2660 {
2661 codegen_error = true;
2662 return NULL;
2663 }
2664 }
2665 else if (bb_contains_loop_close_phi_nodes (bb))
2666 {
2667 if (dump_file)
2668 fprintf (dump_file, "\n[codegen] bb_%d contains close phi nodes",
2669 bb->index);
2670
2927ca4b
AK
2671 edge e = edge_for_new_close_phis (bb);
2672 if (!e)
2ecf4eca 2673 {
2927ca4b
AK
2674 codegen_error = true;
2675 return NULL;
2ecf4eca
AK
2676 }
2677
2927ca4b
AK
2678 basic_block phi_bb = split_edge (e);
2679 gcc_assert (single_pred_edge (phi_bb)->src->loop_father
2680 != single_pred_edge (phi_bb)->dest->loop_father);
2ecf4eca
AK
2681
2682 if (!copy_loop_close_phi_nodes (bb, phi_bb))
2683 {
2684 codegen_error = true;
2685 return NULL;
2686 }
2687 }
2688 else if (num_phis > 0)
2689 {
2690 if (dump_file)
2691 fprintf (dump_file, "\n[codegen] bb_%d contains cond phi nodes",
2692 bb->index);
2693
2694 basic_block phi_bb = single_pred (new_bb);
2695 loop_p loop_father = new_bb->loop_father;
2696
2697 /* Move back until we find the block with two predecessors. */
2698 while (single_pred_p (phi_bb))
2699 phi_bb = single_pred_edge (phi_bb)->src;
2700
2701 /* If a corresponding merge-point was not found, then abort codegen. */
2702 if (phi_bb->loop_father != loop_father
2703 || !copy_cond_phi_nodes (bb, phi_bb, iv_map))
2704 {
2705 codegen_error = true;
2706 return NULL;
2707 }
2708 }
2709
2710 if (dump_file)
2711 fprintf (dump_file, "\n[codegen] copying from bb_%d to bb_%d",
2712 bb->index, new_bb->index);
2713
2714 vec <basic_block> *copied_bbs = region->copied_bb_map->get (bb);
2715 if (copied_bbs)
2716 copied_bbs->safe_push (new_bb);
2717 else
2718 {
2719 vec<basic_block> bbs;
2720 bbs.create (2);
2721 bbs.safe_push (new_bb);
2722 region->copied_bb_map->put (bb, bbs);
2723 }
2724
2725 if (!graphite_copy_stmts_from_block (bb, new_bb, iv_map))
2726 {
2727 codegen_error = true;
2728 return NULL;
2729 }
2730
2731 return single_succ_edge (new_bb);
2732}
2733
2734/* Patch the missing arguments of the phi nodes. */
2735
2736void
2737translate_isl_ast_to_gimple::translate_pending_phi_nodes ()
2738{
2739 int i;
2740 phi_rename *rename;
2741 FOR_EACH_VEC_ELT (region->incomplete_phis, i, rename)
2742 {
2743 gphi *old_phi = rename->first;
2744 gphi *new_phi = rename->second;
2745 basic_block old_bb = gimple_bb (old_phi);
2746 basic_block new_bb = gimple_bb (new_phi);
2747
2748 /* First edge is the init edge and second is the back edge. */
2749 init_back_edge_pair_t ibp_old_bb = get_edges (old_bb);
2750 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
2751
2752 if (dump_file)
2753 {
2754 fprintf (dump_file, "\n[codegen] translating pending old-phi: ");
2755 print_gimple_stmt (dump_file, old_phi, 0, 0);
2756 }
2757
2758 auto_vec <tree, 1> iv_map;
2759 if (bb_contains_loop_phi_nodes (new_bb))
21c7259c
AK
2760 codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
2761 ibp_new_bb, false);
2ecf4eca 2762 else if (bb_contains_loop_close_phi_nodes (new_bb))
21c7259c
AK
2763 codegen_error = !copy_loop_close_phi_args (old_bb, new_bb, false);
2764 else
2765 codegen_error = !copy_cond_phi_args (old_phi, new_phi, iv_map, false);
2ecf4eca
AK
2766
2767 if (dump_file)
2768 {
2769 fprintf (dump_file, "[codegen] to new-phi: ");
2770 print_gimple_stmt (dump_file, new_phi, 0, 0);
2771 }
2772 }
2773}
2774
2775/* Prints NODE to FILE. */
2776
2777void
2778translate_isl_ast_to_gimple::print_isl_ast_node (FILE *file,
2779 __isl_keep isl_ast_node *node,
2780 __isl_keep isl_ctx *ctx) const
2781{
2782 isl_printer *prn = isl_printer_to_file (ctx, file);
2783 prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
2784 prn = isl_printer_print_ast_node (prn, node);
2785 prn = isl_printer_print_str (prn, "\n");
2786 isl_printer_free (prn);
2787}
2788
2789/* Add ISL's parameter identifiers and corresponding trees to ivs_params. */
2790
2791void
2792translate_isl_ast_to_gimple::add_parameters_to_ivs_params (scop_p scop,
2793 ivs_params &ip)
2794{
2795 sese_info_p region = scop->scop_info;
2796 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
2797 gcc_assert (nb_parameters == region->params.length ());
2798 unsigned i;
2799 for (i = 0; i < nb_parameters; i++)
2800 {
2801 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
2802 isl_dim_param, i);
2803 ip[tmp_id] = region->params[i];
2804 }
2805}
2806
2807
2808/* Generates a build, which specifies the constraints on the parameters. */
2809
2810__isl_give isl_ast_build *
2811translate_isl_ast_to_gimple::generate_isl_context (scop_p scop)
2812{
2813 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
2814 return isl_ast_build_from_context (context_isl);
2815}
2816
2817/* Get the maximal number of schedule dimensions in the scop SCOP. */
2818
2819int
2820translate_isl_ast_to_gimple::get_max_schedule_dimensions (scop_p scop)
2821{
2822 int i;
2823 poly_bb_p pbb;
2824 int schedule_dims = 0;
2825
2826 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
2827 {
2828 int pbb_schedule_dims = isl_map_dim (pbb->transformed, isl_dim_out);
2829 if (pbb_schedule_dims > schedule_dims)
2830 schedule_dims = pbb_schedule_dims;
2831 }
2832
2833 return schedule_dims;
2834}
2835
2836/* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
2837
2838 For schedules with different dimensionality, the isl AST generator can not
2839 define an order and will just randomly choose an order. The solution to this
2840 problem is to extend all schedules to the maximal number of schedule
2841 dimensions (using '0's for the remaining values). */
2842
2843__isl_give isl_map *
2844translate_isl_ast_to_gimple::extend_schedule (__isl_take isl_map *schedule,
2845 int nb_schedule_dims)
2846{
2847 int tmp_dims = isl_map_dim (schedule, isl_dim_out);
2848 schedule =
2849 isl_map_add_dims (schedule, isl_dim_out, nb_schedule_dims - tmp_dims);
2850 isl_val *zero =
2851 isl_val_int_from_si (isl_map_get_ctx (schedule), 0);
2852 int i;
2853 for (i = tmp_dims; i < nb_schedule_dims; i++)
2854 {
2855 schedule
2856 = isl_map_fix_val (schedule, isl_dim_out, i, isl_val_copy (zero));
2857 }
2858 isl_val_free (zero);
2859 return schedule;
2860}
2861
2862/* Generates a schedule, which specifies an order used to
2863 visit elements in a domain. */
2864
2865__isl_give isl_union_map *
2866translate_isl_ast_to_gimple::generate_isl_schedule (scop_p scop)
2867{
2868 int nb_schedule_dims = get_max_schedule_dimensions (scop);
2869 int i;
2870 poly_bb_p pbb;
2871 isl_union_map *schedule_isl =
2872 isl_union_map_empty (isl_set_get_space (scop->param_context));
2873
2874 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
2875 {
2876 /* Dead code elimination: when the domain of a PBB is empty,
2877 don't generate code for the PBB. */
2878 if (isl_set_is_empty (pbb->domain))
2879 continue;
2880
2881 isl_map *bb_schedule = isl_map_copy (pbb->transformed);
2882 bb_schedule = isl_map_intersect_domain (bb_schedule,
2883 isl_set_copy (pbb->domain));
2884 bb_schedule = extend_schedule (bb_schedule, nb_schedule_dims);
2885 schedule_isl
2886 = isl_union_map_union (schedule_isl,
2887 isl_union_map_from_map (bb_schedule));
2888 }
2889 return schedule_isl;
2890}
2891
2892/* This method is executed before the construction of a for node. */
2893__isl_give isl_id *
2894ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
2895{
2896 isl_union_map *dependences = (isl_union_map *) user;
2897 ast_build_info *for_info = XNEW (struct ast_build_info);
2898 isl_union_map *schedule = isl_ast_build_get_schedule (build);
2899 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
2900 int dimension = isl_space_dim (schedule_space, isl_dim_out);
2901 for_info->is_parallelizable =
2902 !carries_deps (schedule, dependences, dimension);
2903 isl_union_map_free (schedule);
2904 isl_space_free (schedule_space);
2905 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
2906 return id;
2907}
2908
2909/* Set the separate option for all dimensions.
2910 This helps to reduce control overhead. */
2911
2912__isl_give isl_ast_build *
2913translate_isl_ast_to_gimple::set_options (__isl_take isl_ast_build *control,
2914 __isl_keep isl_union_map *schedule)
2915{
2916 isl_ctx *ctx = isl_union_map_get_ctx (schedule);
2917 isl_space *range_space = isl_space_set_alloc (ctx, 0, 1);
2918 range_space =
2919 isl_space_set_tuple_name (range_space, isl_dim_set, "separate");
2920 isl_union_set *range =
2921 isl_union_set_from_set (isl_set_universe (range_space));
2922 isl_union_set *domain = isl_union_map_range (isl_union_map_copy (schedule));
2923 domain = isl_union_set_universe (domain);
2924 isl_union_map *options = isl_union_map_from_domain_and_range (domain, range);
2925 return isl_ast_build_set_options (control, options);
2926}
2927
2928/* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in IP. */
2929
2930__isl_give isl_ast_node *
2931translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop, ivs_params &ip)
2932{
2933 /* Generate loop upper bounds that consist of the current loop iterator, an
2934 operator (< or <=) and an expression not involving the iterator. If this
2935 option is not set, then the current loop iterator may appear several times
2936 in the upper bound. See the isl manual for more details. */
2937 isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, true);
2938
2939 add_parameters_to_ivs_params (scop, ip);
2940 isl_union_map *schedule_isl = generate_isl_schedule (scop);
2941 isl_ast_build *context_isl = generate_isl_context (scop);
2942 context_isl = set_options (context_isl, schedule_isl);
2943 isl_union_map *dependences = NULL;
2944 if (flag_loop_parallelize_all)
2945 {
2946 dependences = scop_get_dependences (scop);
2947 context_isl =
2948 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
2949 dependences);
2950 }
2951 isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
2952 schedule_isl);
2953 if (dependences)
2954 isl_union_map_free (dependences);
2955 isl_ast_build_free (context_isl);
2956 return ast_isl;
2957}
2958
2959/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
2960 the given SCOP. Return true if code generation succeeded.
2961
2962 FIXME: This is not yet a full implementation of the code generator
2963 with ISL ASTs. Generation of GIMPLE code has to be completed. */
2964
2965bool
2966graphite_regenerate_ast_isl (scop_p scop)
2967{
2968 sese_info_p region = scop->scop_info;
2969 translate_isl_ast_to_gimple t (region);
2970
2971 ifsese if_region = NULL;
2972 isl_ast_node *root_node;
2973 ivs_params ip;
2974
2975 timevar_push (TV_GRAPHITE_CODE_GEN);
2976 root_node = t.scop_to_isl_ast (scop, ip);
2977
2978 if (dump_file && (dump_flags & TDF_DETAILS))
2979 {
2980 fprintf (dump_file, "\nISL AST generated by ISL: \n");
2981 t.print_isl_ast_node (dump_file, root_node, scop->isl_context);
2982 }
2983
2984 recompute_all_dominators ();
2985 graphite_verify ();
2986
2987 if_region = move_sese_in_condition (region);
2988 region->if_region = if_region;
2989 recompute_all_dominators ();
2990
2991 loop_p context_loop = region->region.entry->src->loop_father;
2992
2993 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
2994 basic_block bb = split_edge (e);
a78cfa7f 2995
65b016eb
AK
2996 /* Update the true_region exit edge. */
2997 region->if_region->true_region->region.exit = single_succ_edge (bb);
d819fedb 2998
65b016eb
AK
2999 t.translate_isl_ast (context_loop, root_node, e, ip);
3000 if (t.codegen_error_p ())
3001 {
3002 if (dump_file)
2ecf4eca
AK
3003 fprintf (dump_file, "\n[codegen] unsuccessful,"
3004 " reverting back to the original code.");
65b016eb
AK
3005 set_ifsese_condition (if_region, integer_zero_node);
3006 }
3007 else
3008 {
3009 t.translate_pending_phi_nodes ();
3010 if (!t.codegen_error_p ())
3011 {
3012 sese_insert_phis_for_liveouts (region,
3013 if_region->region->region.exit->src,
3014 if_region->false_region->region.exit,
3015 if_region->true_region->region.exit);
3016 mark_virtual_operands_for_renaming (cfun);
3017 update_ssa (TODO_update_ssa);
3018
3019
3020 graphite_verify ();
3021 scev_reset ();
3022 recompute_all_dominators ();
3023 graphite_verify ();
3024 }
21c7259c
AK
3025 else
3026 {
3027 if (dump_file)
3028 fprintf (dump_file, "\n[codegen] unsuccessful in translating"
3029 " pending phis, reverting back to the original code.");
3030 set_ifsese_condition (if_region, integer_zero_node);
3031 }
65b016eb 3032 }
a78cfa7f
RG
3033
3034 free (if_region->true_region);
3035 free (if_region->region);
3036 free (if_region);
3037
3038 ivs_params_clear (ip);
f6cc3103
RG
3039 isl_ast_node_free (root_node);
3040 timevar_pop (TV_GRAPHITE_CODE_GEN);
574921c2
RG
3041
3042 if (dump_file && (dump_flags & TDF_DETAILS))
3043 {
3044 loop_p loop;
3045 int num_no_dependency = 0;
3046
3047 FOR_EACH_LOOP (loop, 0)
3048 if (loop->can_be_parallel)
3049 num_no_dependency++;
3050
3051 fprintf (dump_file, "\n%d loops carried no dependency.\n",
3052 num_no_dependency);
3053 }
3054
65b016eb 3055 return !t.codegen_error_p ();
f6cc3103 3056}
2ecf4eca 3057
9c358739 3058#endif /* HAVE_isl */