Missing copyright for mem-stats header files.
[official-gcc.git] / gcc / graphite-isl-ast-to-gimple.c
blobd3614e48cd8f6ebfe9917b616a1c999e561ca22f
1 /* Translation of isl AST to Gimple.
2 Copyright (C) 2014-2016 Free Software Foundation, Inc.
3 Contributed by Roman Gareev <gareevroman@gmail.com>.
5 This file is part of GCC.
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.
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.
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/>. */
21 #define USES_ISL
23 #include "config.h"
25 #ifdef HAVE_isl
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>
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. */
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;
68 struct ast_build_info
70 ast_build_info()
71 : is_parallelizable(false)
72 { }
73 bool is_parallelizable;
76 /* Converts a GMP constant VAL to a tree and returns it. */
78 static tree
79 gmp_cst_to_tree (tree type, mpz_t val)
81 tree t = type ? type : integer_type_node;
82 mpz_t tmp;
84 mpz_init (tmp);
85 mpz_set (tmp, val);
86 wide_int wi = wi::from_mpz (t, tmp, true);
87 mpz_clear (tmp);
89 return wide_int_to_tree (t, wi);
92 /* Verifies properties that GRAPHITE should maintain during translation. */
94 static inline void
95 graphite_verify (void)
97 checking_verify_loop_structure ();
98 checking_verify_loop_closed_ssa (true);
101 /* IVS_PARAMS maps isl's scattering and parameter identifiers
102 to corresponding trees. */
104 typedef std::map<isl_id *, tree> ivs_params;
106 /* Free all memory allocated for isl's identifiers. */
108 static void ivs_params_clear (ivs_params &ip)
110 std::map<isl_id *, tree>::iterator it;
111 for (it = ip.begin ();
112 it != ip.end (); it++)
114 isl_id_free (it->first);
118 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
120 /* Set the "separate" option for the schedule node. */
122 static isl_schedule_node *
123 set_separate_option (__isl_take isl_schedule_node *node, void *user)
125 if (user)
126 return node;
128 if (isl_schedule_node_get_type (node) != isl_schedule_node_band)
129 return node;
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);
137 return node;
140 /* Print SCHEDULE under an AST form on file F. */
142 void
143 print_schedule_ast (FILE *f, __isl_keep isl_schedule *schedule, scop_p scop)
145 isl_set *set = isl_set_params (isl_set_copy (scop->param_context));
146 isl_ast_build *context = isl_ast_build_from_context (set);
147 isl_ast_node *ast
148 = isl_ast_build_node_from_schedule (context, isl_schedule_copy (schedule));
149 isl_ast_build_free (context);
150 print_isl_ast (f, ast);
151 isl_ast_node_free (ast);
154 DEBUG_FUNCTION void
155 debug_schedule_ast (__isl_keep isl_schedule *s, scop_p scop)
157 print_schedule_ast (stderr, s, scop);
160 #endif
162 enum phi_node_kind
164 unknown_phi,
165 loop_phi,
166 close_phi,
167 cond_phi
170 class translate_isl_ast_to_gimple
172 public:
173 translate_isl_ast_to_gimple (sese_info_p r)
174 : region (r), codegen_error (false) { }
175 edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
176 edge next_e, ivs_params &ip);
177 edge translate_isl_ast_node_for (loop_p context_loop,
178 __isl_keep isl_ast_node *node,
179 edge next_e, ivs_params &ip);
180 edge translate_isl_ast_for_loop (loop_p context_loop,
181 __isl_keep isl_ast_node *node_for,
182 edge next_e,
183 tree type, tree lb, tree ub,
184 ivs_params &ip);
185 edge translate_isl_ast_node_if (loop_p context_loop,
186 __isl_keep isl_ast_node *node,
187 edge next_e, ivs_params &ip);
188 edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
189 edge next_e, ivs_params &ip);
190 edge translate_isl_ast_node_block (loop_p context_loop,
191 __isl_keep isl_ast_node *node,
192 edge next_e, ivs_params &ip);
193 tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
194 ivs_params &ip);
195 tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
196 ivs_params &ip);
197 tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
198 ivs_params &ip);
199 tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
200 ivs_params &ip);
201 tree gcc_expression_from_isl_expression (tree type,
202 __isl_take isl_ast_expr *,
203 ivs_params &ip);
204 tree gcc_expression_from_isl_ast_expr_id (tree type,
205 __isl_keep isl_ast_expr *expr_id,
206 ivs_params &ip);
207 tree gcc_expression_from_isl_expr_int (tree type,
208 __isl_take isl_ast_expr *expr);
209 tree gcc_expression_from_isl_expr_op (tree type,
210 __isl_take isl_ast_expr *expr,
211 ivs_params &ip);
212 struct loop *graphite_create_new_loop (edge entry_edge,
213 __isl_keep isl_ast_node *node_for,
214 loop_p outer, tree type,
215 tree lb, tree ub, ivs_params &ip);
216 edge graphite_create_new_loop_guard (edge entry_edge,
217 __isl_keep isl_ast_node *node_for,
218 tree *type,
219 tree *lb, tree *ub, ivs_params &ip);
220 edge graphite_create_new_guard (edge entry_edge,
221 __isl_take isl_ast_expr *if_cond,
222 ivs_params &ip);
223 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
224 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
225 sese_l &region);
226 void translate_pending_phi_nodes (void);
227 void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
228 __isl_give isl_ast_build *generate_isl_context (scop_p scop);
230 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
231 __isl_give isl_ast_node * scop_to_isl_ast (scop_p scop);
232 #else
233 int get_max_schedule_dimensions (scop_p scop);
234 __isl_give isl_map *extend_schedule (__isl_take isl_map *schedule,
235 int nb_schedule_dims);
236 __isl_give isl_union_map *generate_isl_schedule (scop_p scop);
237 __isl_give isl_ast_build *set_options (__isl_take isl_ast_build *control,
238 __isl_keep isl_union_map *schedule);
239 __isl_give isl_ast_node *scop_to_isl_ast (scop_p scop, ivs_params &ip);
240 #endif
242 bool is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
243 phi_node_kind, tree old_name, basic_block old_bb) const;
244 tree get_rename (basic_block new_bb, tree old_name,
245 basic_block old_bb, phi_node_kind) const;
246 tree get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
247 basic_block new_bb, basic_block old_bb,
248 vec<tree> iv_map);
249 basic_block get_def_bb_for_const (basic_block bb, basic_block old_bb) const;
250 tree get_new_name (basic_block new_bb, tree op,
251 basic_block old_bb, phi_node_kind) const;
252 void collect_all_ssa_names (tree new_expr, vec<tree> *vec_ssa);
253 bool copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
254 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
255 bool postpone);
256 bool copy_loop_phi_nodes (basic_block bb, basic_block new_bb);
257 bool add_close_phis_to_merge_points (gphi *old_phi, gphi *new_phi,
258 tree default_value);
259 tree add_close_phis_to_outer_loops (tree last_merge_name, edge merge_e,
260 gimple *old_close_phi);
261 bool copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
262 bool postpone);
263 bool copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb);
264 bool copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map,
265 bool postpone);
266 bool copy_cond_phi_nodes (basic_block bb, basic_block new_bb,
267 vec<tree> iv_map);
268 bool graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
269 vec<tree> iv_map);
270 edge copy_bb_and_scalar_dependences (basic_block bb, edge next_e,
271 vec<tree> iv_map);
272 edge edge_for_new_close_phis (basic_block bb);
273 bool add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
274 edge old_bb_dominating_edge,
275 edge old_bb_non_dominating_edge,
276 gphi *phi, gphi *new_phi,
277 basic_block new_bb);
278 bool rename_uses (gimple *copy, gimple_stmt_iterator *gsi_tgt,
279 basic_block old_bb, loop_p loop, vec<tree> iv_map);
280 void set_rename (tree old_name, tree expr);
281 void set_rename_for_each_def (gimple *stmt);
282 void gsi_insert_earliest (gimple_seq seq);
283 tree rename_all_uses (tree new_expr, basic_block new_bb, basic_block old_bb);
284 bool codegen_error_p () const { return codegen_error; }
285 bool is_constant (tree op) const
287 return TREE_CODE (op) == INTEGER_CST
288 || TREE_CODE (op) == REAL_CST
289 || TREE_CODE (op) == COMPLEX_CST
290 || TREE_CODE (op) == VECTOR_CST;
293 private:
294 /* The region to be translated. */
295 sese_info_p region;
297 /* This flag is set when an error occurred during the translation of isl AST
298 to Gimple. */
299 bool codegen_error;
301 /* A vector of all the edges at if_condition merge points. */
302 auto_vec<edge, 2> merge_points;
305 /* Return the tree variable that corresponds to the given isl ast identifier
306 expression (an isl_ast_expr of type isl_ast_expr_id).
308 FIXME: We should replace blind conversion of id's type with derivation
309 of the optimal type when we get the corresponding isl support. Blindly
310 converting type sizes may be problematic when we switch to smaller
311 types. */
313 tree translate_isl_ast_to_gimple::
314 gcc_expression_from_isl_ast_expr_id (tree type,
315 __isl_take isl_ast_expr *expr_id,
316 ivs_params &ip)
318 gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
319 isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
320 std::map<isl_id *, tree>::iterator res;
321 res = ip.find (tmp_isl_id);
322 isl_id_free (tmp_isl_id);
323 gcc_assert (res != ip.end () &&
324 "Could not map isl_id to tree expression");
325 isl_ast_expr_free (expr_id);
326 tree t = res->second;
327 tree *val = region->parameter_rename_map->get(t);
329 if (!val)
330 val = &t;
331 return fold_convert (type, *val);
334 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
335 type TYPE. */
337 tree translate_isl_ast_to_gimple::
338 gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
340 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
341 isl_val *val = isl_ast_expr_get_val (expr);
342 mpz_t val_mpz_t;
343 mpz_init (val_mpz_t);
344 tree res;
345 if (isl_val_get_num_gmp (val, val_mpz_t) == -1)
346 res = NULL_TREE;
347 else
348 res = gmp_cst_to_tree (type, val_mpz_t);
349 isl_val_free (val);
350 isl_ast_expr_free (expr);
351 mpz_clear (val_mpz_t);
352 return res;
355 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
356 type TYPE. */
358 tree translate_isl_ast_to_gimple::
359 binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
361 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
362 tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
363 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
364 tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
366 enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
367 isl_ast_expr_free (expr);
369 if (codegen_error_p ())
370 return NULL_TREE;
372 switch (expr_type)
374 case isl_ast_op_add:
375 return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
377 case isl_ast_op_sub:
378 return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
380 case isl_ast_op_mul:
381 return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
383 case isl_ast_op_div:
384 /* As isl operates on arbitrary precision numbers, we may end up with
385 division by 2^64 that is folded to 0. */
386 if (integer_zerop (tree_rhs_expr))
388 codegen_error = true;
389 return NULL_TREE;
391 return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
393 case isl_ast_op_pdiv_q:
394 /* As isl operates on arbitrary precision numbers, we may end up with
395 division by 2^64 that is folded to 0. */
396 if (integer_zerop (tree_rhs_expr))
398 codegen_error = true;
399 return NULL_TREE;
401 return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
403 #if HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
404 /* isl 0.15 or later. */
405 case isl_ast_op_zdiv_r:
406 #endif
407 case isl_ast_op_pdiv_r:
408 /* As isl operates on arbitrary precision numbers, we may end up with
409 division by 2^64 that is folded to 0. */
410 if (integer_zerop (tree_rhs_expr))
412 codegen_error = true;
413 return NULL_TREE;
415 return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
417 case isl_ast_op_fdiv_q:
418 /* As isl operates on arbitrary precision numbers, we may end up with
419 division by 2^64 that is folded to 0. */
420 if (integer_zerop (tree_rhs_expr))
422 codegen_error = true;
423 return NULL_TREE;
425 return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
427 case isl_ast_op_and:
428 return fold_build2 (TRUTH_ANDIF_EXPR, type,
429 tree_lhs_expr, tree_rhs_expr);
431 case isl_ast_op_or:
432 return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);
434 case isl_ast_op_eq:
435 return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);
437 case isl_ast_op_le:
438 return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
440 case isl_ast_op_lt:
441 return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
443 case isl_ast_op_ge:
444 return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
446 case isl_ast_op_gt:
447 return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
449 default:
450 gcc_unreachable ();
454 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
455 type TYPE. */
457 tree translate_isl_ast_to_gimple::
458 ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
460 enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr);
461 gcc_assert (t == isl_ast_op_cond || t == isl_ast_op_select);
462 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
463 tree a = gcc_expression_from_isl_expression (type, arg_expr, ip);
464 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
465 tree b = gcc_expression_from_isl_expression (type, arg_expr, ip);
466 arg_expr = isl_ast_expr_get_op_arg (expr, 2);
467 tree c = gcc_expression_from_isl_expression (type, arg_expr, ip);
468 isl_ast_expr_free (expr);
470 if (codegen_error_p ())
471 return NULL_TREE;
473 return fold_build3 (COND_EXPR, type, a, b, c);
476 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
477 type TYPE. */
479 tree translate_isl_ast_to_gimple::
480 unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
482 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
483 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
484 tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
485 isl_ast_expr_free (expr);
486 return codegen_error_p () ? NULL_TREE
487 : fold_build1 (NEGATE_EXPR, type, tree_expr);
490 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
491 to a GCC expression tree of type TYPE. */
493 tree translate_isl_ast_to_gimple::
494 nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
496 enum tree_code op_code;
497 switch (isl_ast_expr_get_op_type (expr))
499 case isl_ast_op_max:
500 op_code = MAX_EXPR;
501 break;
503 case isl_ast_op_min:
504 op_code = MIN_EXPR;
505 break;
507 default:
508 gcc_unreachable ();
510 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
511 tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);
513 if (codegen_error_p ())
515 isl_ast_expr_free (expr);
516 return NULL_TREE;
519 int i;
520 for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
522 arg_expr = isl_ast_expr_get_op_arg (expr, i);
523 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
525 if (codegen_error_p ())
527 isl_ast_expr_free (expr);
528 return NULL_TREE;
531 res = fold_build2 (op_code, type, res, t);
533 isl_ast_expr_free (expr);
534 return res;
537 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
538 type TYPE. */
540 tree translate_isl_ast_to_gimple::
541 gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
542 ivs_params &ip)
544 if (codegen_error_p ())
546 isl_ast_expr_free (expr);
547 return NULL_TREE;
550 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
551 switch (isl_ast_expr_get_op_type (expr))
553 /* These isl ast expressions are not supported yet. */
554 case isl_ast_op_error:
555 case isl_ast_op_call:
556 case isl_ast_op_and_then:
557 case isl_ast_op_or_else:
558 gcc_unreachable ();
560 case isl_ast_op_max:
561 case isl_ast_op_min:
562 return nary_op_to_tree (type, expr, ip);
564 case isl_ast_op_add:
565 case isl_ast_op_sub:
566 case isl_ast_op_mul:
567 case isl_ast_op_div:
568 case isl_ast_op_pdiv_q:
569 case isl_ast_op_pdiv_r:
570 case isl_ast_op_fdiv_q:
571 #if HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
572 /* isl 0.15 or later. */
573 case isl_ast_op_zdiv_r:
574 #endif
575 case isl_ast_op_and:
576 case isl_ast_op_or:
577 case isl_ast_op_eq:
578 case isl_ast_op_le:
579 case isl_ast_op_lt:
580 case isl_ast_op_ge:
581 case isl_ast_op_gt:
582 return binary_op_to_tree (type, expr, ip);
584 case isl_ast_op_minus:
585 return unary_op_to_tree (type, expr, ip);
587 case isl_ast_op_cond:
588 case isl_ast_op_select:
589 return ternary_op_to_tree (type, expr, ip);
591 default:
592 gcc_unreachable ();
595 return NULL_TREE;
598 /* Converts an isl AST expression E back to a GCC expression tree of
599 type TYPE. */
601 tree translate_isl_ast_to_gimple::
602 gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
603 ivs_params &ip)
605 if (codegen_error_p ())
607 isl_ast_expr_free (expr);
608 return NULL_TREE;
611 switch (isl_ast_expr_get_type (expr))
613 case isl_ast_expr_id:
614 return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
616 case isl_ast_expr_int:
617 return gcc_expression_from_isl_expr_int (type, expr);
619 case isl_ast_expr_op:
620 return gcc_expression_from_isl_expr_op (type, expr, ip);
622 default:
623 gcc_unreachable ();
626 return NULL_TREE;
629 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
630 induction variable for the new LOOP. New LOOP is attached to CFG
631 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
632 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
633 isl's scattering name to the induction variable created for the
634 loop of STMT. The new induction variable is inserted in the NEWIVS
635 vector and is of type TYPE. */
637 struct loop *translate_isl_ast_to_gimple::
638 graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
639 loop_p outer, tree type, tree lb, tree ub,
640 ivs_params &ip)
642 isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
643 tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
645 /* To fail code generation, we generate wrong code until we discard it. */
646 if (codegen_error_p ())
647 stride = integer_zero_node;
649 tree ivvar = create_tmp_var (type, "graphite_IV");
650 tree iv, iv_after_increment;
651 loop_p loop = create_empty_loop_on_edge
652 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
653 outer ? outer : entry_edge->src->loop_father);
655 isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
656 isl_id *id = isl_ast_expr_get_id (for_iterator);
657 std::map<isl_id *, tree>::iterator res;
658 res = ip.find (id);
659 if (ip.count (id))
660 isl_id_free (res->first);
661 ip[id] = iv;
662 isl_ast_expr_free (for_iterator);
663 return loop;
666 /* Create the loop for a isl_ast_node_for.
668 - NEXT_E is the edge where new generated code should be attached. */
670 edge translate_isl_ast_to_gimple::
671 translate_isl_ast_for_loop (loop_p context_loop,
672 __isl_keep isl_ast_node *node_for, edge next_e,
673 tree type, tree lb, tree ub,
674 ivs_params &ip)
676 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
677 struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
678 type, lb, ub, ip);
679 edge last_e = single_exit (loop);
680 edge to_body = single_succ_edge (loop->header);
681 basic_block after = to_body->dest;
683 /* Translate the body of the loop. */
684 isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
685 next_e = translate_isl_ast (loop, for_body, to_body, ip);
686 isl_ast_node_free (for_body);
688 /* Early return if we failed to translate loop body. */
689 if (!next_e || codegen_error_p ())
690 return NULL;
692 if (next_e->dest != after)
693 redirect_edge_succ_nodup (next_e, after);
694 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
696 if (flag_loop_parallelize_all)
698 isl_id *id = isl_ast_node_get_annotation (node_for);
699 gcc_assert (id);
700 ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
701 loop->can_be_parallel = for_info->is_parallelizable;
702 free (for_info);
703 isl_id_free (id);
706 return last_e;
709 /* We use this function to get the upper bound because of the form,
710 which is used by isl to represent loops:
712 for (iterator = init; cond; iterator += inc)
720 The loop condition is an arbitrary expression, which contains the
721 current loop iterator.
723 (e.g. iterator + 3 < B && C > iterator + A)
725 We have to know the upper bound of the iterator to generate a loop
726 in Gimple form. It can be obtained from the special representation
727 of the loop condition, which is generated by isl,
728 if the ast_build_atomic_upper_bound option is set. In this case,
729 isl generates a loop condition that consists of the current loop
730 iterator, + an operator (< or <=) and an expression not involving
731 the iterator, which is processed and returned by this function.
733 (e.g iterator <= upper-bound-expression-without-iterator) */
735 static __isl_give isl_ast_expr *
736 get_upper_bound (__isl_keep isl_ast_node *node_for)
738 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
739 isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
740 gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
741 isl_ast_expr *res;
742 switch (isl_ast_expr_get_op_type (for_cond))
744 case isl_ast_op_le:
745 res = isl_ast_expr_get_op_arg (for_cond, 1);
746 break;
748 case isl_ast_op_lt:
750 /* (iterator < ub) => (iterator <= ub - 1). */
751 isl_val *one =
752 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
753 isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
754 res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
755 break;
758 default:
759 gcc_unreachable ();
761 isl_ast_expr_free (for_cond);
762 return res;
765 /* All loops generated by create_empty_loop_on_edge have the form of
766 a post-test loop:
771 body of the loop;
772 } while (lower bound < upper bound);
774 We create a new if region protecting the loop to be executed, if
775 the execution count is zero (lower bound > upper bound). */
777 edge translate_isl_ast_to_gimple::
778 graphite_create_new_loop_guard (edge entry_edge,
779 __isl_keep isl_ast_node *node_for, tree *type,
780 tree *lb, tree *ub, ivs_params &ip)
782 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
783 tree cond_expr;
784 edge exit_edge;
786 *type =
787 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
788 isl_ast_expr *for_init = isl_ast_node_for_get_init (node_for);
789 *lb = gcc_expression_from_isl_expression (*type, for_init, ip);
791 /* To fail code generation, we generate wrong code until we discard it. */
792 if (codegen_error_p ())
793 *lb = integer_zero_node;
795 isl_ast_expr *upper_bound = get_upper_bound (node_for);
796 *ub = gcc_expression_from_isl_expression (*type, upper_bound, ip);
798 /* To fail code generation, we generate wrong code until we discard it. */
799 if (codegen_error_p ())
800 *ub = integer_zero_node;
802 /* When ub is simply a constant or a parameter, use lb <= ub. */
803 if (TREE_CODE (*ub) == INTEGER_CST || TREE_CODE (*ub) == SSA_NAME)
804 cond_expr = fold_build2 (LE_EXPR, boolean_type_node, *lb, *ub);
805 else
807 tree one = (POINTER_TYPE_P (*type)
808 ? convert_to_ptrofftype (integer_one_node)
809 : fold_convert (*type, integer_one_node));
810 /* Adding +1 and using LT_EXPR helps with loop latches that have a
811 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this
812 becomes 2^k-1 due to integer overflow, and the condition lb <= ub
813 is true, even if we do not want this. However lb < ub + 1 is false,
814 as expected. */
815 tree ub_one = fold_build2 (POINTER_TYPE_P (*type) ? POINTER_PLUS_EXPR
816 : PLUS_EXPR, *type, *ub, one);
818 cond_expr = fold_build2 (LT_EXPR, boolean_type_node, *lb, ub_one);
821 if (integer_onep (cond_expr))
822 exit_edge = entry_edge;
823 else
824 exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
826 return exit_edge;
829 /* Translates an isl_ast_node_for to Gimple. */
831 edge translate_isl_ast_to_gimple::
832 translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
833 edge next_e, ivs_params &ip)
835 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
836 tree type, lb, ub;
837 edge last_e = graphite_create_new_loop_guard (next_e, node, &type,
838 &lb, &ub, ip);
840 if (last_e == next_e)
842 /* There was no guard generated. */
843 last_e = single_succ_edge (split_edge (last_e));
845 translate_isl_ast_for_loop (context_loop, node, next_e,
846 type, lb, ub, ip);
847 return last_e;
850 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
851 merge_points.safe_push (last_e);
853 last_e = single_succ_edge (split_edge (last_e));
854 translate_isl_ast_for_loop (context_loop, node, true_e, type, lb, ub, ip);
856 return last_e;
859 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
860 variables of the loops around GBB in SESE.
862 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
863 chrec, we could consider using a map<int, tree> that maps loop ids to the
864 corresponding tree expressions. */
866 void translate_isl_ast_to_gimple::
867 build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
868 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
869 sese_l &region)
871 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
872 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
873 int i;
874 isl_ast_expr *arg_expr;
875 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
877 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
878 tree type =
879 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
880 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
882 /* To fail code generation, we generate wrong code until we discard it. */
883 if (codegen_error_p ())
884 t = integer_zero_node;
886 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
887 iv_map[old_loop->num] = t;
891 /* Translates an isl_ast_node_user to Gimple.
893 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
895 edge translate_isl_ast_to_gimple::
896 translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
897 edge next_e, ivs_params &ip)
899 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
901 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
902 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
903 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
905 isl_id *name_id = isl_ast_expr_get_id (name_expr);
906 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
907 gcc_assert (pbb);
909 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
911 isl_ast_expr_free (name_expr);
912 isl_id_free (name_id);
914 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
915 "The entry block should not even appear within a scop");
917 const int nb_loops = number_of_loops (cfun);
918 vec<tree> iv_map;
919 iv_map.create (nb_loops);
920 iv_map.safe_grow_cleared (nb_loops);
922 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
923 isl_ast_expr_free (user_expr);
925 basic_block old_bb = GBB_BB (gbb);
926 if (dump_file)
928 fprintf (dump_file,
929 "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
930 old_bb->index, next_e->src->index, next_e->dest->index);
931 print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
935 next_e = copy_bb_and_scalar_dependences (old_bb, next_e, iv_map);
937 iv_map.release ();
939 if (codegen_error_p ())
940 return NULL;
942 if (dump_file)
944 fprintf (dump_file, "[codegen] (after copy) new basic block\n");
945 print_loops_bb (dump_file, next_e->src, 0, 3);
948 return next_e;
951 /* Translates an isl_ast_node_block to Gimple. */
953 edge translate_isl_ast_to_gimple::
954 translate_isl_ast_node_block (loop_p context_loop,
955 __isl_keep isl_ast_node *node,
956 edge next_e, ivs_params &ip)
958 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
959 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
960 int i;
961 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
963 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
964 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
965 isl_ast_node_free (tmp_node);
967 isl_ast_node_list_free (node_list);
968 return next_e;
971 /* Creates a new if region corresponding to isl's cond. */
973 edge translate_isl_ast_to_gimple::
974 graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
975 ivs_params &ip)
977 tree type =
978 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
979 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
981 /* To fail code generation, we generate wrong code until we discard it. */
982 if (codegen_error_p ())
983 cond_expr = integer_zero_node;
985 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
986 return exit_edge;
989 /* Translates an isl_ast_node_if to Gimple. */
991 edge translate_isl_ast_to_gimple::
992 translate_isl_ast_node_if (loop_p context_loop,
993 __isl_keep isl_ast_node *node,
994 edge next_e, ivs_params &ip)
996 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
997 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
998 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
999 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1000 merge_points.safe_push (last_e);
1002 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
1003 translate_isl_ast (context_loop, then_node, true_e, ip);
1004 isl_ast_node_free (then_node);
1006 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
1007 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
1008 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
1009 translate_isl_ast (context_loop, else_node, false_e, ip);
1011 isl_ast_node_free (else_node);
1012 return last_e;
1015 /* Translates an isl AST node NODE to GCC representation in the
1016 context of a SESE. */
1018 edge translate_isl_ast_to_gimple::
1019 translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
1020 edge next_e, ivs_params &ip)
1022 if (codegen_error_p ())
1023 return NULL;
1025 switch (isl_ast_node_get_type (node))
1027 case isl_ast_node_error:
1028 gcc_unreachable ();
1030 case isl_ast_node_for:
1031 return translate_isl_ast_node_for (context_loop, node,
1032 next_e, ip);
1034 case isl_ast_node_if:
1035 return translate_isl_ast_node_if (context_loop, node,
1036 next_e, ip);
1038 case isl_ast_node_user:
1039 return translate_isl_ast_node_user (node, next_e, ip);
1041 case isl_ast_node_block:
1042 return translate_isl_ast_node_block (context_loop, node,
1043 next_e, ip);
1045 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
1046 case isl_ast_node_mark:
1048 isl_ast_node *n = isl_ast_node_mark_get_node (node);
1049 edge e = translate_isl_ast (context_loop, n, next_e, ip);
1050 isl_ast_node_free (n);
1051 return e;
1053 #endif
1055 default:
1056 gcc_unreachable ();
1060 /* Return true when BB contains loop close phi nodes. A loop close phi node is
1061 at the exit of loop which takes one argument that is the last value of the
1062 variable being used out of the loop. */
1064 static bool
1065 bb_contains_loop_close_phi_nodes (basic_block bb)
1067 return single_pred_p (bb)
1068 && bb->loop_father != single_pred_edge (bb)->src->loop_father;
1071 /* Return true when BB contains loop phi nodes. A loop phi node is the loop
1072 header containing phi nodes which has one init-edge and one back-edge. */
1074 static bool
1075 bb_contains_loop_phi_nodes (basic_block bb)
1077 gcc_assert (EDGE_COUNT (bb->preds) <= 2);
1079 if (bb->preds->length () == 1)
1080 return false;
1082 unsigned depth = loop_depth (bb->loop_father);
1084 edge preds[2] = { (*bb->preds)[0], (*bb->preds)[1] };
1086 if (depth > loop_depth (preds[0]->src->loop_father)
1087 || depth > loop_depth (preds[1]->src->loop_father))
1088 return true;
1090 /* When one of the edges correspond to the same loop father and other
1091 doesn't. */
1092 if (bb->loop_father != preds[0]->src->loop_father
1093 && bb->loop_father == preds[1]->src->loop_father)
1094 return true;
1096 if (bb->loop_father != preds[1]->src->loop_father
1097 && bb->loop_father == preds[0]->src->loop_father)
1098 return true;
1100 return false;
1103 /* Check if USE is defined in a basic block from where the definition of USE can
1104 propagate from all the paths. FIXME: Verify checks for virtual operands. */
1106 static bool
1107 is_loop_closed_ssa_use (basic_block bb, tree use)
1109 if (TREE_CODE (use) != SSA_NAME || virtual_operand_p (use))
1110 return true;
1112 /* For close-phi nodes def always comes from a loop which has a back-edge. */
1113 if (bb_contains_loop_close_phi_nodes (bb))
1114 return true;
1116 gimple *def = SSA_NAME_DEF_STMT (use);
1117 basic_block def_bb = gimple_bb (def);
1118 return (!def_bb
1119 || flow_bb_inside_loop_p (def_bb->loop_father, bb));
1122 /* Return the number of phi nodes in BB. */
1124 static int
1125 number_of_phi_nodes (basic_block bb)
1127 int num_phis = 0;
1128 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1129 gsi_next (&psi))
1130 num_phis++;
1131 return num_phis;
1134 /* Returns true if BB uses name in one of its PHIs. */
1136 static bool
1137 phi_uses_name (basic_block bb, tree name)
1139 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1140 gsi_next (&psi))
1142 gphi *phi = psi.phi ();
1143 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
1145 tree use_arg = gimple_phi_arg_def (phi, i);
1146 if (use_arg == name)
1147 return true;
1150 return false;
1153 /* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
1154 definition should flow into use, and the use should respect the loop-closed
1155 SSA form. */
1157 bool translate_isl_ast_to_gimple::
1158 is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
1159 phi_node_kind phi_kind, tree old_name, basic_block old_bb) const
1161 /* The def of the rename must either dominate the uses or come from a
1162 back-edge. Also the def must respect the loop closed ssa form. */
1163 if (!is_loop_closed_ssa_use (use_bb, rename))
1165 if (dump_file)
1167 fprintf (dump_file, "[codegen] rename not in loop closed ssa: ");
1168 print_generic_expr (dump_file, rename, 0);
1169 fprintf (dump_file, "\n");
1171 return false;
1174 if (dominated_by_p (CDI_DOMINATORS, use_bb, def_bb))
1175 return true;
1177 if (bb_contains_loop_phi_nodes (use_bb) && phi_kind == loop_phi)
1179 /* The loop-header dominates the loop-body. */
1180 if (!dominated_by_p (CDI_DOMINATORS, def_bb, use_bb))
1181 return false;
1183 /* RENAME would be used in loop-phi. */
1184 gcc_assert (number_of_phi_nodes (use_bb));
1186 /* For definitions coming from back edges, we should check that
1187 old_name is used in a loop PHI node.
1188 FIXME: Verify if this is true. */
1189 if (phi_uses_name (old_bb, old_name))
1190 return true;
1192 return false;
1195 /* Returns the expression associated to OLD_NAME (which is used in OLD_BB), in
1196 NEW_BB from RENAME_MAP. PHI_KIND determines the kind of phi node. */
1198 tree translate_isl_ast_to_gimple::
1199 get_rename (basic_block new_bb, tree old_name, basic_block old_bb,
1200 phi_node_kind phi_kind) const
1202 gcc_assert (TREE_CODE (old_name) == SSA_NAME);
1203 vec <tree> *renames = region->rename_map->get (old_name);
1205 if (!renames || renames->is_empty ())
1206 return NULL_TREE;
1208 if (1 == renames->length ())
1210 tree rename = (*renames)[0];
1211 if (TREE_CODE (rename) == SSA_NAME)
1213 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (rename));
1214 if (is_valid_rename (rename, bb, new_bb, phi_kind, old_name, old_bb)
1215 && (phi_kind == close_phi
1216 || flow_bb_inside_loop_p (bb->loop_father, new_bb)))
1217 return rename;
1218 return NULL_TREE;
1221 if (is_constant (rename))
1222 return rename;
1224 return NULL_TREE;
1227 /* More than one renames corresponding to the old_name. Find the rename for
1228 which the definition flows into usage at new_bb. */
1229 int i;
1230 tree t1 = NULL_TREE, t2;
1231 basic_block t1_bb = NULL;
1232 FOR_EACH_VEC_ELT (*renames, i, t2)
1234 basic_block t2_bb = gimple_bb (SSA_NAME_DEF_STMT (t2));
1236 /* Defined in the same basic block as used. */
1237 if (t2_bb == new_bb)
1238 return t2;
1240 /* NEW_BB and T2_BB are in two unrelated if-clauses. */
1241 if (!dominated_by_p (CDI_DOMINATORS, new_bb, t2_bb))
1242 continue;
1244 if (!flow_bb_inside_loop_p (t2_bb->loop_father, new_bb))
1245 continue;
1247 /* Compute the nearest dominator. */
1248 if (!t1 || dominated_by_p (CDI_DOMINATORS, t2_bb, t1_bb))
1250 t1_bb = t2_bb;
1251 t1 = t2;
1255 return t1;
1258 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
1259 When OLD_NAME and EXPR are the same we assert. */
1261 void translate_isl_ast_to_gimple::
1262 set_rename (tree old_name, tree expr)
1264 if (dump_file)
1266 fprintf (dump_file, "[codegen] setting rename: old_name = ");
1267 print_generic_expr (dump_file, old_name, 0);
1268 fprintf (dump_file, ", new_name = ");
1269 print_generic_expr (dump_file, expr, 0);
1270 fprintf (dump_file, "\n");
1273 if (old_name == expr)
1274 return;
1276 vec <tree> *renames = region->rename_map->get (old_name);
1278 if (renames)
1279 renames->safe_push (expr);
1280 else
1282 vec<tree> r;
1283 r.create (2);
1284 r.safe_push (expr);
1285 region->rename_map->put (old_name, r);
1288 tree t;
1289 int i;
1290 /* For a parameter of a scop we don't want to rename it. */
1291 FOR_EACH_VEC_ELT (region->params, i, t)
1292 if (old_name == t)
1293 region->parameter_rename_map->put(old_name, expr);
1296 /* Return an iterator to the instructions comes last in the execution order.
1297 Either GSI1 and GSI2 should belong to the same basic block or one of their
1298 respective basic blocks should dominate the other. */
1300 gimple_stmt_iterator
1301 later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
1303 basic_block bb1 = gsi_bb (gsi1);
1304 basic_block bb2 = gsi_bb (gsi2);
1306 /* Find the iterator which is the latest. */
1307 if (bb1 == bb2)
1309 /* For empty basic blocks gsis point to the end of the sequence. Since
1310 there is no operator== defined for gimple_stmt_iterator and for gsis
1311 not pointing to a valid statement gsi_next would assert. */
1312 gimple_stmt_iterator gsi = gsi1;
1313 do {
1314 if (gsi_stmt (gsi) == gsi_stmt (gsi2))
1315 return gsi2;
1316 gsi_next (&gsi);
1317 } while (!gsi_end_p (gsi));
1319 return gsi1;
1322 /* Find the basic block closest to the basic block which defines stmt. */
1323 if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
1324 return gsi1;
1326 gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
1327 return gsi2;
1330 /* Insert each statement from SEQ at its earliest insertion p. */
1332 void translate_isl_ast_to_gimple::
1333 gsi_insert_earliest (gimple_seq seq)
1335 update_modified_stmts (seq);
1336 sese_l &codegen_region = region->if_region->true_region->region;
1337 basic_block begin_bb = get_entry_bb (codegen_region);
1339 /* Inserting the gimple statements in a vector because gimple_seq behave
1340 in strage ways when inserting the stmts from it into different basic
1341 blocks one at a time. */
1342 auto_vec<gimple *, 3> stmts;
1343 for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
1344 gsi_next (&gsi))
1345 stmts.safe_push (gsi_stmt (gsi));
1347 int i;
1348 gimple *use_stmt;
1349 FOR_EACH_VEC_ELT (stmts, i, use_stmt)
1351 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1352 gimple_stmt_iterator gsi_def_stmt = gsi_start_bb_nondebug (begin_bb);
1354 use_operand_p use_p;
1355 ssa_op_iter op_iter;
1356 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
1358 /* Iterator to the current def of use_p. For function parameters or
1359 anything where def is not found, insert at the beginning of the
1360 generated region. */
1361 gimple_stmt_iterator gsi_stmt = gsi_def_stmt;
1363 tree op = USE_FROM_PTR (use_p);
1364 gimple *stmt = SSA_NAME_DEF_STMT (op);
1365 if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
1366 gsi_stmt = gsi_for_stmt (stmt);
1368 /* For region parameters, insert at the beginning of the generated
1369 region. */
1370 if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
1371 gsi_stmt = gsi_def_stmt;
1373 gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
1376 if (!gsi_stmt (gsi_def_stmt))
1378 gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
1379 gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
1381 else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
1383 gimple_stmt_iterator bsi
1384 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt));
1385 /* Insert right after the PHI statements. */
1386 gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
1388 else
1389 gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);
1391 if (dump_file)
1393 fprintf (dump_file, "[codegen] inserting statement: ");
1394 print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
1395 print_loops_bb (dump_file, gimple_bb (use_stmt), 0, 3);
1400 /* Collect all the operands of NEW_EXPR by recursively visiting each
1401 operand. */
1403 void translate_isl_ast_to_gimple::
1404 collect_all_ssa_names (tree new_expr, vec<tree> *vec_ssa)
1407 /* Rename all uses in new_expr. */
1408 if (TREE_CODE (new_expr) == SSA_NAME)
1410 vec_ssa->safe_push (new_expr);
1411 return;
1414 /* Iterate over SSA_NAMES in NEW_EXPR. */
1415 for (int i = 0; i < (TREE_CODE_LENGTH (TREE_CODE (new_expr))); i++)
1417 tree op = TREE_OPERAND (new_expr, i);
1418 collect_all_ssa_names (op, vec_ssa);
1422 /* This is abridged version of the function copied from:
1423 tree.c:substitute_in_expr (tree exp, tree f, tree r). */
1425 static tree
1426 substitute_ssa_name (tree exp, tree f, tree r)
1428 enum tree_code code = TREE_CODE (exp);
1429 tree op0, op1, op2, op3;
1430 tree new_tree;
1432 /* We handle TREE_LIST and COMPONENT_REF separately. */
1433 if (code == TREE_LIST)
1435 op0 = substitute_ssa_name (TREE_CHAIN (exp), f, r);
1436 op1 = substitute_ssa_name (TREE_VALUE (exp), f, r);
1437 if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
1438 return exp;
1440 return tree_cons (TREE_PURPOSE (exp), op1, op0);
1442 else if (code == COMPONENT_REF)
1444 tree inner;
1446 /* If this expression is getting a value from a PLACEHOLDER_EXPR
1447 and it is the right field, replace it with R. */
1448 for (inner = TREE_OPERAND (exp, 0);
1449 REFERENCE_CLASS_P (inner);
1450 inner = TREE_OPERAND (inner, 0))
1453 /* The field. */
1454 op1 = TREE_OPERAND (exp, 1);
1456 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
1457 return r;
1459 /* If this expression hasn't been completed let, leave it alone. */
1460 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
1461 return exp;
1463 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1464 if (op0 == TREE_OPERAND (exp, 0))
1465 return exp;
1467 new_tree
1468 = fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
1470 else
1471 switch (TREE_CODE_CLASS (code))
1473 case tcc_constant:
1474 return exp;
1476 case tcc_declaration:
1477 if (exp == f)
1478 return r;
1479 else
1480 return exp;
1482 case tcc_expression:
1483 if (exp == f)
1484 return r;
1486 /* Fall through... */
1488 case tcc_exceptional:
1489 case tcc_unary:
1490 case tcc_binary:
1491 case tcc_comparison:
1492 case tcc_reference:
1493 switch (TREE_CODE_LENGTH (code))
1495 case 0:
1496 if (exp == f)
1497 return r;
1498 return exp;
1500 case 1:
1501 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1502 if (op0 == TREE_OPERAND (exp, 0))
1503 return exp;
1505 new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
1506 break;
1508 case 2:
1509 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1510 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1512 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
1513 return exp;
1515 new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
1516 break;
1518 case 3:
1519 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1520 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1521 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1523 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1524 && op2 == TREE_OPERAND (exp, 2))
1525 return exp;
1527 new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
1528 break;
1530 case 4:
1531 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1532 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1533 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1534 op3 = substitute_ssa_name (TREE_OPERAND (exp, 3), f, r);
1536 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1537 && op2 == TREE_OPERAND (exp, 2)
1538 && op3 == TREE_OPERAND (exp, 3))
1539 return exp;
1541 new_tree
1542 = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
1543 break;
1545 default:
1546 gcc_unreachable ();
1548 break;
1550 case tcc_vl_exp:
1551 default:
1552 gcc_unreachable ();
1555 TREE_READONLY (new_tree) |= TREE_READONLY (exp);
1557 if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
1558 TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
1560 return new_tree;
1563 /* Rename all the operands of NEW_EXPR by recursively visiting each operand. */
1565 tree translate_isl_ast_to_gimple::
1566 rename_all_uses (tree new_expr, basic_block new_bb, basic_block old_bb)
1568 auto_vec<tree, 2> ssa_names;
1569 collect_all_ssa_names (new_expr, &ssa_names);
1570 tree t;
1571 int i;
1572 FOR_EACH_VEC_ELT (ssa_names, i, t)
1573 if (tree r = get_rename (new_bb, t, old_bb, unknown_phi))
1574 new_expr = substitute_ssa_name (new_expr, t, r);
1576 return new_expr;
1579 /* For ops which are scev_analyzeable, we can regenerate a new name from its
1580 scalar evolution around LOOP. */
1582 tree translate_isl_ast_to_gimple::
1583 get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
1584 basic_block new_bb, basic_block old_bb,
1585 vec<tree> iv_map)
1587 tree scev = scalar_evolution_in_region (region->region, loop, old_name);
1589 /* At this point we should know the exact scev for each
1590 scalar SSA_NAME used in the scop: all the other scalar
1591 SSA_NAMEs should have been translated out of SSA using
1592 arrays with one element. */
1593 tree new_expr;
1594 if (chrec_contains_undetermined (scev))
1596 codegen_error = true;
1597 return build_zero_cst (TREE_TYPE (old_name));
1600 new_expr = chrec_apply_map (scev, iv_map);
1602 /* The apply should produce an expression tree containing
1603 the uses of the new induction variables. We should be
1604 able to use new_expr instead of the old_name in the newly
1605 generated loop nest. */
1606 if (chrec_contains_undetermined (new_expr)
1607 || tree_contains_chrecs (new_expr, NULL))
1609 codegen_error = true;
1610 return build_zero_cst (TREE_TYPE (old_name));
1613 if (TREE_CODE (new_expr) == SSA_NAME)
1615 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_expr));
1616 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1618 codegen_error = true;
1619 return build_zero_cst (TREE_TYPE (old_name));
1623 new_expr = rename_all_uses (new_expr, new_bb, old_bb);
1625 /* We check all the operands and all of them should dominate the use at
1626 new_expr. */
1627 auto_vec <tree, 2> new_ssa_names;
1628 collect_all_ssa_names (new_expr, &new_ssa_names);
1629 int i;
1630 tree new_ssa_name;
1631 FOR_EACH_VEC_ELT (new_ssa_names, i, new_ssa_name)
1633 if (TREE_CODE (new_ssa_name) == SSA_NAME)
1635 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_ssa_name));
1636 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1638 codegen_error = true;
1639 return build_zero_cst (TREE_TYPE (old_name));
1644 /* Replace the old_name with the new_expr. */
1645 return force_gimple_operand (unshare_expr (new_expr), stmts,
1646 true, NULL_TREE);
1649 /* Renames the scalar uses of the statement COPY, using the
1650 substitution map RENAME_MAP, inserting the gimplification code at
1651 GSI_TGT, for the translation REGION, with the original copied
1652 statement in LOOP, and using the induction variable renaming map
1653 IV_MAP. Returns true when something has been renamed. */
1655 bool translate_isl_ast_to_gimple::
1656 rename_uses (gimple *copy, gimple_stmt_iterator *gsi_tgt, basic_block old_bb,
1657 loop_p loop, vec<tree> iv_map)
1659 bool changed = false;
1661 if (is_gimple_debug (copy))
1663 if (gimple_debug_bind_p (copy))
1664 gimple_debug_bind_reset_value (copy);
1665 else if (gimple_debug_source_bind_p (copy))
1666 return false;
1667 else
1668 gcc_unreachable ();
1670 return false;
1673 if (dump_file)
1675 fprintf (dump_file, "[codegen] renaming uses of stmt: ");
1676 print_gimple_stmt (dump_file, copy, 0, 0);
1679 use_operand_p use_p;
1680 ssa_op_iter op_iter;
1681 FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_USE)
1683 tree old_name = USE_FROM_PTR (use_p);
1685 if (dump_file)
1687 fprintf (dump_file, "[codegen] renaming old_name = ");
1688 print_generic_expr (dump_file, old_name, 0);
1689 fprintf (dump_file, "\n");
1692 if (TREE_CODE (old_name) != SSA_NAME
1693 || SSA_NAME_IS_DEFAULT_DEF (old_name))
1694 continue;
1696 changed = true;
1697 tree new_expr = get_rename (gsi_tgt->bb, old_name,
1698 old_bb, unknown_phi);
1700 if (new_expr)
1702 tree type_old_name = TREE_TYPE (old_name);
1703 tree type_new_expr = TREE_TYPE (new_expr);
1705 if (dump_file)
1707 fprintf (dump_file, "[codegen] from rename_map: new_name = ");
1708 print_generic_expr (dump_file, new_expr, 0);
1709 fprintf (dump_file, "\n");
1712 if (type_old_name != type_new_expr
1713 || TREE_CODE (new_expr) != SSA_NAME)
1715 tree var = create_tmp_var (type_old_name, "var");
1717 if (!useless_type_conversion_p (type_old_name, type_new_expr))
1718 new_expr = fold_convert (type_old_name, new_expr);
1720 gimple_seq stmts;
1721 new_expr = force_gimple_operand (new_expr, &stmts, true, var);
1722 gsi_insert_earliest (stmts);
1725 replace_exp (use_p, new_expr);
1726 continue;
1729 gimple_seq stmts;
1730 new_expr = get_rename_from_scev (old_name, &stmts, loop, gimple_bb (copy),
1731 old_bb, iv_map);
1732 if (!new_expr || codegen_error_p ())
1733 return false;
1735 if (dump_file)
1737 fprintf (dump_file, "[codegen] not in rename map, scev: ");
1738 print_generic_expr (dump_file, new_expr, 0);
1739 fprintf (dump_file, "\n");
1742 gsi_insert_earliest (stmts);
1743 replace_exp (use_p, new_expr);
1745 if (TREE_CODE (new_expr) == INTEGER_CST
1746 && is_gimple_assign (copy))
1748 tree rhs = gimple_assign_rhs1 (copy);
1750 if (TREE_CODE (rhs) == ADDR_EXPR)
1751 recompute_tree_invariant_for_addr_expr (rhs);
1754 set_rename (old_name, new_expr);
1757 return changed;
1760 /* Returns a basic block that could correspond to where a constant was defined
1761 in the original code. In the original code OLD_BB had the definition, we
1762 need to find which basic block out of the copies of old_bb, in the new
1763 region, should a definition correspond to if it has to reach BB. */
1765 basic_block translate_isl_ast_to_gimple::
1766 get_def_bb_for_const (basic_block bb, basic_block old_bb) const
1768 vec <basic_block> *bbs = region->copied_bb_map->get (old_bb);
1770 if (!bbs || bbs->is_empty ())
1771 return NULL;
1773 if (1 == bbs->length ())
1774 return (*bbs)[0];
1776 int i;
1777 basic_block b1 = NULL, b2;
1778 FOR_EACH_VEC_ELT (*bbs, i, b2)
1780 if (b2 == bb)
1781 return bb;
1783 /* BB and B2 are in two unrelated if-clauses. */
1784 if (!dominated_by_p (CDI_DOMINATORS, bb, b2))
1785 continue;
1787 /* Compute the nearest dominator. */
1788 if (!b1 || dominated_by_p (CDI_DOMINATORS, b2, b1))
1789 b1 = b2;
1792 gcc_assert (b1);
1793 return b1;
1796 /* Get the new name of OP (from OLD_BB) to be used in NEW_BB. PHI_KIND
1797 determines the kind of phi node. */
1799 tree translate_isl_ast_to_gimple::
1800 get_new_name (basic_block new_bb, tree op,
1801 basic_block old_bb, phi_node_kind phi_kind) const
1803 /* For constants the names are the same. */
1804 if (is_constant (op))
1805 return op;
1807 return get_rename (new_bb, op, old_bb, phi_kind);
1810 /* Return a debug location for OP. */
1812 static location_t
1813 get_loc (tree op)
1815 location_t loc = UNKNOWN_LOCATION;
1817 if (TREE_CODE (op) == SSA_NAME)
1818 loc = gimple_location (SSA_NAME_DEF_STMT (op));
1819 return loc;
1822 /* Returns the incoming edges of basic_block BB in the pair. The first edge is
1823 the init edge (from outside the loop) and the second one is the back edge
1824 from the same loop. */
1826 std::pair<edge, edge>
1827 get_edges (basic_block bb)
1829 std::pair<edge, edge> edges;
1830 edge e;
1831 edge_iterator ei;
1832 FOR_EACH_EDGE (e, ei, bb->preds)
1833 if (bb->loop_father != e->src->loop_father)
1834 edges.first = e;
1835 else
1836 edges.second = e;
1837 return edges;
1840 /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI
1841 must be found unless they can be POSTPONEd for later. */
1843 bool translate_isl_ast_to_gimple::
1844 copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
1845 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
1846 bool postpone)
1848 gcc_assert (gimple_phi_num_args (old_phi) == gimple_phi_num_args (new_phi));
1850 basic_block new_bb = gimple_bb (new_phi);
1851 for (unsigned i = 0; i < gimple_phi_num_args (old_phi); i++)
1853 edge e;
1854 if (gimple_phi_arg_edge (old_phi, i) == ibp_old_bb.first)
1855 e = ibp_new_bb.first;
1856 else
1857 e = ibp_new_bb.second;
1859 tree old_name = gimple_phi_arg_def (old_phi, i);
1860 tree new_name = get_new_name (new_bb, old_name,
1861 gimple_bb (old_phi), loop_phi);
1862 if (new_name)
1864 add_phi_arg (new_phi, new_name, e, get_loc (old_name));
1865 continue;
1868 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
1869 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
1870 /* If the phi arg was a function arg, or wasn't defined, just use the
1871 old name. */
1872 add_phi_arg (new_phi, old_name, e, get_loc (old_name));
1873 else if (postpone)
1875 /* Postpone code gen for later for those back-edges we don't have the
1876 names yet. */
1877 region->incomplete_phis.safe_push (std::make_pair (old_phi, new_phi));
1878 if (dump_file)
1879 fprintf (dump_file, "[codegen] postpone loop phi nodes.\n");
1881 else
1882 /* Either we should add the arg to phi or, we should postpone. */
1883 return false;
1885 return true;
1888 /* Copy loop phi nodes from BB to NEW_BB. */
1890 bool translate_isl_ast_to_gimple::
1891 copy_loop_phi_nodes (basic_block bb, basic_block new_bb)
1893 if (dump_file)
1894 fprintf (dump_file, "[codegen] copying loop phi nodes in bb_%d.\n",
1895 new_bb->index);
1897 /* Loop phi nodes should have only two arguments. */
1898 gcc_assert (2 == EDGE_COUNT (bb->preds));
1900 /* First edge is the init edge and second is the back edge. */
1901 init_back_edge_pair_t ibp_old_bb = get_edges (bb);
1903 /* First edge is the init edge and second is the back edge. */
1904 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
1906 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1907 gsi_next (&psi))
1909 gphi *phi = psi.phi ();
1910 tree res = gimple_phi_result (phi);
1911 if (virtual_operand_p (res))
1912 continue;
1913 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
1914 continue;
1916 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
1917 tree new_res = create_new_def_for (res, new_phi,
1918 gimple_phi_result_ptr (new_phi));
1919 set_rename (res, new_res);
1920 codegen_error = !copy_loop_phi_args (phi, ibp_old_bb, new_phi,
1921 ibp_new_bb, true);
1922 update_stmt (new_phi);
1924 if (dump_file)
1926 fprintf (dump_file, "[codegen] creating loop-phi node: ");
1927 print_gimple_stmt (dump_file, new_phi, 0, 0);
1931 return true;
1934 /* Return the init value of PHI, the value coming from outside the loop. */
1936 static tree
1937 get_loop_init_value (gphi *phi)
1940 loop_p loop = gimple_bb (phi)->loop_father;
1942 edge e;
1943 edge_iterator ei;
1944 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
1945 if (e->src->loop_father != loop)
1946 return gimple_phi_arg_def (phi, e->dest_idx);
1948 return NULL_TREE;
1951 /* Find the init value (the value which comes from outside the loop), of one of
1952 the operands of DEF which is defined by a loop phi. */
1954 static tree
1955 find_init_value (gimple *def)
1957 if (gimple_code (def) == GIMPLE_PHI)
1958 return get_loop_init_value (as_a <gphi*> (def));
1960 if (gimple_vuse (def))
1961 return NULL_TREE;
1963 ssa_op_iter iter;
1964 use_operand_p use_p;
1965 FOR_EACH_SSA_USE_OPERAND (use_p, def, iter, SSA_OP_USE)
1967 tree use = USE_FROM_PTR (use_p);
1968 if (TREE_CODE (use) == SSA_NAME)
1970 if (tree res = find_init_value (SSA_NAME_DEF_STMT (use)))
1971 return res;
1975 return NULL_TREE;
1978 /* Return the init value, the value coming from outside the loop. */
1980 static tree
1981 find_init_value_close_phi (gphi *phi)
1983 gcc_assert (gimple_phi_num_args (phi) == 1);
1984 tree use_arg = gimple_phi_arg_def (phi, 0);
1985 gimple *def = SSA_NAME_DEF_STMT (use_arg);
1986 return find_init_value (def);
1990 tree translate_isl_ast_to_gimple::
1991 add_close_phis_to_outer_loops (tree last_merge_name, edge last_e,
1992 gimple *old_close_phi)
1994 sese_l &codegen_region = region->if_region->true_region->region;
1995 gimple *stmt = SSA_NAME_DEF_STMT (last_merge_name);
1996 basic_block bb = gimple_bb (stmt);
1997 if (!bb_in_sese_p (bb, codegen_region))
1998 return last_merge_name;
2000 loop_p loop = bb->loop_father;
2001 if (!loop_in_sese_p (loop, codegen_region))
2002 return last_merge_name;
2004 edge e = single_exit (loop);
2006 if (dominated_by_p (CDI_DOMINATORS, e->dest, last_e->src))
2007 return last_merge_name;
2009 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2010 tree old_close_phi_name = gimple_phi_result (old_close_phi);
2012 bb = e->dest;
2013 if (!bb_contains_loop_close_phi_nodes (bb) || !single_succ_p (bb))
2014 bb = split_edge (e);
2016 gphi *close_phi = create_phi_node (SSA_NAME_VAR (last_merge_name), bb);
2017 tree res = create_new_def_for (last_merge_name, close_phi,
2018 gimple_phi_result_ptr (close_phi));
2019 set_rename (old_close_phi_name, res);
2020 add_phi_arg (close_phi, last_merge_name, e, get_loc (old_name));
2021 last_merge_name = res;
2023 return add_close_phis_to_outer_loops (last_merge_name, last_e, old_close_phi);
2026 /* Add phi nodes to all merge points of all the diamonds enclosing the loop of
2027 the close phi node PHI. */
2029 bool translate_isl_ast_to_gimple::
2030 add_close_phis_to_merge_points (gphi *old_close_phi, gphi *new_close_phi,
2031 tree default_value)
2033 sese_l &codegen_region = region->if_region->true_region->region;
2034 basic_block default_value_bb = get_entry_bb (codegen_region);
2035 if (SSA_NAME == TREE_CODE (default_value))
2037 gimple *stmt = SSA_NAME_DEF_STMT (default_value);
2038 if (!stmt || gimple_code (stmt) == GIMPLE_NOP)
2039 return false;
2040 default_value_bb = gimple_bb (stmt);
2043 basic_block new_close_phi_bb = gimple_bb (new_close_phi);
2045 tree old_close_phi_name = gimple_phi_result (old_close_phi);
2046 tree new_close_phi_name = gimple_phi_result (new_close_phi);
2047 tree last_merge_name = new_close_phi_name;
2048 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2050 int i;
2051 edge merge_e;
2052 FOR_EACH_VEC_ELT_REVERSE (merge_points, i, merge_e)
2054 basic_block new_merge_bb = merge_e->src;
2055 if (!dominated_by_p (CDI_DOMINATORS, new_merge_bb, default_value_bb))
2056 continue;
2058 last_merge_name = add_close_phis_to_outer_loops (last_merge_name, merge_e,
2059 old_close_phi);
2061 gphi *merge_phi = create_phi_node (SSA_NAME_VAR (old_close_phi_name), new_merge_bb);
2062 tree merge_res = create_new_def_for (old_close_phi_name, merge_phi,
2063 gimple_phi_result_ptr (merge_phi));
2064 set_rename (old_close_phi_name, merge_res);
2066 edge from_loop = NULL, from_default_value = NULL;
2067 edge e;
2068 edge_iterator ei;
2069 FOR_EACH_EDGE (e, ei, new_merge_bb->preds)
2070 if (dominated_by_p (CDI_DOMINATORS, e->src, new_close_phi_bb))
2071 from_loop = e;
2072 else
2073 from_default_value = e;
2075 /* Because CDI_POST_DOMINATORS are not updated, we only rely on
2076 CDI_DOMINATORS, which may not handle all cases where new_close_phi_bb
2077 is contained in another condition. */
2078 if (!from_default_value || !from_loop)
2079 return false;
2081 add_phi_arg (merge_phi, last_merge_name, from_loop, get_loc (old_name));
2082 add_phi_arg (merge_phi, default_value, from_default_value, get_loc (old_name));
2084 if (dump_file)
2086 fprintf (dump_file, "[codegen] Adding guard-phi: ");
2087 print_gimple_stmt (dump_file, merge_phi, 0, 0);
2090 update_stmt (merge_phi);
2091 last_merge_name = merge_res;
2094 return true;
2097 /* Copy all the loop-close phi args from BB to NEW_BB. */
2099 bool translate_isl_ast_to_gimple::
2100 copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb, bool postpone)
2102 for (gphi_iterator psi = gsi_start_phis (old_bb); !gsi_end_p (psi);
2103 gsi_next (&psi))
2105 gphi *old_close_phi = psi.phi ();
2106 tree res = gimple_phi_result (old_close_phi);
2107 if (virtual_operand_p (res))
2108 continue;
2110 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2111 /* Loop close phi nodes should not be scev_analyzable_p. */
2112 gcc_unreachable ();
2114 gphi *new_close_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
2115 tree new_res = create_new_def_for (res, new_close_phi,
2116 gimple_phi_result_ptr (new_close_phi));
2117 set_rename (res, new_res);
2119 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2120 tree new_name = get_new_name (new_bb, old_name, old_bb, close_phi);
2122 /* Predecessor basic blocks of a loop close phi should have been code
2123 generated before. FIXME: This is fixable by merging PHIs from inner
2124 loops as well. See: gfortran.dg/graphite/interchange-3.f90. */
2125 if (!new_name)
2126 return false;
2128 add_phi_arg (new_close_phi, new_name, single_pred_edge (new_bb),
2129 get_loc (old_name));
2130 if (dump_file)
2132 fprintf (dump_file, "[codegen] Adding loop close phi: ");
2133 print_gimple_stmt (dump_file, new_close_phi, 0, 0);
2136 update_stmt (new_close_phi);
2138 /* When there is no loop guard around this codegenerated loop, there is no
2139 need to collect the close-phi arg. */
2140 if (merge_points.is_empty ())
2141 continue;
2143 /* Add a PHI in the succ_new_bb for each close phi of the loop. */
2144 tree default_value = find_init_value_close_phi (new_close_phi);
2146 /* A close phi must come from a loop-phi having a default value. */
2147 if (!default_value)
2149 if (!postpone)
2150 return false;
2152 region->incomplete_phis.safe_push (std::make_pair (old_close_phi,
2153 new_close_phi));
2154 if (dump_file)
2156 fprintf (dump_file, "[codegen] postpone close phi nodes: ");
2157 print_gimple_stmt (dump_file, new_close_phi, 0, 0);
2159 continue;
2162 if (!add_close_phis_to_merge_points (old_close_phi, new_close_phi,
2163 default_value))
2164 return false;
2167 return true;
2170 /* Copy loop close phi nodes from BB to NEW_BB. */
2172 bool translate_isl_ast_to_gimple::
2173 copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb)
2175 if (dump_file)
2176 fprintf (dump_file, "[codegen] copying loop close phi nodes in bb_%d.\n",
2177 new_bb->index);
2178 /* Loop close phi nodes should have only one argument. */
2179 gcc_assert (1 == EDGE_COUNT (old_bb->preds));
2181 return copy_loop_close_phi_args (old_bb, new_bb, true);
2185 /* Add NEW_NAME as the ARGNUM-th arg of NEW_PHI which is in NEW_BB.
2186 DOMINATING_PRED is the predecessor basic block of OLD_BB which dominates the
2187 other pred of OLD_BB as well. If no such basic block exists then it is NULL.
2188 NON_DOMINATING_PRED is a pred which does not dominate OLD_BB, it cannot be
2189 NULL.
2191 Case1: OLD_BB->preds {BB1, BB2} and BB1 does not dominate BB2 and vice versa.
2192 In this case DOMINATING_PRED = NULL.
2194 Case2: OLD_BB->preds {BB1, BB2} and BB1 dominates BB2.
2196 Returns true on successful copy of the args, false otherwise. */
2198 bool translate_isl_ast_to_gimple::
2199 add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
2200 edge old_bb_dominating_edge,
2201 edge old_bb_non_dominating_edge,
2202 gphi *phi, gphi *new_phi,
2203 basic_block new_bb)
2205 basic_block def_pred[2] = { NULL, NULL };
2206 int not_found_bb_index = -1;
2207 for (int i = 0; i < 2; i++)
2209 /* If the corresponding def_bb could not be found the entry will be
2210 NULL. */
2211 if (TREE_CODE (old_phi_args[i]) == INTEGER_CST)
2212 def_pred[i] = get_def_bb_for_const (new_bb,
2213 gimple_phi_arg_edge (phi, i)->src);
2214 else if (new_phi_args[i] && (TREE_CODE (new_phi_args[i]) == SSA_NAME))
2215 def_pred[i] = gimple_bb (SSA_NAME_DEF_STMT (new_phi_args[i]));
2217 if (!def_pred[i])
2219 /* When non are available bail out. */
2220 if (not_found_bb_index != -1)
2221 return false;
2222 not_found_bb_index = i;
2226 /* Here we are pattern matching on the structure of CFG w.r.t. old one. */
2227 if (old_bb_dominating_edge)
2229 if (not_found_bb_index != -1)
2230 return false;
2232 basic_block new_pred1 = (*new_bb->preds)[0]->src;
2233 basic_block new_pred2 = (*new_bb->preds)[1]->src;
2234 vec <basic_block> *bbs
2235 = region->copied_bb_map->get (old_bb_non_dominating_edge->src);
2237 /* Could not find a mapping. */
2238 if (!bbs)
2239 return false;
2241 basic_block new_pred = NULL;
2242 basic_block b;
2243 int i;
2244 FOR_EACH_VEC_ELT (*bbs, i, b)
2246 if (dominated_by_p (CDI_DOMINATORS, new_pred1, b))
2248 /* FIXME: If we have already found new_pred then we have to
2249 disambiguate, bail out for now. */
2250 if (new_pred)
2251 return false;
2252 new_pred = new_pred1;
2254 if (dominated_by_p (CDI_DOMINATORS, new_pred2, b))
2256 /* FIXME: If we have already found new_pred then we have to either
2257 it dominates both or we have to disambiguate, bail out. */
2258 if (new_pred)
2259 return false;
2260 new_pred = new_pred2;
2264 if (!new_pred)
2265 return false;
2267 edge new_non_dominating_edge = find_edge (new_pred, new_bb);
2268 gcc_assert (new_non_dominating_edge);
2269 /* FIXME: Validate each args just like in loop-phis. */
2270 /* By the process of elimination we first insert insert phi-edge for
2271 non-dominating pred which is computed above and then we insert the
2272 remaining one. */
2273 int inserted_edge = 0;
2274 for (; inserted_edge < 2; inserted_edge++)
2276 edge new_bb_pred_edge = gimple_phi_arg_edge (new_phi, inserted_edge);
2277 if (new_non_dominating_edge == new_bb_pred_edge)
2279 add_phi_arg (new_phi, new_phi_args[inserted_edge],
2280 new_non_dominating_edge,
2281 get_loc (old_phi_args[inserted_edge]));
2282 break;
2285 if (inserted_edge == 2)
2286 return false;
2288 int edge_dominating = inserted_edge == 0 ? 1 : 0;
2290 edge new_dominating_edge = NULL;
2291 for (inserted_edge = 0; inserted_edge < 2; inserted_edge++)
2293 edge e = gimple_phi_arg_edge (new_phi, inserted_edge);
2294 if (e != new_non_dominating_edge)
2296 new_dominating_edge = e;
2297 add_phi_arg (new_phi, new_phi_args[edge_dominating],
2298 new_dominating_edge,
2299 get_loc (old_phi_args[inserted_edge]));
2300 break;
2303 gcc_assert (new_dominating_edge);
2305 else
2307 /* Classic diamond structure: both edges are non-dominating. We need to
2308 find one unique edge then the other can be found be elimination. If
2309 any definition (def_pred) dominates both the preds of new_bb then we
2310 bail out. Entries of def_pred maybe NULL, in that case we must
2311 uniquely find pred with help of only one entry. */
2312 edge new_e[2] = { NULL, NULL };
2313 for (int i = 0; i < 2; i++)
2315 edge e;
2316 edge_iterator ei;
2317 FOR_EACH_EDGE (e, ei, new_bb->preds)
2318 if (def_pred[i]
2319 && dominated_by_p (CDI_DOMINATORS, e->src, def_pred[i]))
2321 if (new_e[i])
2322 /* We do not know how to handle the case when def_pred
2323 dominates more than a predecessor. */
2324 return false;
2325 new_e[i] = e;
2329 gcc_assert (new_e[0] || new_e[1]);
2331 /* Find the other edge by process of elimination. */
2332 if (not_found_bb_index != -1)
2334 gcc_assert (!new_e[not_found_bb_index]);
2335 int found_bb_index = not_found_bb_index == 1 ? 0 : 1;
2336 edge e;
2337 edge_iterator ei;
2338 FOR_EACH_EDGE (e, ei, new_bb->preds)
2340 if (new_e[found_bb_index] == e)
2341 continue;
2342 new_e[not_found_bb_index] = e;
2346 /* Add edges to phi args. */
2347 for (int i = 0; i < 2; i++)
2348 add_phi_arg (new_phi, new_phi_args[i], new_e[i],
2349 get_loc (old_phi_args[i]));
2352 return true;
2355 /* Copy the arguments of cond-phi node PHI, to NEW_PHI in the codegenerated
2356 region. If postpone is true and it isn't possible to copy any arg of PHI,
2357 the PHI is added to the REGION->INCOMPLETE_PHIS to be codegenerated later.
2358 Returns false if the copying was unsuccessful. */
2360 bool translate_isl_ast_to_gimple::
2361 copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map, bool postpone)
2363 if (dump_file)
2364 fprintf (dump_file, "[codegen] copying cond phi args.\n");
2365 gcc_assert (2 == gimple_phi_num_args (phi));
2367 basic_block new_bb = gimple_bb (new_phi);
2368 loop_p loop = gimple_bb (phi)->loop_father;
2370 basic_block old_bb = gimple_bb (phi);
2371 edge old_bb_non_dominating_edge = NULL, old_bb_dominating_edge = NULL;
2373 edge e;
2374 edge_iterator ei;
2375 FOR_EACH_EDGE (e, ei, old_bb->preds)
2376 if (!dominated_by_p (CDI_DOMINATORS, old_bb, e->src))
2377 old_bb_non_dominating_edge = e;
2378 else
2379 old_bb_dominating_edge = e;
2381 gcc_assert (!dominated_by_p (CDI_DOMINATORS, old_bb,
2382 old_bb_non_dominating_edge->src));
2384 tree new_phi_args[2];
2385 tree old_phi_args[2];
2387 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
2389 tree old_name = gimple_phi_arg_def (phi, i);
2390 tree new_name = get_new_name (new_bb, old_name, old_bb, cond_phi);
2391 old_phi_args[i] = old_name;
2392 if (new_name)
2394 new_phi_args [i] = new_name;
2395 continue;
2398 /* If the phi-arg was a parameter. */
2399 if (vec_find (region->params, old_name) != -1)
2401 new_phi_args [i] = old_name;
2402 if (dump_file)
2404 fprintf (dump_file,
2405 "[codegen] parameter argument to phi, new_expr: ");
2406 print_generic_expr (dump_file, new_phi_args[i], 0);
2407 fprintf (dump_file, "\n");
2409 continue;
2412 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
2413 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
2414 /* FIXME: If the phi arg was a function arg, or wasn't defined, just use
2415 the old name. */
2416 return false;
2418 if (postpone)
2420 /* If the phi-arg is scev-analyzeable but only in the first stage. */
2421 if (is_gimple_reg (old_name)
2422 && scev_analyzable_p (old_name, region->region))
2424 gimple_seq stmts;
2425 tree new_expr = get_rename_from_scev (old_name, &stmts, loop,
2426 new_bb, old_bb, iv_map);
2427 if (codegen_error_p ())
2428 return false;
2430 gcc_assert (new_expr);
2431 if (dump_file)
2433 fprintf (dump_file,
2434 "[codegen] scev analyzeable, new_expr: ");
2435 print_generic_expr (dump_file, new_expr, 0);
2436 fprintf (dump_file, "\n");
2438 gsi_insert_earliest (stmts);
2439 new_phi_args [i] = new_name;
2440 continue;
2443 /* Postpone code gen for later for back-edges. */
2444 region->incomplete_phis.safe_push (std::make_pair (phi, new_phi));
2446 if (dump_file)
2448 fprintf (dump_file, "[codegen] postpone cond phi nodes: ");
2449 print_gimple_stmt (dump_file, new_phi, 0, 0);
2452 new_phi_args [i] = NULL_TREE;
2453 continue;
2455 else
2456 /* Either we should add the arg to phi or, we should postpone. */
2457 return false;
2460 /* If none of the args have been determined in the first stage then wait until
2461 later. */
2462 if (postpone && !new_phi_args[0] && !new_phi_args[1])
2463 return true;
2465 return add_phi_arg_for_new_expr (old_phi_args, new_phi_args,
2466 old_bb_dominating_edge,
2467 old_bb_non_dominating_edge,
2468 phi, new_phi, new_bb);
2471 /* Copy cond phi nodes from BB to NEW_BB. A cond-phi node is a basic block
2472 containing phi nodes coming from two predecessors, and none of them are back
2473 edges. */
2475 bool translate_isl_ast_to_gimple::
2476 copy_cond_phi_nodes (basic_block bb, basic_block new_bb, vec<tree> iv_map)
2479 gcc_assert (!bb_contains_loop_close_phi_nodes (bb));
2481 if (dump_file)
2482 fprintf (dump_file, "[codegen] copying cond phi nodes in bb_%d.\n",
2483 new_bb->index);
2485 /* Cond phi nodes should have exactly two arguments. */
2486 gcc_assert (2 == EDGE_COUNT (bb->preds));
2488 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2489 gsi_next (&psi))
2491 gphi *phi = psi.phi ();
2492 tree res = gimple_phi_result (phi);
2493 if (virtual_operand_p (res))
2494 continue;
2495 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2496 /* Cond phi nodes should not be scev_analyzable_p. */
2497 gcc_unreachable ();
2499 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
2500 tree new_res = create_new_def_for (res, new_phi,
2501 gimple_phi_result_ptr (new_phi));
2502 set_rename (res, new_res);
2504 if (!copy_cond_phi_args (phi, new_phi, iv_map, true))
2505 return false;
2507 update_stmt (new_phi);
2510 return true;
2513 /* Return true if STMT should be copied from region to the new code-generated
2514 region. LABELs, CONDITIONS, induction-variables and region parameters need
2515 not be copied. */
2517 static bool
2518 should_copy_to_new_region (gimple *stmt, sese_info_p region)
2520 /* Do not copy labels or conditions. */
2521 if (gimple_code (stmt) == GIMPLE_LABEL
2522 || gimple_code (stmt) == GIMPLE_COND)
2523 return false;
2525 tree lhs;
2526 /* Do not copy induction variables. */
2527 if (is_gimple_assign (stmt)
2528 && (lhs = gimple_assign_lhs (stmt))
2529 && TREE_CODE (lhs) == SSA_NAME
2530 && is_gimple_reg (lhs)
2531 && scev_analyzable_p (lhs, region->region))
2532 return false;
2534 /* Do not copy parameters that have been generated in the header of the
2535 scop. */
2536 if (is_gimple_assign (stmt)
2537 && (lhs = gimple_assign_lhs (stmt))
2538 && TREE_CODE (lhs) == SSA_NAME
2539 && region->parameter_rename_map->get(lhs))
2540 return false;
2542 return true;
2545 /* Create new names for all the definitions created by COPY and add replacement
2546 mappings for each new name. */
2548 void translate_isl_ast_to_gimple::
2549 set_rename_for_each_def (gimple *stmt)
2551 def_operand_p def_p;
2552 ssa_op_iter op_iter;
2553 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
2555 tree old_name = DEF_FROM_PTR (def_p);
2556 tree new_name = create_new_def_for (old_name, stmt, def_p);
2557 set_rename (old_name, new_name);
2561 /* Duplicates the statements of basic block BB into basic block NEW_BB
2562 and compute the new induction variables according to the IV_MAP. */
2564 bool translate_isl_ast_to_gimple::
2565 graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
2566 vec<tree> iv_map)
2568 /* Iterator poining to the place where new statement (s) will be inserted. */
2569 gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
2571 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
2572 gsi_next (&gsi))
2574 gimple *stmt = gsi_stmt (gsi);
2575 if (!should_copy_to_new_region (stmt, region))
2576 continue;
2578 /* Create a new copy of STMT and duplicate STMT's virtual
2579 operands. */
2580 gimple *copy = gimple_copy (stmt);
2581 gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
2583 if (dump_file)
2585 fprintf (dump_file, "[codegen] inserting statement: ");
2586 print_gimple_stmt (dump_file, copy, 0, 0);
2589 maybe_duplicate_eh_stmt (copy, stmt);
2590 gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
2592 /* Crete new names for each def in the copied stmt. */
2593 set_rename_for_each_def (copy);
2595 loop_p loop = bb->loop_father;
2596 if (rename_uses (copy, &gsi_tgt, bb, loop, iv_map))
2598 fold_stmt_inplace (&gsi_tgt);
2599 gcc_assert (gsi_stmt (gsi_tgt) == copy);
2602 if (codegen_error_p ())
2603 return false;
2605 /* For each SSA_NAME in the parameter_rename_map rename their usage. */
2606 ssa_op_iter iter;
2607 use_operand_p use_p;
2608 if (!is_gimple_debug (copy))
2609 FOR_EACH_SSA_USE_OPERAND (use_p, copy, iter, SSA_OP_USE)
2611 tree old_name = USE_FROM_PTR (use_p);
2613 if (TREE_CODE (old_name) != SSA_NAME
2614 || SSA_NAME_IS_DEFAULT_DEF (old_name))
2615 continue;
2617 tree *new_expr = region->parameter_rename_map->get (old_name);
2618 if (!new_expr)
2619 continue;
2621 replace_exp (use_p, *new_expr);
2624 update_stmt (copy);
2627 return true;
2631 /* Given a basic block containing close-phi it returns the new basic block where
2632 to insert a copy of the close-phi nodes. All the uses in close phis should
2633 come from a single loop otherwise it returns NULL. */
2635 edge translate_isl_ast_to_gimple::
2636 edge_for_new_close_phis (basic_block bb)
2638 /* Make sure that NEW_BB is the new_loop->exit->dest. We find the definition
2639 of close phi in the original code and then find the mapping of basic block
2640 defining that variable. If there are multiple close-phis and they are
2641 defined in different loops (in the original or in the new code) because of
2642 loop splitting, then we bail out. */
2643 loop_p new_loop = NULL;
2644 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2645 gsi_next (&psi))
2647 gphi *phi = psi.phi ();
2648 tree name = gimple_phi_arg_def (phi, 0);
2649 basic_block old_loop_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
2651 vec <basic_block> *bbs = region->copied_bb_map->get (old_loop_bb);
2652 if (!bbs || bbs->length () != 1)
2653 /* This is one of the places which shows preserving original structure
2654 is not always possible, as we may need to insert close PHI for a loop
2655 where the latch does not have any mapping, or the mapping is
2656 ambiguous. */
2657 return NULL;
2659 if (!new_loop)
2660 new_loop = (*bbs)[0]->loop_father;
2661 else if (new_loop != (*bbs)[0]->loop_father)
2662 return NULL;
2665 if (!new_loop)
2666 return NULL;
2668 return single_exit (new_loop);
2671 /* Copies BB and includes in the copied BB all the statements that can
2672 be reached following the use-def chains from the memory accesses,
2673 and returns the next edge following this new block. */
2675 edge translate_isl_ast_to_gimple::
2676 copy_bb_and_scalar_dependences (basic_block bb, edge next_e, vec<tree> iv_map)
2678 int num_phis = number_of_phi_nodes (bb);
2680 if (region->copied_bb_map->get (bb))
2682 /* FIXME: we should be able to handle phi nodes with args coming from
2683 outside the region. */
2684 if (num_phis)
2686 codegen_error = true;
2687 return NULL;
2691 basic_block new_bb = NULL;
2692 if (bb_contains_loop_close_phi_nodes (bb))
2694 if (dump_file)
2695 fprintf (dump_file, "[codegen] bb_%d contains close phi nodes.\n",
2696 bb->index);
2698 edge e = edge_for_new_close_phis (bb);
2699 if (!e)
2701 codegen_error = true;
2702 return NULL;
2705 basic_block phi_bb = e->dest;
2707 if (!bb_contains_loop_close_phi_nodes (phi_bb) || !single_succ_p (phi_bb))
2708 phi_bb = split_edge (e);
2710 gcc_assert (single_pred_edge (phi_bb)->src->loop_father
2711 != single_pred_edge (phi_bb)->dest->loop_father);
2713 if (!copy_loop_close_phi_nodes (bb, phi_bb))
2715 codegen_error = true;
2716 return NULL;
2719 if (e == next_e)
2720 new_bb = phi_bb;
2721 else
2722 new_bb = split_edge (next_e);
2724 else
2726 new_bb = split_edge (next_e);
2727 if (num_phis > 0 && bb_contains_loop_phi_nodes (bb))
2729 basic_block phi_bb = next_e->dest->loop_father->header;
2731 /* At this point we are unable to codegenerate by still preserving the SSA
2732 structure because maybe the loop is completely unrolled and the PHIs
2733 and cross-bb scalar dependencies are untrackable w.r.t. the original
2734 code. See gfortran.dg/graphite/pr29832.f90. */
2735 if (EDGE_COUNT (bb->preds) != EDGE_COUNT (phi_bb->preds))
2737 codegen_error = true;
2738 return NULL;
2741 /* In case isl did some loop peeling, like this:
2743 S_8(0);
2744 for (int c1 = 1; c1 <= 5; c1 += 1) {
2745 S_8(c1);
2747 S_8(6);
2749 there should be no loop-phi nodes in S_8(0).
2751 FIXME: We need to reason about dynamic instances of S_8, i.e., the
2752 values of all scalar variables: for the moment we instantiate only
2753 SCEV analyzable expressions on the iteration domain, and we need to
2754 extend that to reductions that cannot be analyzed by SCEV. */
2755 if (!bb_in_sese_p (phi_bb, region->if_region->true_region->region))
2757 codegen_error = true;
2758 return NULL;
2761 if (dump_file)
2762 fprintf (dump_file, "[codegen] bb_%d contains loop phi nodes.\n",
2763 bb->index);
2764 if (!copy_loop_phi_nodes (bb, phi_bb))
2766 codegen_error = true;
2767 return NULL;
2770 else if (num_phis > 0)
2772 if (dump_file)
2773 fprintf (dump_file, "[codegen] bb_%d contains cond phi nodes.\n",
2774 bb->index);
2776 basic_block phi_bb = single_pred (new_bb);
2777 loop_p loop_father = new_bb->loop_father;
2779 /* Move back until we find the block with two predecessors. */
2780 while (single_pred_p (phi_bb))
2781 phi_bb = single_pred_edge (phi_bb)->src;
2783 /* If a corresponding merge-point was not found, then abort codegen. */
2784 if (phi_bb->loop_father != loop_father
2785 || !bb_in_sese_p (phi_bb, region->if_region->true_region->region)
2786 || !copy_cond_phi_nodes (bb, phi_bb, iv_map))
2788 codegen_error = true;
2789 return NULL;
2794 if (dump_file)
2795 fprintf (dump_file, "[codegen] copying from bb_%d to bb_%d.\n",
2796 bb->index, new_bb->index);
2798 vec <basic_block> *copied_bbs = region->copied_bb_map->get (bb);
2799 if (copied_bbs)
2800 copied_bbs->safe_push (new_bb);
2801 else
2803 vec<basic_block> bbs;
2804 bbs.create (2);
2805 bbs.safe_push (new_bb);
2806 region->copied_bb_map->put (bb, bbs);
2809 if (!graphite_copy_stmts_from_block (bb, new_bb, iv_map))
2811 codegen_error = true;
2812 return NULL;
2815 return single_succ_edge (new_bb);
2818 /* Patch the missing arguments of the phi nodes. */
2820 void translate_isl_ast_to_gimple::
2821 translate_pending_phi_nodes ()
2823 int i;
2824 phi_rename *rename;
2825 FOR_EACH_VEC_ELT (region->incomplete_phis, i, rename)
2827 gphi *old_phi = rename->first;
2828 gphi *new_phi = rename->second;
2829 basic_block old_bb = gimple_bb (old_phi);
2830 basic_block new_bb = gimple_bb (new_phi);
2832 /* First edge is the init edge and second is the back edge. */
2833 init_back_edge_pair_t ibp_old_bb = get_edges (old_bb);
2834 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
2836 if (dump_file)
2838 fprintf (dump_file, "[codegen] translating pending old-phi: ");
2839 print_gimple_stmt (dump_file, old_phi, 0, 0);
2842 auto_vec <tree, 1> iv_map;
2843 if (bb_contains_loop_phi_nodes (new_bb))
2844 codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
2845 ibp_new_bb, false);
2846 else if (bb_contains_loop_close_phi_nodes (new_bb))
2847 codegen_error = !copy_loop_close_phi_args (old_bb, new_bb, false);
2848 else
2849 codegen_error = !copy_cond_phi_args (old_phi, new_phi, iv_map, false);
2851 if (dump_file)
2853 fprintf (dump_file, "[codegen] to new-phi: ");
2854 print_gimple_stmt (dump_file, new_phi, 0, 0);
2856 if (codegen_error_p ())
2857 return;
2861 /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
2863 void translate_isl_ast_to_gimple::
2864 add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
2866 sese_info_p region = scop->scop_info;
2867 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
2868 gcc_assert (nb_parameters == region->params.length ());
2869 unsigned i;
2870 for (i = 0; i < nb_parameters; i++)
2872 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
2873 isl_dim_param, i);
2874 ip[tmp_id] = region->params[i];
2879 /* Generates a build, which specifies the constraints on the parameters. */
2881 __isl_give isl_ast_build *translate_isl_ast_to_gimple::
2882 generate_isl_context (scop_p scop)
2884 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
2885 return isl_ast_build_from_context (context_isl);
2888 /* This method is executed before the construction of a for node. */
2889 __isl_give isl_id *
2890 ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
2892 isl_union_map *dependences = (isl_union_map *) user;
2893 ast_build_info *for_info = XNEW (struct ast_build_info);
2894 isl_union_map *schedule = isl_ast_build_get_schedule (build);
2895 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
2896 int dimension = isl_space_dim (schedule_space, isl_dim_out);
2897 for_info->is_parallelizable =
2898 !carries_deps (schedule, dependences, dimension);
2899 isl_union_map_free (schedule);
2900 isl_space_free (schedule_space);
2901 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
2902 return id;
2905 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
2907 /* Generate isl AST from schedule of SCOP. */
2909 __isl_give isl_ast_node *translate_isl_ast_to_gimple::
2910 scop_to_isl_ast (scop_p scop)
2912 gcc_assert (scop->transformed_schedule);
2914 /* Set the separate option to reduce control flow overhead. */
2915 isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
2916 (isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
2917 isl_ast_build *context_isl = generate_isl_context (scop);
2919 if (flag_loop_parallelize_all)
2921 scop_get_dependences (scop);
2922 context_isl =
2923 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
2924 scop->dependence);
2927 isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
2928 (context_isl, schedule);
2929 isl_ast_build_free (context_isl);
2930 return ast_isl;
2933 #else
2934 /* Get the maximal number of schedule dimensions in the scop SCOP. */
2936 int translate_isl_ast_to_gimple::
2937 get_max_schedule_dimensions (scop_p scop)
2939 int i;
2940 poly_bb_p pbb;
2941 int schedule_dims = 0;
2943 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
2945 int pbb_schedule_dims = isl_map_dim (pbb->transformed, isl_dim_out);
2946 if (pbb_schedule_dims > schedule_dims)
2947 schedule_dims = pbb_schedule_dims;
2950 return schedule_dims;
2953 /* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
2955 For schedules with different dimensionality, the isl AST generator can not
2956 define an order and will just randomly choose an order. The solution to this
2957 problem is to extend all schedules to the maximal number of schedule
2958 dimensions (using '0's for the remaining values). */
2960 __isl_give isl_map *translate_isl_ast_to_gimple::
2961 extend_schedule (__isl_take isl_map *schedule, int nb_schedule_dims)
2963 int tmp_dims = isl_map_dim (schedule, isl_dim_out);
2964 schedule =
2965 isl_map_add_dims (schedule, isl_dim_out, nb_schedule_dims - tmp_dims);
2966 isl_val *zero =
2967 isl_val_int_from_si (isl_map_get_ctx (schedule), 0);
2968 int i;
2969 for (i = tmp_dims; i < nb_schedule_dims; i++)
2971 schedule
2972 = isl_map_fix_val (schedule, isl_dim_out, i, isl_val_copy (zero));
2974 isl_val_free (zero);
2975 return schedule;
2978 /* Generates a schedule, which specifies an order used to
2979 visit elements in a domain. */
2981 __isl_give isl_union_map *translate_isl_ast_to_gimple::
2982 generate_isl_schedule (scop_p scop)
2984 int nb_schedule_dims = get_max_schedule_dimensions (scop);
2985 int i;
2986 poly_bb_p pbb;
2987 isl_union_map *schedule_isl =
2988 isl_union_map_empty (isl_set_get_space (scop->param_context));
2990 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
2992 /* Dead code elimination: when the domain of a PBB is empty,
2993 don't generate code for the PBB. */
2994 if (isl_set_is_empty (pbb->domain))
2995 continue;
2997 isl_map *bb_schedule = isl_map_copy (pbb->transformed);
2998 bb_schedule = isl_map_intersect_domain (bb_schedule,
2999 isl_set_copy (pbb->domain));
3000 bb_schedule = extend_schedule (bb_schedule, nb_schedule_dims);
3001 bb_schedule = isl_map_coalesce (bb_schedule);
3002 schedule_isl
3003 = isl_union_map_union (schedule_isl,
3004 isl_union_map_from_map (bb_schedule));
3005 schedule_isl = isl_union_map_coalesce (schedule_isl);
3007 return schedule_isl;
3010 /* Set the separate option for all dimensions.
3011 This helps to reduce control overhead. */
3013 __isl_give isl_ast_build *translate_isl_ast_to_gimple::
3014 set_options (__isl_take isl_ast_build *control,
3015 __isl_keep isl_union_map *schedule)
3017 isl_ctx *ctx = isl_union_map_get_ctx (schedule);
3018 isl_space *range_space = isl_space_set_alloc (ctx, 0, 1);
3019 range_space =
3020 isl_space_set_tuple_name (range_space, isl_dim_set, "separate");
3021 isl_union_set *range =
3022 isl_union_set_from_set (isl_set_universe (range_space));
3023 isl_union_set *domain = isl_union_map_range (isl_union_map_copy (schedule));
3024 domain = isl_union_set_universe (domain);
3025 isl_union_map *options = isl_union_map_from_domain_and_range (domain, range);
3026 return isl_ast_build_set_options (control, options);
3029 /* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in IP. */
3031 __isl_give isl_ast_node *translate_isl_ast_to_gimple::
3032 scop_to_isl_ast (scop_p scop, ivs_params &ip)
3034 /* Generate loop upper bounds that consist of the current loop iterator, an
3035 operator (< or <=) and an expression not involving the iterator. If this
3036 option is not set, then the current loop iterator may appear several times
3037 in the upper bound. See the isl manual for more details. */
3038 isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, true);
3040 add_parameters_to_ivs_params (scop, ip);
3041 isl_union_map *schedule_isl = generate_isl_schedule (scop);
3042 isl_ast_build *context_isl = generate_isl_context (scop);
3043 context_isl = set_options (context_isl, schedule_isl);
3044 if (flag_loop_parallelize_all)
3046 isl_union_map *dependence = scop_get_dependences (scop);
3047 context_isl =
3048 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
3049 dependence);
3052 isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
3053 schedule_isl);
3054 if (scop->schedule)
3056 isl_schedule_free (scop->schedule);
3057 scop->schedule = NULL;
3060 isl_ast_build_free (context_isl);
3061 return ast_isl;
3063 #endif
3065 /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
3066 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
3068 static void
3069 copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
3070 gimple_stmt_iterator *gsi)
3072 if (!defined_in_sese_p (tr, region->region))
3073 return;
3075 ssa_op_iter iter;
3076 use_operand_p use_p;
3077 FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
3079 tree use_tr = USE_FROM_PTR (use_p);
3081 /* Do not copy parameters that have been generated in the header of the
3082 scop. */
3083 if (region->parameter_rename_map->get(use_tr))
3084 continue;
3086 gimple *def_of_use = SSA_NAME_DEF_STMT (use_tr);
3087 if (!def_of_use)
3088 continue;
3090 copy_def (use_tr, def_of_use, region, to_region, gsi);
3093 gimple *copy = gimple_copy (def_stmt);
3094 gsi_insert_after (gsi, copy, GSI_NEW_STMT);
3096 /* Create new names for all the definitions created by COPY and
3097 add replacement mappings for each new name. */
3098 def_operand_p def_p;
3099 ssa_op_iter op_iter;
3100 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
3102 tree old_name = DEF_FROM_PTR (def_p);
3103 tree new_name = create_new_def_for (old_name, copy, def_p);
3104 region->parameter_rename_map->put(old_name, new_name);
3107 update_stmt (copy);
3110 static void
3111 copy_internal_parameters (sese_info_p region, sese_info_p to_region)
3113 /* For all the parameters which definitino is in the if_region->false_region,
3114 insert code on true_region (if_region->true_region->entry). */
3116 int i;
3117 tree tr;
3118 gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
3120 FOR_EACH_VEC_ELT (region->params, i, tr)
3122 // If def is not in region.
3123 gimple *def_stmt = SSA_NAME_DEF_STMT (tr);
3124 if (def_stmt)
3125 copy_def (tr, def_stmt, region, to_region, &gsi);
3129 /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
3130 Return true if code generation succeeded. */
3132 bool
3133 graphite_regenerate_ast_isl (scop_p scop)
3135 sese_info_p region = scop->scop_info;
3136 translate_isl_ast_to_gimple t (region);
3138 ifsese if_region = NULL;
3139 isl_ast_node *root_node;
3140 ivs_params ip;
3142 timevar_push (TV_GRAPHITE_CODE_GEN);
3143 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
3144 t.add_parameters_to_ivs_params (scop, ip);
3145 root_node = t.scop_to_isl_ast (scop);
3146 #else
3147 root_node = t.scop_to_isl_ast (scop, ip);
3148 #endif
3150 if (dump_file && (dump_flags & TDF_DETAILS))
3152 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
3153 fprintf (dump_file, "[scheduler] original schedule:\n");
3154 print_isl_schedule (dump_file, scop->original_schedule);
3155 fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
3156 print_isl_schedule (dump_file, scop->transformed_schedule);
3158 fprintf (dump_file, "[scheduler] original ast:\n");
3159 print_schedule_ast (dump_file, scop->original_schedule, scop);
3160 #endif
3161 fprintf (dump_file, "[scheduler] AST generated by isl:\n");
3162 print_isl_ast (dump_file, root_node);
3165 recompute_all_dominators ();
3166 graphite_verify ();
3168 if_region = move_sese_in_condition (region);
3169 region->if_region = if_region;
3170 recompute_all_dominators ();
3172 loop_p context_loop = region->region.entry->src->loop_father;
3174 /* Copy all the parameters which are defined in the region. */
3175 copy_internal_parameters(if_region->false_region, if_region->true_region);
3177 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
3178 basic_block bb = split_edge (e);
3180 /* Update the true_region exit edge. */
3181 region->if_region->true_region->region.exit = single_succ_edge (bb);
3183 t.translate_isl_ast (context_loop, root_node, e, ip);
3184 if (t.codegen_error_p ())
3186 if (dump_file)
3187 fprintf (dump_file, "codegen error: "
3188 "reverting back to the original code.\n");
3189 set_ifsese_condition (if_region, integer_zero_node);
3191 else
3193 t.translate_pending_phi_nodes ();
3194 if (!t.codegen_error_p ())
3196 sese_insert_phis_for_liveouts (region,
3197 if_region->region->region.exit->src,
3198 if_region->false_region->region.exit,
3199 if_region->true_region->region.exit);
3200 mark_virtual_operands_for_renaming (cfun);
3201 update_ssa (TODO_update_ssa);
3204 graphite_verify ();
3205 scev_reset ();
3206 recompute_all_dominators ();
3207 graphite_verify ();
3209 if (dump_file)
3210 fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
3212 else
3214 if (dump_file)
3215 fprintf (dump_file, "[codegen] unsuccessful in translating"
3216 " pending phis, reverting back to the original code.\n");
3217 set_ifsese_condition (if_region, integer_zero_node);
3221 free (if_region->true_region);
3222 free (if_region->region);
3223 free (if_region);
3225 ivs_params_clear (ip);
3226 isl_ast_node_free (root_node);
3227 timevar_pop (TV_GRAPHITE_CODE_GEN);
3229 if (dump_file && (dump_flags & TDF_DETAILS))
3231 loop_p loop;
3232 int num_no_dependency = 0;
3234 FOR_EACH_LOOP (loop, 0)
3235 if (loop->can_be_parallel)
3236 num_no_dependency++;
3238 fprintf (dump_file, "%d loops carried no dependency.\n",
3239 num_no_dependency);
3242 return !t.codegen_error_p ();
3245 #endif /* HAVE_isl */