[Patch AArch64 1/3] Enable CRC by default for armv8.1-a
[official-gcc.git] / gcc / graphite-isl-ast-to-gimple.c
blob8dd5dc8bb84362d6fd35c20193b7c5a10ca691c8
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,
825 unshare_expr (cond_expr));
827 return exit_edge;
830 /* Translates an isl_ast_node_for to Gimple. */
832 edge translate_isl_ast_to_gimple::
833 translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
834 edge next_e, ivs_params &ip)
836 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
837 tree type, lb, ub;
838 edge last_e = graphite_create_new_loop_guard (next_e, node, &type,
839 &lb, &ub, ip);
841 if (last_e == next_e)
843 /* There was no guard generated. */
844 last_e = single_succ_edge (split_edge (last_e));
846 translate_isl_ast_for_loop (context_loop, node, next_e,
847 type, lb, ub, ip);
848 return last_e;
851 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
852 merge_points.safe_push (last_e);
854 last_e = single_succ_edge (split_edge (last_e));
855 translate_isl_ast_for_loop (context_loop, node, true_e, type, lb, ub, ip);
857 return last_e;
860 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
861 variables of the loops around GBB in SESE.
863 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
864 chrec, we could consider using a map<int, tree> that maps loop ids to the
865 corresponding tree expressions. */
867 void translate_isl_ast_to_gimple::
868 build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
869 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
870 sese_l &region)
872 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
873 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
874 int i;
875 isl_ast_expr *arg_expr;
876 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
878 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
879 tree type =
880 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
881 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
883 /* To fail code generation, we generate wrong code until we discard it. */
884 if (codegen_error_p ())
885 t = integer_zero_node;
887 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
888 iv_map[old_loop->num] = t;
892 /* Translates an isl_ast_node_user to Gimple.
894 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
896 edge translate_isl_ast_to_gimple::
897 translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
898 edge next_e, ivs_params &ip)
900 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
902 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
903 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
904 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
906 isl_id *name_id = isl_ast_expr_get_id (name_expr);
907 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
908 gcc_assert (pbb);
910 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
912 isl_ast_expr_free (name_expr);
913 isl_id_free (name_id);
915 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
916 "The entry block should not even appear within a scop");
918 const int nb_loops = number_of_loops (cfun);
919 vec<tree> iv_map;
920 iv_map.create (nb_loops);
921 iv_map.safe_grow_cleared (nb_loops);
923 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
924 isl_ast_expr_free (user_expr);
926 basic_block old_bb = GBB_BB (gbb);
927 if (dump_file)
929 fprintf (dump_file,
930 "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
931 old_bb->index, next_e->src->index, next_e->dest->index);
932 print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
936 next_e = copy_bb_and_scalar_dependences (old_bb, next_e, iv_map);
938 iv_map.release ();
940 if (codegen_error_p ())
941 return NULL;
943 if (dump_file)
945 fprintf (dump_file, "[codegen] (after copy) new basic block\n");
946 print_loops_bb (dump_file, next_e->src, 0, 3);
949 return next_e;
952 /* Translates an isl_ast_node_block to Gimple. */
954 edge translate_isl_ast_to_gimple::
955 translate_isl_ast_node_block (loop_p context_loop,
956 __isl_keep isl_ast_node *node,
957 edge next_e, ivs_params &ip)
959 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
960 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
961 int i;
962 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
964 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
965 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
966 isl_ast_node_free (tmp_node);
968 isl_ast_node_list_free (node_list);
969 return next_e;
972 /* Creates a new if region corresponding to isl's cond. */
974 edge translate_isl_ast_to_gimple::
975 graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
976 ivs_params &ip)
978 tree type =
979 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
980 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
982 /* To fail code generation, we generate wrong code until we discard it. */
983 if (codegen_error_p ())
984 cond_expr = integer_zero_node;
986 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
987 return exit_edge;
990 /* Translates an isl_ast_node_if to Gimple. */
992 edge translate_isl_ast_to_gimple::
993 translate_isl_ast_node_if (loop_p context_loop,
994 __isl_keep isl_ast_node *node,
995 edge next_e, ivs_params &ip)
997 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
998 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
999 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
1000 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
1001 merge_points.safe_push (last_e);
1003 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
1004 translate_isl_ast (context_loop, then_node, true_e, ip);
1005 isl_ast_node_free (then_node);
1007 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
1008 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
1009 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
1010 translate_isl_ast (context_loop, else_node, false_e, ip);
1012 isl_ast_node_free (else_node);
1013 return last_e;
1016 /* Translates an isl AST node NODE to GCC representation in the
1017 context of a SESE. */
1019 edge translate_isl_ast_to_gimple::
1020 translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
1021 edge next_e, ivs_params &ip)
1023 if (codegen_error_p ())
1024 return NULL;
1026 switch (isl_ast_node_get_type (node))
1028 case isl_ast_node_error:
1029 gcc_unreachable ();
1031 case isl_ast_node_for:
1032 return translate_isl_ast_node_for (context_loop, node,
1033 next_e, ip);
1035 case isl_ast_node_if:
1036 return translate_isl_ast_node_if (context_loop, node,
1037 next_e, ip);
1039 case isl_ast_node_user:
1040 return translate_isl_ast_node_user (node, next_e, ip);
1042 case isl_ast_node_block:
1043 return translate_isl_ast_node_block (context_loop, node,
1044 next_e, ip);
1046 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
1047 case isl_ast_node_mark:
1049 isl_ast_node *n = isl_ast_node_mark_get_node (node);
1050 edge e = translate_isl_ast (context_loop, n, next_e, ip);
1051 isl_ast_node_free (n);
1052 return e;
1054 #endif
1056 default:
1057 gcc_unreachable ();
1061 /* Return true when BB contains loop close phi nodes. A loop close phi node is
1062 at the exit of loop which takes one argument that is the last value of the
1063 variable being used out of the loop. */
1065 static bool
1066 bb_contains_loop_close_phi_nodes (basic_block bb)
1068 return single_pred_p (bb)
1069 && bb->loop_father != single_pred_edge (bb)->src->loop_father;
1072 /* Return true when BB contains loop phi nodes. A loop phi node is the loop
1073 header containing phi nodes which has one init-edge and one back-edge. */
1075 static bool
1076 bb_contains_loop_phi_nodes (basic_block bb)
1078 gcc_assert (EDGE_COUNT (bb->preds) <= 2);
1080 if (bb->preds->length () == 1)
1081 return false;
1083 unsigned depth = loop_depth (bb->loop_father);
1085 edge preds[2] = { (*bb->preds)[0], (*bb->preds)[1] };
1087 if (depth > loop_depth (preds[0]->src->loop_father)
1088 || depth > loop_depth (preds[1]->src->loop_father))
1089 return true;
1091 /* When one of the edges correspond to the same loop father and other
1092 doesn't. */
1093 if (bb->loop_father != preds[0]->src->loop_father
1094 && bb->loop_father == preds[1]->src->loop_father)
1095 return true;
1097 if (bb->loop_father != preds[1]->src->loop_father
1098 && bb->loop_father == preds[0]->src->loop_father)
1099 return true;
1101 return false;
1104 /* Check if USE is defined in a basic block from where the definition of USE can
1105 propagate from all the paths. FIXME: Verify checks for virtual operands. */
1107 static bool
1108 is_loop_closed_ssa_use (basic_block bb, tree use)
1110 if (TREE_CODE (use) != SSA_NAME || virtual_operand_p (use))
1111 return true;
1113 /* For close-phi nodes def always comes from a loop which has a back-edge. */
1114 if (bb_contains_loop_close_phi_nodes (bb))
1115 return true;
1117 gimple *def = SSA_NAME_DEF_STMT (use);
1118 basic_block def_bb = gimple_bb (def);
1119 return (!def_bb
1120 || flow_bb_inside_loop_p (def_bb->loop_father, bb));
1123 /* Return the number of phi nodes in BB. */
1125 static int
1126 number_of_phi_nodes (basic_block bb)
1128 int num_phis = 0;
1129 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1130 gsi_next (&psi))
1131 num_phis++;
1132 return num_phis;
1135 /* Returns true if BB uses name in one of its PHIs. */
1137 static bool
1138 phi_uses_name (basic_block bb, tree name)
1140 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1141 gsi_next (&psi))
1143 gphi *phi = psi.phi ();
1144 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
1146 tree use_arg = gimple_phi_arg_def (phi, i);
1147 if (use_arg == name)
1148 return true;
1151 return false;
1154 /* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
1155 definition should flow into use, and the use should respect the loop-closed
1156 SSA form. */
1158 bool translate_isl_ast_to_gimple::
1159 is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
1160 phi_node_kind phi_kind, tree old_name, basic_block old_bb) const
1162 /* The def of the rename must either dominate the uses or come from a
1163 back-edge. Also the def must respect the loop closed ssa form. */
1164 if (!is_loop_closed_ssa_use (use_bb, rename))
1166 if (dump_file)
1168 fprintf (dump_file, "[codegen] rename not in loop closed ssa: ");
1169 print_generic_expr (dump_file, rename, 0);
1170 fprintf (dump_file, "\n");
1172 return false;
1175 if (dominated_by_p (CDI_DOMINATORS, use_bb, def_bb))
1176 return true;
1178 if (bb_contains_loop_phi_nodes (use_bb) && phi_kind == loop_phi)
1180 /* The loop-header dominates the loop-body. */
1181 if (!dominated_by_p (CDI_DOMINATORS, def_bb, use_bb))
1182 return false;
1184 /* RENAME would be used in loop-phi. */
1185 gcc_assert (number_of_phi_nodes (use_bb));
1187 /* For definitions coming from back edges, we should check that
1188 old_name is used in a loop PHI node.
1189 FIXME: Verify if this is true. */
1190 if (phi_uses_name (old_bb, old_name))
1191 return true;
1193 return false;
1196 /* Returns the expression associated to OLD_NAME (which is used in OLD_BB), in
1197 NEW_BB from RENAME_MAP. PHI_KIND determines the kind of phi node. */
1199 tree translate_isl_ast_to_gimple::
1200 get_rename (basic_block new_bb, tree old_name, basic_block old_bb,
1201 phi_node_kind phi_kind) const
1203 gcc_assert (TREE_CODE (old_name) == SSA_NAME);
1204 vec <tree> *renames = region->rename_map->get (old_name);
1206 if (!renames || renames->is_empty ())
1207 return NULL_TREE;
1209 if (1 == renames->length ())
1211 tree rename = (*renames)[0];
1212 if (TREE_CODE (rename) == SSA_NAME)
1214 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (rename));
1215 if (is_valid_rename (rename, bb, new_bb, phi_kind, old_name, old_bb)
1216 && (phi_kind == close_phi
1217 || flow_bb_inside_loop_p (bb->loop_father, new_bb)))
1218 return rename;
1219 return NULL_TREE;
1222 if (is_constant (rename))
1223 return rename;
1225 return NULL_TREE;
1228 /* More than one renames corresponding to the old_name. Find the rename for
1229 which the definition flows into usage at new_bb. */
1230 int i;
1231 tree t1 = NULL_TREE, t2;
1232 basic_block t1_bb = NULL;
1233 FOR_EACH_VEC_ELT (*renames, i, t2)
1235 basic_block t2_bb = gimple_bb (SSA_NAME_DEF_STMT (t2));
1237 /* Defined in the same basic block as used. */
1238 if (t2_bb == new_bb)
1239 return t2;
1241 /* NEW_BB and T2_BB are in two unrelated if-clauses. */
1242 if (!dominated_by_p (CDI_DOMINATORS, new_bb, t2_bb))
1243 continue;
1245 if (!flow_bb_inside_loop_p (t2_bb->loop_father, new_bb))
1246 continue;
1248 /* Compute the nearest dominator. */
1249 if (!t1 || dominated_by_p (CDI_DOMINATORS, t2_bb, t1_bb))
1251 t1_bb = t2_bb;
1252 t1 = t2;
1256 return t1;
1259 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
1260 When OLD_NAME and EXPR are the same we assert. */
1262 void translate_isl_ast_to_gimple::
1263 set_rename (tree old_name, tree expr)
1265 if (dump_file)
1267 fprintf (dump_file, "[codegen] setting rename: old_name = ");
1268 print_generic_expr (dump_file, old_name, 0);
1269 fprintf (dump_file, ", new_name = ");
1270 print_generic_expr (dump_file, expr, 0);
1271 fprintf (dump_file, "\n");
1274 if (old_name == expr)
1275 return;
1277 vec <tree> *renames = region->rename_map->get (old_name);
1279 if (renames)
1280 renames->safe_push (expr);
1281 else
1283 vec<tree> r;
1284 r.create (2);
1285 r.safe_push (expr);
1286 region->rename_map->put (old_name, r);
1289 tree t;
1290 int i;
1291 /* For a parameter of a scop we don't want to rename it. */
1292 FOR_EACH_VEC_ELT (region->params, i, t)
1293 if (old_name == t)
1294 region->parameter_rename_map->put(old_name, expr);
1297 /* Return an iterator to the instructions comes last in the execution order.
1298 Either GSI1 and GSI2 should belong to the same basic block or one of their
1299 respective basic blocks should dominate the other. */
1301 gimple_stmt_iterator
1302 later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
1304 basic_block bb1 = gsi_bb (gsi1);
1305 basic_block bb2 = gsi_bb (gsi2);
1307 /* Find the iterator which is the latest. */
1308 if (bb1 == bb2)
1310 /* For empty basic blocks gsis point to the end of the sequence. Since
1311 there is no operator== defined for gimple_stmt_iterator and for gsis
1312 not pointing to a valid statement gsi_next would assert. */
1313 gimple_stmt_iterator gsi = gsi1;
1314 do {
1315 if (gsi_stmt (gsi) == gsi_stmt (gsi2))
1316 return gsi2;
1317 gsi_next (&gsi);
1318 } while (!gsi_end_p (gsi));
1320 return gsi1;
1323 /* Find the basic block closest to the basic block which defines stmt. */
1324 if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
1325 return gsi1;
1327 gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
1328 return gsi2;
1331 /* Insert each statement from SEQ at its earliest insertion p. */
1333 void translate_isl_ast_to_gimple::
1334 gsi_insert_earliest (gimple_seq seq)
1336 update_modified_stmts (seq);
1337 sese_l &codegen_region = region->if_region->true_region->region;
1338 basic_block begin_bb = get_entry_bb (codegen_region);
1340 /* Inserting the gimple statements in a vector because gimple_seq behave
1341 in strage ways when inserting the stmts from it into different basic
1342 blocks one at a time. */
1343 auto_vec<gimple *, 3> stmts;
1344 for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
1345 gsi_next (&gsi))
1346 stmts.safe_push (gsi_stmt (gsi));
1348 int i;
1349 gimple *use_stmt;
1350 FOR_EACH_VEC_ELT (stmts, i, use_stmt)
1352 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1353 gimple_stmt_iterator gsi_def_stmt = gsi_start_bb_nondebug (begin_bb);
1355 use_operand_p use_p;
1356 ssa_op_iter op_iter;
1357 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
1359 /* Iterator to the current def of use_p. For function parameters or
1360 anything where def is not found, insert at the beginning of the
1361 generated region. */
1362 gimple_stmt_iterator gsi_stmt = gsi_def_stmt;
1364 tree op = USE_FROM_PTR (use_p);
1365 gimple *stmt = SSA_NAME_DEF_STMT (op);
1366 if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
1367 gsi_stmt = gsi_for_stmt (stmt);
1369 /* For region parameters, insert at the beginning of the generated
1370 region. */
1371 if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
1372 gsi_stmt = gsi_def_stmt;
1374 gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
1377 if (!gsi_stmt (gsi_def_stmt))
1379 gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
1380 gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
1382 else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
1384 gimple_stmt_iterator bsi
1385 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt));
1386 /* Insert right after the PHI statements. */
1387 gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
1389 else
1390 gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);
1392 if (dump_file)
1394 fprintf (dump_file, "[codegen] inserting statement: ");
1395 print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
1396 print_loops_bb (dump_file, gimple_bb (use_stmt), 0, 3);
1401 /* Collect all the operands of NEW_EXPR by recursively visiting each
1402 operand. */
1404 void translate_isl_ast_to_gimple::
1405 collect_all_ssa_names (tree new_expr, vec<tree> *vec_ssa)
1407 if (new_expr == NULL_TREE)
1408 return;
1410 /* Rename all uses in new_expr. */
1411 if (TREE_CODE (new_expr) == SSA_NAME)
1413 vec_ssa->safe_push (new_expr);
1414 return;
1417 /* Iterate over SSA_NAMES in NEW_EXPR. */
1418 for (int i = 0; i < (TREE_CODE_LENGTH (TREE_CODE (new_expr))); i++)
1420 tree op = TREE_OPERAND (new_expr, i);
1421 collect_all_ssa_names (op, vec_ssa);
1425 /* This is abridged version of the function copied from:
1426 tree.c:substitute_in_expr (tree exp, tree f, tree r). */
1428 static tree
1429 substitute_ssa_name (tree exp, tree f, tree r)
1431 enum tree_code code = TREE_CODE (exp);
1432 tree op0, op1, op2, op3;
1433 tree new_tree;
1435 /* We handle TREE_LIST and COMPONENT_REF separately. */
1436 if (code == TREE_LIST)
1438 op0 = substitute_ssa_name (TREE_CHAIN (exp), f, r);
1439 op1 = substitute_ssa_name (TREE_VALUE (exp), f, r);
1440 if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
1441 return exp;
1443 return tree_cons (TREE_PURPOSE (exp), op1, op0);
1445 else if (code == COMPONENT_REF)
1447 tree inner;
1449 /* If this expression is getting a value from a PLACEHOLDER_EXPR
1450 and it is the right field, replace it with R. */
1451 for (inner = TREE_OPERAND (exp, 0);
1452 REFERENCE_CLASS_P (inner);
1453 inner = TREE_OPERAND (inner, 0))
1456 /* The field. */
1457 op1 = TREE_OPERAND (exp, 1);
1459 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
1460 return r;
1462 /* If this expression hasn't been completed let, leave it alone. */
1463 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
1464 return exp;
1466 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1467 if (op0 == TREE_OPERAND (exp, 0))
1468 return exp;
1470 new_tree
1471 = fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
1473 else
1474 switch (TREE_CODE_CLASS (code))
1476 case tcc_constant:
1477 return exp;
1479 case tcc_declaration:
1480 if (exp == f)
1481 return r;
1482 else
1483 return exp;
1485 case tcc_expression:
1486 if (exp == f)
1487 return r;
1489 /* Fall through... */
1491 case tcc_exceptional:
1492 case tcc_unary:
1493 case tcc_binary:
1494 case tcc_comparison:
1495 case tcc_reference:
1496 switch (TREE_CODE_LENGTH (code))
1498 case 0:
1499 if (exp == f)
1500 return r;
1501 return exp;
1503 case 1:
1504 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1505 if (op0 == TREE_OPERAND (exp, 0))
1506 return exp;
1508 new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
1509 break;
1511 case 2:
1512 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1513 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1515 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
1516 return exp;
1518 new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
1519 break;
1521 case 3:
1522 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1523 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1524 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1526 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1527 && op2 == TREE_OPERAND (exp, 2))
1528 return exp;
1530 new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
1531 break;
1533 case 4:
1534 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1535 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1536 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1537 op3 = substitute_ssa_name (TREE_OPERAND (exp, 3), f, r);
1539 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1540 && op2 == TREE_OPERAND (exp, 2)
1541 && op3 == TREE_OPERAND (exp, 3))
1542 return exp;
1544 new_tree
1545 = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
1546 break;
1548 default:
1549 gcc_unreachable ();
1551 break;
1553 case tcc_vl_exp:
1554 default:
1555 gcc_unreachable ();
1558 TREE_READONLY (new_tree) |= TREE_READONLY (exp);
1560 if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
1561 TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
1563 return new_tree;
1566 /* Rename all the operands of NEW_EXPR by recursively visiting each operand. */
1568 tree translate_isl_ast_to_gimple::
1569 rename_all_uses (tree new_expr, basic_block new_bb, basic_block old_bb)
1571 auto_vec<tree, 2> ssa_names;
1572 collect_all_ssa_names (new_expr, &ssa_names);
1573 tree t;
1574 int i;
1575 FOR_EACH_VEC_ELT (ssa_names, i, t)
1576 if (tree r = get_rename (new_bb, t, old_bb, unknown_phi))
1577 new_expr = substitute_ssa_name (new_expr, t, r);
1579 return new_expr;
1582 /* For ops which are scev_analyzeable, we can regenerate a new name from its
1583 scalar evolution around LOOP. */
1585 tree translate_isl_ast_to_gimple::
1586 get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
1587 basic_block new_bb, basic_block old_bb,
1588 vec<tree> iv_map)
1590 tree scev = scalar_evolution_in_region (region->region, loop, old_name);
1592 /* At this point we should know the exact scev for each
1593 scalar SSA_NAME used in the scop: all the other scalar
1594 SSA_NAMEs should have been translated out of SSA using
1595 arrays with one element. */
1596 tree new_expr;
1597 if (chrec_contains_undetermined (scev))
1599 codegen_error = true;
1600 return build_zero_cst (TREE_TYPE (old_name));
1603 new_expr = chrec_apply_map (scev, iv_map);
1605 /* The apply should produce an expression tree containing
1606 the uses of the new induction variables. We should be
1607 able to use new_expr instead of the old_name in the newly
1608 generated loop nest. */
1609 if (chrec_contains_undetermined (new_expr)
1610 || tree_contains_chrecs (new_expr, NULL))
1612 codegen_error = true;
1613 return build_zero_cst (TREE_TYPE (old_name));
1616 if (TREE_CODE (new_expr) == SSA_NAME)
1618 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_expr));
1619 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1621 codegen_error = true;
1622 return build_zero_cst (TREE_TYPE (old_name));
1626 new_expr = rename_all_uses (new_expr, new_bb, old_bb);
1628 /* We check all the operands and all of them should dominate the use at
1629 new_expr. */
1630 auto_vec <tree, 2> new_ssa_names;
1631 collect_all_ssa_names (new_expr, &new_ssa_names);
1632 int i;
1633 tree new_ssa_name;
1634 FOR_EACH_VEC_ELT (new_ssa_names, i, new_ssa_name)
1636 if (TREE_CODE (new_ssa_name) == SSA_NAME)
1638 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_ssa_name));
1639 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1641 codegen_error = true;
1642 return build_zero_cst (TREE_TYPE (old_name));
1647 /* Replace the old_name with the new_expr. */
1648 return force_gimple_operand (unshare_expr (new_expr), stmts,
1649 true, NULL_TREE);
1652 /* Renames the scalar uses of the statement COPY, using the
1653 substitution map RENAME_MAP, inserting the gimplification code at
1654 GSI_TGT, for the translation REGION, with the original copied
1655 statement in LOOP, and using the induction variable renaming map
1656 IV_MAP. Returns true when something has been renamed. */
1658 bool translate_isl_ast_to_gimple::
1659 rename_uses (gimple *copy, gimple_stmt_iterator *gsi_tgt, basic_block old_bb,
1660 loop_p loop, vec<tree> iv_map)
1662 bool changed = false;
1664 if (is_gimple_debug (copy))
1666 if (gimple_debug_bind_p (copy))
1667 gimple_debug_bind_reset_value (copy);
1668 else if (gimple_debug_source_bind_p (copy))
1669 return false;
1670 else
1671 gcc_unreachable ();
1673 return false;
1676 if (dump_file)
1678 fprintf (dump_file, "[codegen] renaming uses of stmt: ");
1679 print_gimple_stmt (dump_file, copy, 0, 0);
1682 use_operand_p use_p;
1683 ssa_op_iter op_iter;
1684 FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_USE)
1686 tree old_name = USE_FROM_PTR (use_p);
1688 if (dump_file)
1690 fprintf (dump_file, "[codegen] renaming old_name = ");
1691 print_generic_expr (dump_file, old_name, 0);
1692 fprintf (dump_file, "\n");
1695 if (TREE_CODE (old_name) != SSA_NAME
1696 || SSA_NAME_IS_DEFAULT_DEF (old_name))
1697 continue;
1699 changed = true;
1700 tree new_expr = get_rename (gsi_tgt->bb, old_name,
1701 old_bb, unknown_phi);
1703 if (new_expr)
1705 tree type_old_name = TREE_TYPE (old_name);
1706 tree type_new_expr = TREE_TYPE (new_expr);
1708 if (dump_file)
1710 fprintf (dump_file, "[codegen] from rename_map: new_name = ");
1711 print_generic_expr (dump_file, new_expr, 0);
1712 fprintf (dump_file, "\n");
1715 if (type_old_name != type_new_expr
1716 || TREE_CODE (new_expr) != SSA_NAME)
1718 tree var = create_tmp_var (type_old_name, "var");
1720 if (!useless_type_conversion_p (type_old_name, type_new_expr))
1721 new_expr = fold_convert (type_old_name, new_expr);
1723 gimple_seq stmts;
1724 new_expr = force_gimple_operand (new_expr, &stmts, true, var);
1725 gsi_insert_earliest (stmts);
1728 replace_exp (use_p, new_expr);
1729 continue;
1732 gimple_seq stmts;
1733 new_expr = get_rename_from_scev (old_name, &stmts, loop, gimple_bb (copy),
1734 old_bb, iv_map);
1735 if (!new_expr || codegen_error_p ())
1736 return false;
1738 if (dump_file)
1740 fprintf (dump_file, "[codegen] not in rename map, scev: ");
1741 print_generic_expr (dump_file, new_expr, 0);
1742 fprintf (dump_file, "\n");
1745 gsi_insert_earliest (stmts);
1746 replace_exp (use_p, new_expr);
1748 if (TREE_CODE (new_expr) == INTEGER_CST
1749 && is_gimple_assign (copy))
1751 tree rhs = gimple_assign_rhs1 (copy);
1753 if (TREE_CODE (rhs) == ADDR_EXPR)
1754 recompute_tree_invariant_for_addr_expr (rhs);
1757 set_rename (old_name, new_expr);
1760 return changed;
1763 /* Returns a basic block that could correspond to where a constant was defined
1764 in the original code. In the original code OLD_BB had the definition, we
1765 need to find which basic block out of the copies of old_bb, in the new
1766 region, should a definition correspond to if it has to reach BB. */
1768 basic_block translate_isl_ast_to_gimple::
1769 get_def_bb_for_const (basic_block bb, basic_block old_bb) const
1771 vec <basic_block> *bbs = region->copied_bb_map->get (old_bb);
1773 if (!bbs || bbs->is_empty ())
1774 return NULL;
1776 if (1 == bbs->length ())
1777 return (*bbs)[0];
1779 int i;
1780 basic_block b1 = NULL, b2;
1781 FOR_EACH_VEC_ELT (*bbs, i, b2)
1783 if (b2 == bb)
1784 return bb;
1786 /* BB and B2 are in two unrelated if-clauses. */
1787 if (!dominated_by_p (CDI_DOMINATORS, bb, b2))
1788 continue;
1790 /* Compute the nearest dominator. */
1791 if (!b1 || dominated_by_p (CDI_DOMINATORS, b2, b1))
1792 b1 = b2;
1795 gcc_assert (b1);
1796 return b1;
1799 /* Get the new name of OP (from OLD_BB) to be used in NEW_BB. PHI_KIND
1800 determines the kind of phi node. */
1802 tree translate_isl_ast_to_gimple::
1803 get_new_name (basic_block new_bb, tree op,
1804 basic_block old_bb, phi_node_kind phi_kind) const
1806 /* For constants the names are the same. */
1807 if (TREE_CODE (op) != SSA_NAME)
1808 return op;
1810 return get_rename (new_bb, op, old_bb, phi_kind);
1813 /* Return a debug location for OP. */
1815 static location_t
1816 get_loc (tree op)
1818 location_t loc = UNKNOWN_LOCATION;
1820 if (TREE_CODE (op) == SSA_NAME)
1821 loc = gimple_location (SSA_NAME_DEF_STMT (op));
1822 return loc;
1825 /* Returns the incoming edges of basic_block BB in the pair. The first edge is
1826 the init edge (from outside the loop) and the second one is the back edge
1827 from the same loop. */
1829 std::pair<edge, edge>
1830 get_edges (basic_block bb)
1832 std::pair<edge, edge> edges;
1833 edge e;
1834 edge_iterator ei;
1835 FOR_EACH_EDGE (e, ei, bb->preds)
1836 if (bb->loop_father != e->src->loop_father)
1837 edges.first = e;
1838 else
1839 edges.second = e;
1840 return edges;
1843 /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI
1844 must be found unless they can be POSTPONEd for later. */
1846 bool translate_isl_ast_to_gimple::
1847 copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
1848 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
1849 bool postpone)
1851 gcc_assert (gimple_phi_num_args (old_phi) == gimple_phi_num_args (new_phi));
1853 basic_block new_bb = gimple_bb (new_phi);
1854 for (unsigned i = 0; i < gimple_phi_num_args (old_phi); i++)
1856 edge e;
1857 if (gimple_phi_arg_edge (old_phi, i) == ibp_old_bb.first)
1858 e = ibp_new_bb.first;
1859 else
1860 e = ibp_new_bb.second;
1862 tree old_name = gimple_phi_arg_def (old_phi, i);
1863 tree new_name = get_new_name (new_bb, old_name,
1864 gimple_bb (old_phi), loop_phi);
1865 if (new_name)
1867 add_phi_arg (new_phi, new_name, e, get_loc (old_name));
1868 continue;
1871 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
1872 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
1873 /* If the phi arg was a function arg, or wasn't defined, just use the
1874 old name. */
1875 add_phi_arg (new_phi, old_name, e, get_loc (old_name));
1876 else if (postpone)
1878 /* Postpone code gen for later for those back-edges we don't have the
1879 names yet. */
1880 region->incomplete_phis.safe_push (std::make_pair (old_phi, new_phi));
1881 if (dump_file)
1882 fprintf (dump_file, "[codegen] postpone loop phi nodes.\n");
1884 else
1885 /* Either we should add the arg to phi or, we should postpone. */
1886 return false;
1888 return true;
1891 /* Copy loop phi nodes from BB to NEW_BB. */
1893 bool translate_isl_ast_to_gimple::
1894 copy_loop_phi_nodes (basic_block bb, basic_block new_bb)
1896 if (dump_file)
1897 fprintf (dump_file, "[codegen] copying loop phi nodes in bb_%d.\n",
1898 new_bb->index);
1900 /* Loop phi nodes should have only two arguments. */
1901 gcc_assert (2 == EDGE_COUNT (bb->preds));
1903 /* First edge is the init edge and second is the back edge. */
1904 init_back_edge_pair_t ibp_old_bb = get_edges (bb);
1906 /* First edge is the init edge and second is the back edge. */
1907 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
1909 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1910 gsi_next (&psi))
1912 gphi *phi = psi.phi ();
1913 tree res = gimple_phi_result (phi);
1914 if (virtual_operand_p (res))
1915 continue;
1916 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
1917 continue;
1919 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
1920 tree new_res = create_new_def_for (res, new_phi,
1921 gimple_phi_result_ptr (new_phi));
1922 set_rename (res, new_res);
1923 codegen_error = !copy_loop_phi_args (phi, ibp_old_bb, new_phi,
1924 ibp_new_bb, true);
1925 update_stmt (new_phi);
1927 if (dump_file)
1929 fprintf (dump_file, "[codegen] creating loop-phi node: ");
1930 print_gimple_stmt (dump_file, new_phi, 0, 0);
1934 return true;
1937 /* Return the init value of PHI, the value coming from outside the loop. */
1939 static tree
1940 get_loop_init_value (gphi *phi)
1943 loop_p loop = gimple_bb (phi)->loop_father;
1945 edge e;
1946 edge_iterator ei;
1947 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
1948 if (e->src->loop_father != loop)
1949 return gimple_phi_arg_def (phi, e->dest_idx);
1951 return NULL_TREE;
1954 /* Find the init value (the value which comes from outside the loop), of one of
1955 the operands of DEF which is defined by a loop phi. */
1957 static tree
1958 find_init_value (gimple *def)
1960 if (gimple_code (def) == GIMPLE_PHI)
1961 return get_loop_init_value (as_a <gphi*> (def));
1963 if (gimple_vuse (def))
1964 return NULL_TREE;
1966 ssa_op_iter iter;
1967 use_operand_p use_p;
1968 FOR_EACH_SSA_USE_OPERAND (use_p, def, iter, SSA_OP_USE)
1970 tree use = USE_FROM_PTR (use_p);
1971 if (TREE_CODE (use) == SSA_NAME)
1973 if (tree res = find_init_value (SSA_NAME_DEF_STMT (use)))
1974 return res;
1978 return NULL_TREE;
1981 /* Return the init value, the value coming from outside the loop. */
1983 static tree
1984 find_init_value_close_phi (gphi *phi)
1986 gcc_assert (gimple_phi_num_args (phi) == 1);
1987 tree use_arg = gimple_phi_arg_def (phi, 0);
1988 gimple *def = SSA_NAME_DEF_STMT (use_arg);
1989 return find_init_value (def);
1993 tree translate_isl_ast_to_gimple::
1994 add_close_phis_to_outer_loops (tree last_merge_name, edge last_e,
1995 gimple *old_close_phi)
1997 sese_l &codegen_region = region->if_region->true_region->region;
1998 gimple *stmt = SSA_NAME_DEF_STMT (last_merge_name);
1999 basic_block bb = gimple_bb (stmt);
2000 if (!bb_in_sese_p (bb, codegen_region))
2001 return last_merge_name;
2003 loop_p loop = bb->loop_father;
2004 if (!loop_in_sese_p (loop, codegen_region))
2005 return last_merge_name;
2007 edge e = single_exit (loop);
2009 if (dominated_by_p (CDI_DOMINATORS, e->dest, last_e->src))
2010 return last_merge_name;
2012 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2013 tree old_close_phi_name = gimple_phi_result (old_close_phi);
2015 bb = e->dest;
2016 if (!bb_contains_loop_close_phi_nodes (bb) || !single_succ_p (bb))
2017 bb = split_edge (e);
2019 gphi *close_phi = create_phi_node (SSA_NAME_VAR (last_merge_name), bb);
2020 tree res = create_new_def_for (last_merge_name, close_phi,
2021 gimple_phi_result_ptr (close_phi));
2022 set_rename (old_close_phi_name, res);
2023 add_phi_arg (close_phi, last_merge_name, e, get_loc (old_name));
2024 last_merge_name = res;
2026 return add_close_phis_to_outer_loops (last_merge_name, last_e, old_close_phi);
2029 /* Add phi nodes to all merge points of all the diamonds enclosing the loop of
2030 the close phi node PHI. */
2032 bool translate_isl_ast_to_gimple::
2033 add_close_phis_to_merge_points (gphi *old_close_phi, gphi *new_close_phi,
2034 tree default_value)
2036 sese_l &codegen_region = region->if_region->true_region->region;
2037 basic_block default_value_bb = get_entry_bb (codegen_region);
2038 if (SSA_NAME == TREE_CODE (default_value))
2040 gimple *stmt = SSA_NAME_DEF_STMT (default_value);
2041 if (!stmt || gimple_code (stmt) == GIMPLE_NOP)
2042 return false;
2043 default_value_bb = gimple_bb (stmt);
2046 basic_block new_close_phi_bb = gimple_bb (new_close_phi);
2048 tree old_close_phi_name = gimple_phi_result (old_close_phi);
2049 tree new_close_phi_name = gimple_phi_result (new_close_phi);
2050 tree last_merge_name = new_close_phi_name;
2051 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2053 int i;
2054 edge merge_e;
2055 FOR_EACH_VEC_ELT_REVERSE (merge_points, i, merge_e)
2057 basic_block new_merge_bb = merge_e->src;
2058 if (!dominated_by_p (CDI_DOMINATORS, new_merge_bb, default_value_bb))
2059 continue;
2061 last_merge_name = add_close_phis_to_outer_loops (last_merge_name, merge_e,
2062 old_close_phi);
2064 gphi *merge_phi = create_phi_node (SSA_NAME_VAR (old_close_phi_name), new_merge_bb);
2065 tree merge_res = create_new_def_for (old_close_phi_name, merge_phi,
2066 gimple_phi_result_ptr (merge_phi));
2067 set_rename (old_close_phi_name, merge_res);
2069 edge from_loop = NULL, from_default_value = NULL;
2070 edge e;
2071 edge_iterator ei;
2072 FOR_EACH_EDGE (e, ei, new_merge_bb->preds)
2073 if (dominated_by_p (CDI_DOMINATORS, e->src, new_close_phi_bb))
2074 from_loop = e;
2075 else
2076 from_default_value = e;
2078 /* Because CDI_POST_DOMINATORS are not updated, we only rely on
2079 CDI_DOMINATORS, which may not handle all cases where new_close_phi_bb
2080 is contained in another condition. */
2081 if (!from_default_value || !from_loop)
2082 return false;
2084 add_phi_arg (merge_phi, last_merge_name, from_loop, get_loc (old_name));
2085 add_phi_arg (merge_phi, default_value, from_default_value, get_loc (old_name));
2087 if (dump_file)
2089 fprintf (dump_file, "[codegen] Adding guard-phi: ");
2090 print_gimple_stmt (dump_file, merge_phi, 0, 0);
2093 update_stmt (merge_phi);
2094 last_merge_name = merge_res;
2097 return true;
2100 /* Copy all the loop-close phi args from BB to NEW_BB. */
2102 bool translate_isl_ast_to_gimple::
2103 copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb, bool postpone)
2105 for (gphi_iterator psi = gsi_start_phis (old_bb); !gsi_end_p (psi);
2106 gsi_next (&psi))
2108 gphi *old_close_phi = psi.phi ();
2109 tree res = gimple_phi_result (old_close_phi);
2110 if (virtual_operand_p (res))
2111 continue;
2113 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2114 /* Loop close phi nodes should not be scev_analyzable_p. */
2115 gcc_unreachable ();
2117 gphi *new_close_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
2118 tree new_res = create_new_def_for (res, new_close_phi,
2119 gimple_phi_result_ptr (new_close_phi));
2120 set_rename (res, new_res);
2122 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2123 tree new_name = get_new_name (new_bb, old_name, old_bb, close_phi);
2125 /* Predecessor basic blocks of a loop close phi should have been code
2126 generated before. FIXME: This is fixable by merging PHIs from inner
2127 loops as well. See: gfortran.dg/graphite/interchange-3.f90. */
2128 if (!new_name)
2129 return false;
2131 add_phi_arg (new_close_phi, new_name, single_pred_edge (new_bb),
2132 get_loc (old_name));
2133 if (dump_file)
2135 fprintf (dump_file, "[codegen] Adding loop close phi: ");
2136 print_gimple_stmt (dump_file, new_close_phi, 0, 0);
2139 update_stmt (new_close_phi);
2141 /* When there is no loop guard around this codegenerated loop, there is no
2142 need to collect the close-phi arg. */
2143 if (merge_points.is_empty ())
2144 continue;
2146 /* Add a PHI in the succ_new_bb for each close phi of the loop. */
2147 tree default_value = find_init_value_close_phi (new_close_phi);
2149 /* A close phi must come from a loop-phi having a default value. */
2150 if (!default_value)
2152 if (!postpone)
2153 return false;
2155 region->incomplete_phis.safe_push (std::make_pair (old_close_phi,
2156 new_close_phi));
2157 if (dump_file)
2159 fprintf (dump_file, "[codegen] postpone close phi nodes: ");
2160 print_gimple_stmt (dump_file, new_close_phi, 0, 0);
2162 continue;
2165 if (!add_close_phis_to_merge_points (old_close_phi, new_close_phi,
2166 default_value))
2167 return false;
2170 return true;
2173 /* Copy loop close phi nodes from BB to NEW_BB. */
2175 bool translate_isl_ast_to_gimple::
2176 copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb)
2178 if (dump_file)
2179 fprintf (dump_file, "[codegen] copying loop close phi nodes in bb_%d.\n",
2180 new_bb->index);
2181 /* Loop close phi nodes should have only one argument. */
2182 gcc_assert (1 == EDGE_COUNT (old_bb->preds));
2184 return copy_loop_close_phi_args (old_bb, new_bb, true);
2188 /* Add NEW_NAME as the ARGNUM-th arg of NEW_PHI which is in NEW_BB.
2189 DOMINATING_PRED is the predecessor basic block of OLD_BB which dominates the
2190 other pred of OLD_BB as well. If no such basic block exists then it is NULL.
2191 NON_DOMINATING_PRED is a pred which does not dominate OLD_BB, it cannot be
2192 NULL.
2194 Case1: OLD_BB->preds {BB1, BB2} and BB1 does not dominate BB2 and vice versa.
2195 In this case DOMINATING_PRED = NULL.
2197 Case2: OLD_BB->preds {BB1, BB2} and BB1 dominates BB2.
2199 Returns true on successful copy of the args, false otherwise. */
2201 bool translate_isl_ast_to_gimple::
2202 add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
2203 edge old_bb_dominating_edge,
2204 edge old_bb_non_dominating_edge,
2205 gphi *phi, gphi *new_phi,
2206 basic_block new_bb)
2208 basic_block def_pred[2] = { NULL, NULL };
2209 int not_found_bb_index = -1;
2210 for (int i = 0; i < 2; i++)
2212 /* If the corresponding def_bb could not be found the entry will be
2213 NULL. */
2214 if (TREE_CODE (old_phi_args[i]) == INTEGER_CST)
2215 def_pred[i] = get_def_bb_for_const (new_bb,
2216 gimple_phi_arg_edge (phi, i)->src);
2217 else if (new_phi_args[i] && (TREE_CODE (new_phi_args[i]) == SSA_NAME))
2218 def_pred[i] = gimple_bb (SSA_NAME_DEF_STMT (new_phi_args[i]));
2220 if (!def_pred[i])
2222 /* When non are available bail out. */
2223 if (not_found_bb_index != -1)
2224 return false;
2225 not_found_bb_index = i;
2229 /* Here we are pattern matching on the structure of CFG w.r.t. old one. */
2230 if (old_bb_dominating_edge)
2232 if (not_found_bb_index != -1)
2233 return false;
2235 basic_block new_pred1 = (*new_bb->preds)[0]->src;
2236 basic_block new_pred2 = (*new_bb->preds)[1]->src;
2237 vec <basic_block> *bbs
2238 = region->copied_bb_map->get (old_bb_non_dominating_edge->src);
2240 /* Could not find a mapping. */
2241 if (!bbs)
2242 return false;
2244 basic_block new_pred = NULL;
2245 basic_block b;
2246 int i;
2247 FOR_EACH_VEC_ELT (*bbs, i, b)
2249 if (dominated_by_p (CDI_DOMINATORS, new_pred1, b))
2251 /* FIXME: If we have already found new_pred then we have to
2252 disambiguate, bail out for now. */
2253 if (new_pred)
2254 return false;
2255 new_pred = new_pred1;
2257 if (dominated_by_p (CDI_DOMINATORS, new_pred2, b))
2259 /* FIXME: If we have already found new_pred then we have to either
2260 it dominates both or we have to disambiguate, bail out. */
2261 if (new_pred)
2262 return false;
2263 new_pred = new_pred2;
2267 if (!new_pred)
2268 return false;
2270 edge new_non_dominating_edge = find_edge (new_pred, new_bb);
2271 gcc_assert (new_non_dominating_edge);
2272 /* FIXME: Validate each args just like in loop-phis. */
2273 /* By the process of elimination we first insert insert phi-edge for
2274 non-dominating pred which is computed above and then we insert the
2275 remaining one. */
2276 int inserted_edge = 0;
2277 for (; inserted_edge < 2; inserted_edge++)
2279 edge new_bb_pred_edge = gimple_phi_arg_edge (new_phi, inserted_edge);
2280 if (new_non_dominating_edge == new_bb_pred_edge)
2282 add_phi_arg (new_phi, new_phi_args[inserted_edge],
2283 new_non_dominating_edge,
2284 get_loc (old_phi_args[inserted_edge]));
2285 break;
2288 if (inserted_edge == 2)
2289 return false;
2291 int edge_dominating = inserted_edge == 0 ? 1 : 0;
2293 edge new_dominating_edge = NULL;
2294 for (inserted_edge = 0; inserted_edge < 2; inserted_edge++)
2296 edge e = gimple_phi_arg_edge (new_phi, inserted_edge);
2297 if (e != new_non_dominating_edge)
2299 new_dominating_edge = e;
2300 add_phi_arg (new_phi, new_phi_args[edge_dominating],
2301 new_dominating_edge,
2302 get_loc (old_phi_args[inserted_edge]));
2303 break;
2306 gcc_assert (new_dominating_edge);
2308 else
2310 /* Classic diamond structure: both edges are non-dominating. We need to
2311 find one unique edge then the other can be found be elimination. If
2312 any definition (def_pred) dominates both the preds of new_bb then we
2313 bail out. Entries of def_pred maybe NULL, in that case we must
2314 uniquely find pred with help of only one entry. */
2315 edge new_e[2] = { NULL, NULL };
2316 for (int i = 0; i < 2; i++)
2318 edge e;
2319 edge_iterator ei;
2320 FOR_EACH_EDGE (e, ei, new_bb->preds)
2321 if (def_pred[i]
2322 && dominated_by_p (CDI_DOMINATORS, e->src, def_pred[i]))
2324 if (new_e[i])
2325 /* We do not know how to handle the case when def_pred
2326 dominates more than a predecessor. */
2327 return false;
2328 new_e[i] = e;
2332 gcc_assert (new_e[0] || new_e[1]);
2334 /* Find the other edge by process of elimination. */
2335 if (not_found_bb_index != -1)
2337 gcc_assert (!new_e[not_found_bb_index]);
2338 int found_bb_index = not_found_bb_index == 1 ? 0 : 1;
2339 edge e;
2340 edge_iterator ei;
2341 FOR_EACH_EDGE (e, ei, new_bb->preds)
2343 if (new_e[found_bb_index] == e)
2344 continue;
2345 new_e[not_found_bb_index] = e;
2349 /* Add edges to phi args. */
2350 for (int i = 0; i < 2; i++)
2351 add_phi_arg (new_phi, new_phi_args[i], new_e[i],
2352 get_loc (old_phi_args[i]));
2355 return true;
2358 /* Copy the arguments of cond-phi node PHI, to NEW_PHI in the codegenerated
2359 region. If postpone is true and it isn't possible to copy any arg of PHI,
2360 the PHI is added to the REGION->INCOMPLETE_PHIS to be codegenerated later.
2361 Returns false if the copying was unsuccessful. */
2363 bool translate_isl_ast_to_gimple::
2364 copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map, bool postpone)
2366 if (dump_file)
2367 fprintf (dump_file, "[codegen] copying cond phi args.\n");
2368 gcc_assert (2 == gimple_phi_num_args (phi));
2370 basic_block new_bb = gimple_bb (new_phi);
2371 loop_p loop = gimple_bb (phi)->loop_father;
2373 basic_block old_bb = gimple_bb (phi);
2374 edge old_bb_non_dominating_edge = NULL, old_bb_dominating_edge = NULL;
2376 edge e;
2377 edge_iterator ei;
2378 FOR_EACH_EDGE (e, ei, old_bb->preds)
2379 if (!dominated_by_p (CDI_DOMINATORS, old_bb, e->src))
2380 old_bb_non_dominating_edge = e;
2381 else
2382 old_bb_dominating_edge = e;
2384 gcc_assert (!dominated_by_p (CDI_DOMINATORS, old_bb,
2385 old_bb_non_dominating_edge->src));
2387 tree new_phi_args[2];
2388 tree old_phi_args[2];
2390 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
2392 tree old_name = gimple_phi_arg_def (phi, i);
2393 tree new_name = get_new_name (new_bb, old_name, old_bb, cond_phi);
2394 old_phi_args[i] = old_name;
2395 if (new_name)
2397 new_phi_args [i] = new_name;
2398 continue;
2401 /* If the phi-arg was a parameter. */
2402 if (vec_find (region->params, old_name) != -1)
2404 new_phi_args [i] = old_name;
2405 if (dump_file)
2407 fprintf (dump_file,
2408 "[codegen] parameter argument to phi, new_expr: ");
2409 print_generic_expr (dump_file, new_phi_args[i], 0);
2410 fprintf (dump_file, "\n");
2412 continue;
2415 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
2416 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
2417 /* FIXME: If the phi arg was a function arg, or wasn't defined, just use
2418 the old name. */
2419 return false;
2421 if (postpone)
2423 /* If the phi-arg is scev-analyzeable but only in the first stage. */
2424 if (is_gimple_reg (old_name)
2425 && scev_analyzable_p (old_name, region->region))
2427 gimple_seq stmts;
2428 tree new_expr = get_rename_from_scev (old_name, &stmts, loop,
2429 new_bb, old_bb, iv_map);
2430 if (codegen_error_p ())
2431 return false;
2433 gcc_assert (new_expr);
2434 if (dump_file)
2436 fprintf (dump_file,
2437 "[codegen] scev analyzeable, new_expr: ");
2438 print_generic_expr (dump_file, new_expr, 0);
2439 fprintf (dump_file, "\n");
2441 gsi_insert_earliest (stmts);
2442 new_phi_args [i] = new_name;
2443 continue;
2446 /* Postpone code gen for later for back-edges. */
2447 region->incomplete_phis.safe_push (std::make_pair (phi, new_phi));
2449 if (dump_file)
2451 fprintf (dump_file, "[codegen] postpone cond phi nodes: ");
2452 print_gimple_stmt (dump_file, new_phi, 0, 0);
2455 new_phi_args [i] = NULL_TREE;
2456 continue;
2458 else
2459 /* Either we should add the arg to phi or, we should postpone. */
2460 return false;
2463 /* If none of the args have been determined in the first stage then wait until
2464 later. */
2465 if (postpone && !new_phi_args[0] && !new_phi_args[1])
2466 return true;
2468 return add_phi_arg_for_new_expr (old_phi_args, new_phi_args,
2469 old_bb_dominating_edge,
2470 old_bb_non_dominating_edge,
2471 phi, new_phi, new_bb);
2474 /* Copy cond phi nodes from BB to NEW_BB. A cond-phi node is a basic block
2475 containing phi nodes coming from two predecessors, and none of them are back
2476 edges. */
2478 bool translate_isl_ast_to_gimple::
2479 copy_cond_phi_nodes (basic_block bb, basic_block new_bb, vec<tree> iv_map)
2482 gcc_assert (!bb_contains_loop_close_phi_nodes (bb));
2484 if (dump_file)
2485 fprintf (dump_file, "[codegen] copying cond phi nodes in bb_%d.\n",
2486 new_bb->index);
2488 /* Cond phi nodes should have exactly two arguments. */
2489 gcc_assert (2 == EDGE_COUNT (bb->preds));
2491 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2492 gsi_next (&psi))
2494 gphi *phi = psi.phi ();
2495 tree res = gimple_phi_result (phi);
2496 if (virtual_operand_p (res))
2497 continue;
2498 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2499 /* Cond phi nodes should not be scev_analyzable_p. */
2500 gcc_unreachable ();
2502 gphi *new_phi = create_phi_node (SSA_NAME_VAR (res), new_bb);
2503 tree new_res = create_new_def_for (res, new_phi,
2504 gimple_phi_result_ptr (new_phi));
2505 set_rename (res, new_res);
2507 if (!copy_cond_phi_args (phi, new_phi, iv_map, true))
2508 return false;
2510 update_stmt (new_phi);
2513 return true;
2516 /* Return true if STMT should be copied from region to the new code-generated
2517 region. LABELs, CONDITIONS, induction-variables and region parameters need
2518 not be copied. */
2520 static bool
2521 should_copy_to_new_region (gimple *stmt, sese_info_p region)
2523 /* Do not copy labels or conditions. */
2524 if (gimple_code (stmt) == GIMPLE_LABEL
2525 || gimple_code (stmt) == GIMPLE_COND)
2526 return false;
2528 tree lhs;
2529 /* Do not copy induction variables. */
2530 if (is_gimple_assign (stmt)
2531 && (lhs = gimple_assign_lhs (stmt))
2532 && TREE_CODE (lhs) == SSA_NAME
2533 && is_gimple_reg (lhs)
2534 && scev_analyzable_p (lhs, region->region))
2535 return false;
2537 /* Do not copy parameters that have been generated in the header of the
2538 scop. */
2539 if (is_gimple_assign (stmt)
2540 && (lhs = gimple_assign_lhs (stmt))
2541 && TREE_CODE (lhs) == SSA_NAME
2542 && region->parameter_rename_map->get(lhs))
2543 return false;
2545 return true;
2548 /* Create new names for all the definitions created by COPY and add replacement
2549 mappings for each new name. */
2551 void translate_isl_ast_to_gimple::
2552 set_rename_for_each_def (gimple *stmt)
2554 def_operand_p def_p;
2555 ssa_op_iter op_iter;
2556 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
2558 tree old_name = DEF_FROM_PTR (def_p);
2559 tree new_name = create_new_def_for (old_name, stmt, def_p);
2560 set_rename (old_name, new_name);
2564 /* Duplicates the statements of basic block BB into basic block NEW_BB
2565 and compute the new induction variables according to the IV_MAP. */
2567 bool translate_isl_ast_to_gimple::
2568 graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
2569 vec<tree> iv_map)
2571 /* Iterator poining to the place where new statement (s) will be inserted. */
2572 gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
2574 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
2575 gsi_next (&gsi))
2577 gimple *stmt = gsi_stmt (gsi);
2578 if (!should_copy_to_new_region (stmt, region))
2579 continue;
2581 /* Create a new copy of STMT and duplicate STMT's virtual
2582 operands. */
2583 gimple *copy = gimple_copy (stmt);
2584 gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
2586 if (dump_file)
2588 fprintf (dump_file, "[codegen] inserting statement: ");
2589 print_gimple_stmt (dump_file, copy, 0, 0);
2592 maybe_duplicate_eh_stmt (copy, stmt);
2593 gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
2595 /* Crete new names for each def in the copied stmt. */
2596 set_rename_for_each_def (copy);
2598 loop_p loop = bb->loop_father;
2599 if (rename_uses (copy, &gsi_tgt, bb, loop, iv_map))
2601 fold_stmt_inplace (&gsi_tgt);
2602 gcc_assert (gsi_stmt (gsi_tgt) == copy);
2605 if (codegen_error_p ())
2606 return false;
2608 /* For each SSA_NAME in the parameter_rename_map rename their usage. */
2609 ssa_op_iter iter;
2610 use_operand_p use_p;
2611 if (!is_gimple_debug (copy))
2612 FOR_EACH_SSA_USE_OPERAND (use_p, copy, iter, SSA_OP_USE)
2614 tree old_name = USE_FROM_PTR (use_p);
2616 if (TREE_CODE (old_name) != SSA_NAME
2617 || SSA_NAME_IS_DEFAULT_DEF (old_name))
2618 continue;
2620 tree *new_expr = region->parameter_rename_map->get (old_name);
2621 if (!new_expr)
2622 continue;
2624 replace_exp (use_p, *new_expr);
2627 update_stmt (copy);
2630 return true;
2634 /* Given a basic block containing close-phi it returns the new basic block where
2635 to insert a copy of the close-phi nodes. All the uses in close phis should
2636 come from a single loop otherwise it returns NULL. */
2638 edge translate_isl_ast_to_gimple::
2639 edge_for_new_close_phis (basic_block bb)
2641 /* Make sure that NEW_BB is the new_loop->exit->dest. We find the definition
2642 of close phi in the original code and then find the mapping of basic block
2643 defining that variable. If there are multiple close-phis and they are
2644 defined in different loops (in the original or in the new code) because of
2645 loop splitting, then we bail out. */
2646 loop_p new_loop = NULL;
2647 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2648 gsi_next (&psi))
2650 gphi *phi = psi.phi ();
2651 tree name = gimple_phi_arg_def (phi, 0);
2652 basic_block old_loop_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
2654 vec <basic_block> *bbs = region->copied_bb_map->get (old_loop_bb);
2655 if (!bbs || bbs->length () != 1)
2656 /* This is one of the places which shows preserving original structure
2657 is not always possible, as we may need to insert close PHI for a loop
2658 where the latch does not have any mapping, or the mapping is
2659 ambiguous. */
2660 return NULL;
2662 if (!new_loop)
2663 new_loop = (*bbs)[0]->loop_father;
2664 else if (new_loop != (*bbs)[0]->loop_father)
2665 return NULL;
2668 if (!new_loop)
2669 return NULL;
2671 return single_exit (new_loop);
2674 /* Copies BB and includes in the copied BB all the statements that can
2675 be reached following the use-def chains from the memory accesses,
2676 and returns the next edge following this new block. */
2678 edge translate_isl_ast_to_gimple::
2679 copy_bb_and_scalar_dependences (basic_block bb, edge next_e, vec<tree> iv_map)
2681 int num_phis = number_of_phi_nodes (bb);
2683 if (region->copied_bb_map->get (bb))
2685 /* FIXME: we should be able to handle phi nodes with args coming from
2686 outside the region. */
2687 if (num_phis)
2689 codegen_error = true;
2690 return NULL;
2694 basic_block new_bb = NULL;
2695 if (bb_contains_loop_close_phi_nodes (bb))
2697 if (dump_file)
2698 fprintf (dump_file, "[codegen] bb_%d contains close phi nodes.\n",
2699 bb->index);
2701 edge e = edge_for_new_close_phis (bb);
2702 if (!e)
2704 codegen_error = true;
2705 return NULL;
2708 basic_block phi_bb = e->dest;
2710 if (!bb_contains_loop_close_phi_nodes (phi_bb) || !single_succ_p (phi_bb))
2711 phi_bb = split_edge (e);
2713 gcc_assert (single_pred_edge (phi_bb)->src->loop_father
2714 != single_pred_edge (phi_bb)->dest->loop_father);
2716 if (!copy_loop_close_phi_nodes (bb, phi_bb))
2718 codegen_error = true;
2719 return NULL;
2722 if (e == next_e)
2723 new_bb = phi_bb;
2724 else
2725 new_bb = split_edge (next_e);
2727 else
2729 new_bb = split_edge (next_e);
2730 if (num_phis > 0 && bb_contains_loop_phi_nodes (bb))
2732 basic_block phi_bb = next_e->dest->loop_father->header;
2734 /* At this point we are unable to codegenerate by still preserving the SSA
2735 structure because maybe the loop is completely unrolled and the PHIs
2736 and cross-bb scalar dependencies are untrackable w.r.t. the original
2737 code. See gfortran.dg/graphite/pr29832.f90. */
2738 if (EDGE_COUNT (bb->preds) != EDGE_COUNT (phi_bb->preds))
2740 codegen_error = true;
2741 return NULL;
2744 /* In case isl did some loop peeling, like this:
2746 S_8(0);
2747 for (int c1 = 1; c1 <= 5; c1 += 1) {
2748 S_8(c1);
2750 S_8(6);
2752 there should be no loop-phi nodes in S_8(0).
2754 FIXME: We need to reason about dynamic instances of S_8, i.e., the
2755 values of all scalar variables: for the moment we instantiate only
2756 SCEV analyzable expressions on the iteration domain, and we need to
2757 extend that to reductions that cannot be analyzed by SCEV. */
2758 if (!bb_in_sese_p (phi_bb, region->if_region->true_region->region))
2760 codegen_error = true;
2761 return NULL;
2764 if (dump_file)
2765 fprintf (dump_file, "[codegen] bb_%d contains loop phi nodes.\n",
2766 bb->index);
2767 if (!copy_loop_phi_nodes (bb, phi_bb))
2769 codegen_error = true;
2770 return NULL;
2773 else if (num_phis > 0)
2775 if (dump_file)
2776 fprintf (dump_file, "[codegen] bb_%d contains cond phi nodes.\n",
2777 bb->index);
2779 basic_block phi_bb = single_pred (new_bb);
2780 loop_p loop_father = new_bb->loop_father;
2782 /* Move back until we find the block with two predecessors. */
2783 while (single_pred_p (phi_bb))
2784 phi_bb = single_pred_edge (phi_bb)->src;
2786 /* If a corresponding merge-point was not found, then abort codegen. */
2787 if (phi_bb->loop_father != loop_father
2788 || !bb_in_sese_p (phi_bb, region->if_region->true_region->region)
2789 || !copy_cond_phi_nodes (bb, phi_bb, iv_map))
2791 codegen_error = true;
2792 return NULL;
2797 if (dump_file)
2798 fprintf (dump_file, "[codegen] copying from bb_%d to bb_%d.\n",
2799 bb->index, new_bb->index);
2801 vec <basic_block> *copied_bbs = region->copied_bb_map->get (bb);
2802 if (copied_bbs)
2803 copied_bbs->safe_push (new_bb);
2804 else
2806 vec<basic_block> bbs;
2807 bbs.create (2);
2808 bbs.safe_push (new_bb);
2809 region->copied_bb_map->put (bb, bbs);
2812 if (!graphite_copy_stmts_from_block (bb, new_bb, iv_map))
2814 codegen_error = true;
2815 return NULL;
2818 return single_succ_edge (new_bb);
2821 /* Patch the missing arguments of the phi nodes. */
2823 void translate_isl_ast_to_gimple::
2824 translate_pending_phi_nodes ()
2826 int i;
2827 phi_rename *rename;
2828 FOR_EACH_VEC_ELT (region->incomplete_phis, i, rename)
2830 gphi *old_phi = rename->first;
2831 gphi *new_phi = rename->second;
2832 basic_block old_bb = gimple_bb (old_phi);
2833 basic_block new_bb = gimple_bb (new_phi);
2835 /* First edge is the init edge and second is the back edge. */
2836 init_back_edge_pair_t ibp_old_bb = get_edges (old_bb);
2837 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
2839 if (dump_file)
2841 fprintf (dump_file, "[codegen] translating pending old-phi: ");
2842 print_gimple_stmt (dump_file, old_phi, 0, 0);
2845 auto_vec <tree, 1> iv_map;
2846 if (bb_contains_loop_phi_nodes (new_bb))
2847 codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
2848 ibp_new_bb, false);
2849 else if (bb_contains_loop_close_phi_nodes (new_bb))
2850 codegen_error = !copy_loop_close_phi_args (old_bb, new_bb, false);
2851 else
2852 codegen_error = !copy_cond_phi_args (old_phi, new_phi, iv_map, false);
2854 if (dump_file)
2856 fprintf (dump_file, "[codegen] to new-phi: ");
2857 print_gimple_stmt (dump_file, new_phi, 0, 0);
2859 if (codegen_error_p ())
2860 return;
2864 /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
2866 void translate_isl_ast_to_gimple::
2867 add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
2869 sese_info_p region = scop->scop_info;
2870 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
2871 gcc_assert (nb_parameters == region->params.length ());
2872 unsigned i;
2873 for (i = 0; i < nb_parameters; i++)
2875 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
2876 isl_dim_param, i);
2877 ip[tmp_id] = region->params[i];
2882 /* Generates a build, which specifies the constraints on the parameters. */
2884 __isl_give isl_ast_build *translate_isl_ast_to_gimple::
2885 generate_isl_context (scop_p scop)
2887 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
2888 return isl_ast_build_from_context (context_isl);
2891 /* This method is executed before the construction of a for node. */
2892 __isl_give isl_id *
2893 ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
2895 isl_union_map *dependences = (isl_union_map *) user;
2896 ast_build_info *for_info = XNEW (struct ast_build_info);
2897 isl_union_map *schedule = isl_ast_build_get_schedule (build);
2898 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
2899 int dimension = isl_space_dim (schedule_space, isl_dim_out);
2900 for_info->is_parallelizable =
2901 !carries_deps (schedule, dependences, dimension);
2902 isl_union_map_free (schedule);
2903 isl_space_free (schedule_space);
2904 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
2905 return id;
2908 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
2910 /* Generate isl AST from schedule of SCOP. */
2912 __isl_give isl_ast_node *translate_isl_ast_to_gimple::
2913 scop_to_isl_ast (scop_p scop)
2915 gcc_assert (scop->transformed_schedule);
2917 /* Set the separate option to reduce control flow overhead. */
2918 isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
2919 (isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
2920 isl_ast_build *context_isl = generate_isl_context (scop);
2922 if (flag_loop_parallelize_all)
2924 scop_get_dependences (scop);
2925 context_isl =
2926 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
2927 scop->dependence);
2930 isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
2931 (context_isl, schedule);
2932 isl_ast_build_free (context_isl);
2933 return ast_isl;
2936 #else
2937 /* Get the maximal number of schedule dimensions in the scop SCOP. */
2939 int translate_isl_ast_to_gimple::
2940 get_max_schedule_dimensions (scop_p scop)
2942 int i;
2943 poly_bb_p pbb;
2944 int schedule_dims = 0;
2946 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
2948 int pbb_schedule_dims = isl_map_dim (pbb->transformed, isl_dim_out);
2949 if (pbb_schedule_dims > schedule_dims)
2950 schedule_dims = pbb_schedule_dims;
2953 return schedule_dims;
2956 /* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
2958 For schedules with different dimensionality, the isl AST generator can not
2959 define an order and will just randomly choose an order. The solution to this
2960 problem is to extend all schedules to the maximal number of schedule
2961 dimensions (using '0's for the remaining values). */
2963 __isl_give isl_map *translate_isl_ast_to_gimple::
2964 extend_schedule (__isl_take isl_map *schedule, int nb_schedule_dims)
2966 int tmp_dims = isl_map_dim (schedule, isl_dim_out);
2967 schedule =
2968 isl_map_add_dims (schedule, isl_dim_out, nb_schedule_dims - tmp_dims);
2969 isl_val *zero =
2970 isl_val_int_from_si (isl_map_get_ctx (schedule), 0);
2971 int i;
2972 for (i = tmp_dims; i < nb_schedule_dims; i++)
2974 schedule
2975 = isl_map_fix_val (schedule, isl_dim_out, i, isl_val_copy (zero));
2977 isl_val_free (zero);
2978 return schedule;
2981 /* Generates a schedule, which specifies an order used to
2982 visit elements in a domain. */
2984 __isl_give isl_union_map *translate_isl_ast_to_gimple::
2985 generate_isl_schedule (scop_p scop)
2987 int nb_schedule_dims = get_max_schedule_dimensions (scop);
2988 int i;
2989 poly_bb_p pbb;
2990 isl_union_map *schedule_isl =
2991 isl_union_map_empty (isl_set_get_space (scop->param_context));
2993 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
2995 /* Dead code elimination: when the domain of a PBB is empty,
2996 don't generate code for the PBB. */
2997 if (isl_set_is_empty (pbb->domain))
2998 continue;
3000 isl_map *bb_schedule = isl_map_copy (pbb->transformed);
3001 bb_schedule = isl_map_intersect_domain (bb_schedule,
3002 isl_set_copy (pbb->domain));
3003 bb_schedule = extend_schedule (bb_schedule, nb_schedule_dims);
3004 bb_schedule = isl_map_coalesce (bb_schedule);
3005 schedule_isl
3006 = isl_union_map_union (schedule_isl,
3007 isl_union_map_from_map (bb_schedule));
3008 schedule_isl = isl_union_map_coalesce (schedule_isl);
3010 return schedule_isl;
3013 /* Set the separate option for all dimensions.
3014 This helps to reduce control overhead. */
3016 __isl_give isl_ast_build *translate_isl_ast_to_gimple::
3017 set_options (__isl_take isl_ast_build *control,
3018 __isl_keep isl_union_map *schedule)
3020 isl_ctx *ctx = isl_union_map_get_ctx (schedule);
3021 isl_space *range_space = isl_space_set_alloc (ctx, 0, 1);
3022 range_space =
3023 isl_space_set_tuple_name (range_space, isl_dim_set, "separate");
3024 isl_union_set *range =
3025 isl_union_set_from_set (isl_set_universe (range_space));
3026 isl_union_set *domain = isl_union_map_range (isl_union_map_copy (schedule));
3027 domain = isl_union_set_universe (domain);
3028 isl_union_map *options = isl_union_map_from_domain_and_range (domain, range);
3029 return isl_ast_build_set_options (control, options);
3032 /* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in IP. */
3034 __isl_give isl_ast_node *translate_isl_ast_to_gimple::
3035 scop_to_isl_ast (scop_p scop, ivs_params &ip)
3037 /* Generate loop upper bounds that consist of the current loop iterator, an
3038 operator (< or <=) and an expression not involving the iterator. If this
3039 option is not set, then the current loop iterator may appear several times
3040 in the upper bound. See the isl manual for more details. */
3041 isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, true);
3043 add_parameters_to_ivs_params (scop, ip);
3044 isl_union_map *schedule_isl = generate_isl_schedule (scop);
3045 isl_ast_build *context_isl = generate_isl_context (scop);
3046 context_isl = set_options (context_isl, schedule_isl);
3047 if (flag_loop_parallelize_all)
3049 isl_union_map *dependence = scop_get_dependences (scop);
3050 context_isl =
3051 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
3052 dependence);
3055 isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
3056 schedule_isl);
3057 if (scop->schedule)
3059 isl_schedule_free (scop->schedule);
3060 scop->schedule = NULL;
3063 isl_ast_build_free (context_isl);
3064 return ast_isl;
3066 #endif
3068 /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
3069 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
3071 static void
3072 copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
3073 gimple_stmt_iterator *gsi)
3075 if (!defined_in_sese_p (tr, region->region))
3076 return;
3078 ssa_op_iter iter;
3079 use_operand_p use_p;
3080 FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
3082 tree use_tr = USE_FROM_PTR (use_p);
3084 /* Do not copy parameters that have been generated in the header of the
3085 scop. */
3086 if (region->parameter_rename_map->get(use_tr))
3087 continue;
3089 gimple *def_of_use = SSA_NAME_DEF_STMT (use_tr);
3090 if (!def_of_use)
3091 continue;
3093 copy_def (use_tr, def_of_use, region, to_region, gsi);
3096 gimple *copy = gimple_copy (def_stmt);
3097 gsi_insert_after (gsi, copy, GSI_NEW_STMT);
3099 /* Create new names for all the definitions created by COPY and
3100 add replacement mappings for each new name. */
3101 def_operand_p def_p;
3102 ssa_op_iter op_iter;
3103 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
3105 tree old_name = DEF_FROM_PTR (def_p);
3106 tree new_name = create_new_def_for (old_name, copy, def_p);
3107 region->parameter_rename_map->put(old_name, new_name);
3110 update_stmt (copy);
3113 static void
3114 copy_internal_parameters (sese_info_p region, sese_info_p to_region)
3116 /* For all the parameters which definitino is in the if_region->false_region,
3117 insert code on true_region (if_region->true_region->entry). */
3119 int i;
3120 tree tr;
3121 gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
3123 FOR_EACH_VEC_ELT (region->params, i, tr)
3125 // If def is not in region.
3126 gimple *def_stmt = SSA_NAME_DEF_STMT (tr);
3127 if (def_stmt)
3128 copy_def (tr, def_stmt, region, to_region, &gsi);
3132 /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
3133 Return true if code generation succeeded. */
3135 bool
3136 graphite_regenerate_ast_isl (scop_p scop)
3138 sese_info_p region = scop->scop_info;
3139 translate_isl_ast_to_gimple t (region);
3141 ifsese if_region = NULL;
3142 isl_ast_node *root_node;
3143 ivs_params ip;
3145 timevar_push (TV_GRAPHITE_CODE_GEN);
3146 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
3147 t.add_parameters_to_ivs_params (scop, ip);
3148 root_node = t.scop_to_isl_ast (scop);
3149 #else
3150 root_node = t.scop_to_isl_ast (scop, ip);
3151 #endif
3153 if (dump_file && (dump_flags & TDF_DETAILS))
3155 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
3156 fprintf (dump_file, "[scheduler] original schedule:\n");
3157 print_isl_schedule (dump_file, scop->original_schedule);
3158 fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
3159 print_isl_schedule (dump_file, scop->transformed_schedule);
3161 fprintf (dump_file, "[scheduler] original ast:\n");
3162 print_schedule_ast (dump_file, scop->original_schedule, scop);
3163 #endif
3164 fprintf (dump_file, "[scheduler] AST generated by isl:\n");
3165 print_isl_ast (dump_file, root_node);
3168 recompute_all_dominators ();
3169 graphite_verify ();
3171 if_region = move_sese_in_condition (region);
3172 region->if_region = if_region;
3173 recompute_all_dominators ();
3175 loop_p context_loop = region->region.entry->src->loop_father;
3177 /* Copy all the parameters which are defined in the region. */
3178 copy_internal_parameters(if_region->false_region, if_region->true_region);
3180 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
3181 basic_block bb = split_edge (e);
3183 /* Update the true_region exit edge. */
3184 region->if_region->true_region->region.exit = single_succ_edge (bb);
3186 t.translate_isl_ast (context_loop, root_node, e, ip);
3187 if (t.codegen_error_p ())
3189 if (dump_file)
3190 fprintf (dump_file, "codegen error: "
3191 "reverting back to the original code.\n");
3192 set_ifsese_condition (if_region, integer_zero_node);
3194 else
3196 t.translate_pending_phi_nodes ();
3197 if (!t.codegen_error_p ())
3199 sese_insert_phis_for_liveouts (region,
3200 if_region->region->region.exit->src,
3201 if_region->false_region->region.exit,
3202 if_region->true_region->region.exit);
3203 mark_virtual_operands_for_renaming (cfun);
3204 update_ssa (TODO_update_ssa);
3207 graphite_verify ();
3208 scev_reset ();
3209 recompute_all_dominators ();
3210 graphite_verify ();
3212 if (dump_file)
3213 fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
3215 else
3217 if (dump_file)
3218 fprintf (dump_file, "[codegen] unsuccessful in translating"
3219 " pending phis, reverting back to the original code.\n");
3220 set_ifsese_condition (if_region, integer_zero_node);
3224 free (if_region->true_region);
3225 free (if_region->region);
3226 free (if_region);
3228 ivs_params_clear (ip);
3229 isl_ast_node_free (root_node);
3230 timevar_pop (TV_GRAPHITE_CODE_GEN);
3232 if (dump_file && (dump_flags & TDF_DETAILS))
3234 loop_p loop;
3235 int num_no_dependency = 0;
3237 FOR_EACH_LOOP (loop, 0)
3238 if (loop->can_be_parallel)
3239 num_no_dependency++;
3241 fprintf (dump_file, "%d loops carried no dependency.\n",
3242 num_no_dependency);
3245 return !t.codegen_error_p ();
3248 #endif /* HAVE_isl */