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