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