2017-10-02 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / gcc / graphite-isl-ast-to-gimple.c
blobfb91ba15eac1941017f370588c567079abca5191
1 /* Translation of isl AST to Gimple.
2 Copyright (C) 2014-2017 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 #define INCLUDE_MAP
28 #include "system.h"
29 #include "coretypes.h"
30 #include "backend.h"
31 #include "cfghooks.h"
32 #include "tree.h"
33 #include "gimple.h"
34 #include "params.h"
35 #include "fold-const.h"
36 #include "gimple-fold.h"
37 #include "gimple-iterator.h"
38 #include "gimplify.h"
39 #include "gimplify-me.h"
40 #include "tree-eh.h"
41 #include "tree-ssa-loop.h"
42 #include "tree-ssa-operands.h"
43 #include "tree-ssa-propagate.h"
44 #include "tree-pass.h"
45 #include "cfgloop.h"
46 #include "tree-data-ref.h"
47 #include "tree-ssa-loop-manip.h"
48 #include "tree-scalar-evolution.h"
49 #include "gimple-ssa.h"
50 #include "tree-phinodes.h"
51 #include "tree-into-ssa.h"
52 #include "ssa-iterators.h"
53 #include "tree-cfg.h"
54 #include "gimple-pretty-print.h"
55 #include "cfganal.h"
56 #include "value-prof.h"
57 #include "graphite.h"
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 (int_mode_for_size (MAX_FIXED_MODE_SIZE, 0).require ());
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 /* IVS_PARAMS maps isl's scattering and parameter identifiers
77 to corresponding trees. */
79 typedef std::map<isl_id *, tree> ivs_params;
81 /* Free all memory allocated for isl's identifiers. */
83 static void ivs_params_clear (ivs_params &ip)
85 std::map<isl_id *, tree>::iterator it;
86 for (it = ip.begin ();
87 it != ip.end (); it++)
89 isl_id_free (it->first);
93 /* Set the "separate" option for the schedule node. */
95 static isl_schedule_node *
96 set_separate_option (__isl_take isl_schedule_node *node, void *user)
98 if (user)
99 return node;
101 if (isl_schedule_node_get_type (node) != isl_schedule_node_band)
102 return node;
104 /* Set the "separate" option unless it is set earlier to another option. */
105 if (isl_schedule_node_band_member_get_ast_loop_type (node, 0)
106 == isl_ast_loop_default)
107 return isl_schedule_node_band_member_set_ast_loop_type
108 (node, 0, isl_ast_loop_separate);
110 return node;
113 /* Print SCHEDULE under an AST form on file F. */
115 void
116 print_schedule_ast (FILE *f, __isl_keep isl_schedule *schedule, scop_p scop)
118 isl_set *set = isl_set_params (isl_set_copy (scop->param_context));
119 isl_ast_build *context = isl_ast_build_from_context (set);
120 isl_ast_node *ast
121 = isl_ast_build_node_from_schedule (context, isl_schedule_copy (schedule));
122 isl_ast_build_free (context);
123 print_isl_ast (f, ast);
124 isl_ast_node_free (ast);
127 DEBUG_FUNCTION void
128 debug_schedule_ast (__isl_keep isl_schedule *s, scop_p scop)
130 print_schedule_ast (stderr, s, scop);
133 enum phi_node_kind
135 unknown_phi,
136 loop_phi,
137 close_phi,
138 cond_phi
141 class translate_isl_ast_to_gimple
143 public:
144 translate_isl_ast_to_gimple (sese_info_p r)
145 : region (r), codegen_error (false) { }
146 edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
147 edge next_e, ivs_params &ip);
148 edge translate_isl_ast_node_for (loop_p context_loop,
149 __isl_keep isl_ast_node *node,
150 edge next_e, ivs_params &ip);
151 edge translate_isl_ast_for_loop (loop_p context_loop,
152 __isl_keep isl_ast_node *node_for,
153 edge next_e,
154 tree type, tree lb, tree ub,
155 ivs_params &ip);
156 edge translate_isl_ast_node_if (loop_p context_loop,
157 __isl_keep isl_ast_node *node,
158 edge next_e, ivs_params &ip);
159 edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
160 edge next_e, ivs_params &ip);
161 edge translate_isl_ast_node_block (loop_p context_loop,
162 __isl_keep isl_ast_node *node,
163 edge next_e, ivs_params &ip);
164 tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
165 ivs_params &ip);
166 tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
167 ivs_params &ip);
168 tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
169 ivs_params &ip);
170 tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
171 ivs_params &ip);
172 tree gcc_expression_from_isl_expression (tree type,
173 __isl_take isl_ast_expr *,
174 ivs_params &ip);
175 tree gcc_expression_from_isl_ast_expr_id (tree type,
176 __isl_keep isl_ast_expr *expr_id,
177 ivs_params &ip);
178 tree gcc_expression_from_isl_expr_int (tree type,
179 __isl_take isl_ast_expr *expr);
180 tree gcc_expression_from_isl_expr_op (tree type,
181 __isl_take isl_ast_expr *expr,
182 ivs_params &ip);
183 struct loop *graphite_create_new_loop (edge entry_edge,
184 __isl_keep isl_ast_node *node_for,
185 loop_p outer, tree type,
186 tree lb, tree ub, ivs_params &ip);
187 edge graphite_create_new_guard (edge entry_edge,
188 __isl_take isl_ast_expr *if_cond,
189 ivs_params &ip);
190 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
191 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
192 sese_l &region);
193 void translate_pending_phi_nodes (void);
194 void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
195 __isl_give isl_ast_build *generate_isl_context (scop_p scop);
197 __isl_give isl_ast_node * scop_to_isl_ast (scop_p scop);
199 bool is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
200 phi_node_kind, tree old_name, basic_block old_bb) const;
201 tree get_rename (basic_block new_bb, tree old_name,
202 basic_block old_bb, phi_node_kind) const;
203 tree get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
204 basic_block new_bb, basic_block old_bb,
205 vec<tree> iv_map);
206 basic_block get_def_bb_for_const (basic_block bb, basic_block old_bb) const;
207 tree get_new_name (basic_block new_bb, tree op,
208 basic_block old_bb, phi_node_kind) const;
209 void collect_all_ssa_names (tree new_expr, vec<tree> *vec_ssa);
210 bool copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
211 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
212 bool postpone);
213 bool copy_loop_phi_nodes (basic_block bb, basic_block new_bb);
214 bool add_close_phis_to_merge_points (gphi *old_phi, gphi *new_phi,
215 tree default_value);
216 tree add_close_phis_to_outer_loops (tree last_merge_name, edge merge_e,
217 gimple *old_close_phi);
218 bool copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
219 vec<tree> iv_map, bool postpone);
220 bool copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb,
221 vec<tree> iv_map);
222 bool copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map,
223 bool postpone);
224 bool copy_cond_phi_nodes (basic_block bb, basic_block new_bb,
225 vec<tree> iv_map);
226 bool graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
227 vec<tree> iv_map);
228 edge copy_bb_and_scalar_dependences (basic_block bb, edge next_e,
229 vec<tree> iv_map);
230 edge edge_for_new_close_phis (basic_block bb);
231 bool add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
232 edge old_bb_dominating_edge,
233 edge old_bb_non_dominating_edge,
234 gphi *phi, gphi *new_phi,
235 basic_block new_bb);
236 bool rename_uses (gimple *copy, gimple_stmt_iterator *gsi_tgt,
237 basic_block old_bb, loop_p loop, vec<tree> iv_map);
238 void set_rename (tree old_name, tree expr);
239 void set_rename_for_each_def (gimple *stmt);
240 void gsi_insert_earliest (gimple_seq seq);
241 tree rename_all_uses (tree new_expr, basic_block new_bb, basic_block old_bb);
242 bool codegen_error_p () const { return codegen_error; }
243 void set_codegen_error () { codegen_error = true; }
244 bool is_constant (tree op) const
246 return TREE_CODE (op) == INTEGER_CST
247 || TREE_CODE (op) == REAL_CST
248 || TREE_CODE (op) == COMPLEX_CST
249 || TREE_CODE (op) == VECTOR_CST;
252 private:
253 /* The region to be translated. */
254 sese_info_p region;
256 /* This flag is set when an error occurred during the translation of isl AST
257 to Gimple. */
258 bool codegen_error;
260 /* A vector of all the edges at if_condition merge points. */
261 auto_vec<edge, 2> merge_points;
264 /* Return the tree variable that corresponds to the given isl ast identifier
265 expression (an isl_ast_expr of type isl_ast_expr_id).
267 FIXME: We should replace blind conversion of id's type with derivation
268 of the optimal type when we get the corresponding isl support. Blindly
269 converting type sizes may be problematic when we switch to smaller
270 types. */
272 tree translate_isl_ast_to_gimple::
273 gcc_expression_from_isl_ast_expr_id (tree type,
274 __isl_take isl_ast_expr *expr_id,
275 ivs_params &ip)
277 gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
278 isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
279 std::map<isl_id *, tree>::iterator res;
280 res = ip.find (tmp_isl_id);
281 isl_id_free (tmp_isl_id);
282 gcc_assert (res != ip.end () &&
283 "Could not map isl_id to tree expression");
284 isl_ast_expr_free (expr_id);
285 tree t = res->second;
286 tree *val = region->parameter_rename_map->get(t);
288 if (!val)
289 val = &t;
290 return fold_convert (type, *val);
293 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
294 type TYPE. */
296 tree translate_isl_ast_to_gimple::
297 gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
299 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
300 isl_val *val = isl_ast_expr_get_val (expr);
301 size_t n = isl_val_n_abs_num_chunks (val, sizeof (HOST_WIDE_INT));
302 HOST_WIDE_INT *chunks = XALLOCAVEC (HOST_WIDE_INT, n);
303 tree res;
304 if (isl_val_get_abs_num_chunks (val, sizeof (HOST_WIDE_INT), chunks) == -1)
305 res = NULL_TREE;
306 else
308 widest_int wi = widest_int::from_array (chunks, n, true);
309 if (isl_val_is_neg (val))
310 wi = -wi;
311 res = wide_int_to_tree (type, wi);
313 isl_val_free (val);
314 isl_ast_expr_free (expr);
315 return res;
318 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
319 type TYPE. */
321 tree translate_isl_ast_to_gimple::
322 binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
324 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
325 tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
326 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
327 tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
329 enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
330 isl_ast_expr_free (expr);
332 if (codegen_error_p ())
333 return NULL_TREE;
335 switch (expr_type)
337 case isl_ast_op_add:
338 return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
340 case isl_ast_op_sub:
341 return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
343 case isl_ast_op_mul:
344 return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
346 case isl_ast_op_div:
347 /* As isl operates on arbitrary precision numbers, we may end up with
348 division by 2^64 that is folded to 0. */
349 if (integer_zerop (tree_rhs_expr))
351 set_codegen_error ();
352 return NULL_TREE;
354 return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
356 case isl_ast_op_pdiv_q:
357 /* As isl operates on arbitrary precision numbers, we may end up with
358 division by 2^64 that is folded to 0. */
359 if (integer_zerop (tree_rhs_expr))
361 set_codegen_error ();
362 return NULL_TREE;
364 return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
366 case isl_ast_op_zdiv_r:
367 case isl_ast_op_pdiv_r:
368 /* As isl operates on arbitrary precision numbers, we may end up with
369 division by 2^64 that is folded to 0. */
370 if (integer_zerop (tree_rhs_expr))
372 set_codegen_error ();
373 return NULL_TREE;
375 return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
377 case isl_ast_op_fdiv_q:
378 /* As isl operates on arbitrary precision numbers, we may end up with
379 division by 2^64 that is folded to 0. */
380 if (integer_zerop (tree_rhs_expr))
382 set_codegen_error ();
383 return NULL_TREE;
385 return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
387 case isl_ast_op_and:
388 return fold_build2 (TRUTH_ANDIF_EXPR, type,
389 tree_lhs_expr, tree_rhs_expr);
391 case isl_ast_op_or:
392 return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);
394 case isl_ast_op_eq:
395 return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);
397 case isl_ast_op_le:
398 return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
400 case isl_ast_op_lt:
401 return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
403 case isl_ast_op_ge:
404 return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
406 case isl_ast_op_gt:
407 return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
409 default:
410 gcc_unreachable ();
414 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
415 type TYPE. */
417 tree translate_isl_ast_to_gimple::
418 ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
420 enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr);
421 gcc_assert (t == isl_ast_op_cond || t == isl_ast_op_select);
422 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
423 tree a = gcc_expression_from_isl_expression (type, arg_expr, ip);
424 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
425 tree b = gcc_expression_from_isl_expression (type, arg_expr, ip);
426 arg_expr = isl_ast_expr_get_op_arg (expr, 2);
427 tree c = gcc_expression_from_isl_expression (type, arg_expr, ip);
428 isl_ast_expr_free (expr);
430 if (codegen_error_p ())
431 return NULL_TREE;
433 return fold_build3 (COND_EXPR, type, a, b, c);
436 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
437 type TYPE. */
439 tree translate_isl_ast_to_gimple::
440 unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
442 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
443 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
444 tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
445 isl_ast_expr_free (expr);
446 return codegen_error_p () ? NULL_TREE
447 : fold_build1 (NEGATE_EXPR, type, tree_expr);
450 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
451 to a GCC expression tree of type TYPE. */
453 tree translate_isl_ast_to_gimple::
454 nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
456 enum tree_code op_code;
457 switch (isl_ast_expr_get_op_type (expr))
459 case isl_ast_op_max:
460 op_code = MAX_EXPR;
461 break;
463 case isl_ast_op_min:
464 op_code = MIN_EXPR;
465 break;
467 default:
468 gcc_unreachable ();
470 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
471 tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);
473 if (codegen_error_p ())
475 isl_ast_expr_free (expr);
476 return NULL_TREE;
479 int i;
480 for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
482 arg_expr = isl_ast_expr_get_op_arg (expr, i);
483 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
485 if (codegen_error_p ())
487 isl_ast_expr_free (expr);
488 return NULL_TREE;
491 res = fold_build2 (op_code, type, res, t);
493 isl_ast_expr_free (expr);
494 return res;
497 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
498 type TYPE. */
500 tree translate_isl_ast_to_gimple::
501 gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
502 ivs_params &ip)
504 if (codegen_error_p ())
506 isl_ast_expr_free (expr);
507 return NULL_TREE;
510 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
511 switch (isl_ast_expr_get_op_type (expr))
513 /* These isl ast expressions are not supported yet. */
514 case isl_ast_op_error:
515 case isl_ast_op_call:
516 case isl_ast_op_and_then:
517 case isl_ast_op_or_else:
518 gcc_unreachable ();
520 case isl_ast_op_max:
521 case isl_ast_op_min:
522 return nary_op_to_tree (type, expr, ip);
524 case isl_ast_op_add:
525 case isl_ast_op_sub:
526 case isl_ast_op_mul:
527 case isl_ast_op_div:
528 case isl_ast_op_pdiv_q:
529 case isl_ast_op_pdiv_r:
530 case isl_ast_op_fdiv_q:
531 case isl_ast_op_zdiv_r:
532 case isl_ast_op_and:
533 case isl_ast_op_or:
534 case isl_ast_op_eq:
535 case isl_ast_op_le:
536 case isl_ast_op_lt:
537 case isl_ast_op_ge:
538 case isl_ast_op_gt:
539 return binary_op_to_tree (type, expr, ip);
541 case isl_ast_op_minus:
542 return unary_op_to_tree (type, expr, ip);
544 case isl_ast_op_cond:
545 case isl_ast_op_select:
546 return ternary_op_to_tree (type, expr, ip);
548 default:
549 gcc_unreachable ();
552 return NULL_TREE;
555 /* Converts an isl AST expression E back to a GCC expression tree of
556 type TYPE. */
558 tree translate_isl_ast_to_gimple::
559 gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
560 ivs_params &ip)
562 if (codegen_error_p ())
564 isl_ast_expr_free (expr);
565 return NULL_TREE;
568 switch (isl_ast_expr_get_type (expr))
570 case isl_ast_expr_id:
571 return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
573 case isl_ast_expr_int:
574 return gcc_expression_from_isl_expr_int (type, expr);
576 case isl_ast_expr_op:
577 return gcc_expression_from_isl_expr_op (type, expr, ip);
579 default:
580 gcc_unreachable ();
583 return NULL_TREE;
586 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
587 induction variable for the new LOOP. New LOOP is attached to CFG
588 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
589 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
590 isl's scattering name to the induction variable created for the
591 loop of STMT. The new induction variable is inserted in the NEWIVS
592 vector and is of type TYPE. */
594 struct loop *translate_isl_ast_to_gimple::
595 graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
596 loop_p outer, tree type, tree lb, tree ub,
597 ivs_params &ip)
599 isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
600 tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
602 /* To fail code generation, we generate wrong code until we discard it. */
603 if (codegen_error_p ())
604 stride = integer_zero_node;
606 tree ivvar = create_tmp_var (type, "graphite_IV");
607 tree iv, iv_after_increment;
608 loop_p loop = create_empty_loop_on_edge
609 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
610 outer ? outer : entry_edge->src->loop_father);
612 isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
613 isl_id *id = isl_ast_expr_get_id (for_iterator);
614 std::map<isl_id *, tree>::iterator res;
615 res = ip.find (id);
616 if (ip.count (id))
617 isl_id_free (res->first);
618 ip[id] = iv;
619 isl_ast_expr_free (for_iterator);
620 return loop;
623 /* Create the loop for a isl_ast_node_for.
625 - NEXT_E is the edge where new generated code should be attached. */
627 edge translate_isl_ast_to_gimple::
628 translate_isl_ast_for_loop (loop_p context_loop,
629 __isl_keep isl_ast_node *node_for, edge next_e,
630 tree type, tree lb, tree ub,
631 ivs_params &ip)
633 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
634 struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
635 type, lb, ub, ip);
636 edge last_e = single_exit (loop);
637 edge to_body = single_succ_edge (loop->header);
638 basic_block after = to_body->dest;
640 /* Translate the body of the loop. */
641 isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
642 next_e = translate_isl_ast (loop, for_body, to_body, ip);
643 isl_ast_node_free (for_body);
645 /* Early return if we failed to translate loop body. */
646 if (!next_e || codegen_error_p ())
647 return NULL;
649 if (next_e->dest != after)
650 redirect_edge_succ_nodup (next_e, after);
651 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
653 if (flag_loop_parallelize_all)
655 isl_id *id = isl_ast_node_get_annotation (node_for);
656 gcc_assert (id);
657 ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
658 loop->can_be_parallel = for_info->is_parallelizable;
659 free (for_info);
660 isl_id_free (id);
663 return last_e;
666 /* We use this function to get the upper bound because of the form,
667 which is used by isl to represent loops:
669 for (iterator = init; cond; iterator += inc)
677 The loop condition is an arbitrary expression, which contains the
678 current loop iterator.
680 (e.g. iterator + 3 < B && C > iterator + A)
682 We have to know the upper bound of the iterator to generate a loop
683 in Gimple form. It can be obtained from the special representation
684 of the loop condition, which is generated by isl,
685 if the ast_build_atomic_upper_bound option is set. In this case,
686 isl generates a loop condition that consists of the current loop
687 iterator, + an operator (< or <=) and an expression not involving
688 the iterator, which is processed and returned by this function.
690 (e.g iterator <= upper-bound-expression-without-iterator) */
692 static __isl_give isl_ast_expr *
693 get_upper_bound (__isl_keep isl_ast_node *node_for)
695 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
696 isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
697 gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
698 isl_ast_expr *res;
699 switch (isl_ast_expr_get_op_type (for_cond))
701 case isl_ast_op_le:
702 res = isl_ast_expr_get_op_arg (for_cond, 1);
703 break;
705 case isl_ast_op_lt:
707 /* (iterator < ub) => (iterator <= ub - 1). */
708 isl_val *one =
709 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
710 isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
711 res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
712 break;
715 default:
716 gcc_unreachable ();
718 isl_ast_expr_free (for_cond);
719 return res;
722 /* Translates an isl_ast_node_for to Gimple. */
724 edge translate_isl_ast_to_gimple::
725 translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
726 edge next_e, ivs_params &ip)
728 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
729 tree type
730 = build_nonstandard_integer_type (graphite_expression_type_precision, 0);
732 isl_ast_expr *for_init = isl_ast_node_for_get_init (node);
733 tree lb = gcc_expression_from_isl_expression (type, for_init, ip);
734 /* To fail code generation, we generate wrong code until we discard it. */
735 if (codegen_error_p ())
736 lb = integer_zero_node;
738 isl_ast_expr *upper_bound = get_upper_bound (node);
739 tree ub = gcc_expression_from_isl_expression (type, upper_bound, ip);
740 /* To fail code generation, we generate wrong code until we discard it. */
741 if (codegen_error_p ())
742 ub = integer_zero_node;
744 edge last_e = single_succ_edge (split_edge (next_e));
745 translate_isl_ast_for_loop (context_loop, node, next_e,
746 type, lb, ub, ip);
747 return last_e;
750 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
751 variables of the loops around GBB in SESE.
753 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
754 chrec, we could consider using a map<int, tree> that maps loop ids to the
755 corresponding tree expressions. */
757 void translate_isl_ast_to_gimple::
758 build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
759 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
760 sese_l &region)
762 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
763 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
764 int i;
765 isl_ast_expr *arg_expr;
766 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
768 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
769 tree type =
770 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
771 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
773 /* To fail code generation, we generate wrong code until we discard it. */
774 if (codegen_error_p ())
775 t = integer_zero_node;
777 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 2);
778 /* Record sth only for real loops. */
779 if (loop_in_sese_p (old_loop, region))
780 iv_map[old_loop->num] = t;
784 /* Translates an isl_ast_node_user to Gimple.
786 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
788 edge translate_isl_ast_to_gimple::
789 translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
790 edge next_e, ivs_params &ip)
792 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
794 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
795 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
796 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
798 isl_id *name_id = isl_ast_expr_get_id (name_expr);
799 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
800 gcc_assert (pbb);
802 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
804 isl_ast_expr_free (name_expr);
805 isl_id_free (name_id);
807 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
808 "The entry block should not even appear within a scop");
810 const int nb_loops = number_of_loops (cfun);
811 vec<tree> iv_map;
812 iv_map.create (nb_loops);
813 iv_map.safe_grow_cleared (nb_loops);
815 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
816 isl_ast_expr_free (user_expr);
818 basic_block old_bb = GBB_BB (gbb);
819 if (dump_file)
821 fprintf (dump_file,
822 "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
823 old_bb->index, next_e->src->index, next_e->dest->index);
824 print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
828 next_e = copy_bb_and_scalar_dependences (old_bb, next_e, iv_map);
830 iv_map.release ();
832 if (codegen_error_p ())
833 return NULL;
835 if (dump_file)
837 fprintf (dump_file, "[codegen] (after copy) new basic block\n");
838 print_loops_bb (dump_file, next_e->src, 0, 3);
841 return next_e;
844 /* Translates an isl_ast_node_block to Gimple. */
846 edge translate_isl_ast_to_gimple::
847 translate_isl_ast_node_block (loop_p context_loop,
848 __isl_keep isl_ast_node *node,
849 edge next_e, ivs_params &ip)
851 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
852 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
853 int i;
854 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
856 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
857 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
858 isl_ast_node_free (tmp_node);
860 isl_ast_node_list_free (node_list);
861 return next_e;
864 /* Creates a new if region corresponding to isl's cond. */
866 edge translate_isl_ast_to_gimple::
867 graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
868 ivs_params &ip)
870 tree type =
871 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
872 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
874 /* To fail code generation, we generate wrong code until we discard it. */
875 if (codegen_error_p ())
876 cond_expr = integer_zero_node;
878 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
879 return exit_edge;
882 /* Translates an isl_ast_node_if to Gimple. */
884 edge translate_isl_ast_to_gimple::
885 translate_isl_ast_node_if (loop_p context_loop,
886 __isl_keep isl_ast_node *node,
887 edge next_e, ivs_params &ip)
889 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
890 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
891 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
892 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
893 merge_points.safe_push (last_e);
895 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
896 translate_isl_ast (context_loop, then_node, true_e, ip);
897 isl_ast_node_free (then_node);
899 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
900 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
901 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
902 translate_isl_ast (context_loop, else_node, false_e, ip);
904 isl_ast_node_free (else_node);
905 return last_e;
908 /* Translates an isl AST node NODE to GCC representation in the
909 context of a SESE. */
911 edge translate_isl_ast_to_gimple::
912 translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
913 edge next_e, ivs_params &ip)
915 if (codegen_error_p ())
916 return NULL;
918 switch (isl_ast_node_get_type (node))
920 case isl_ast_node_error:
921 gcc_unreachable ();
923 case isl_ast_node_for:
924 return translate_isl_ast_node_for (context_loop, node,
925 next_e, ip);
927 case isl_ast_node_if:
928 return translate_isl_ast_node_if (context_loop, node,
929 next_e, ip);
931 case isl_ast_node_user:
932 return translate_isl_ast_node_user (node, next_e, ip);
934 case isl_ast_node_block:
935 return translate_isl_ast_node_block (context_loop, node,
936 next_e, ip);
938 case isl_ast_node_mark:
940 isl_ast_node *n = isl_ast_node_mark_get_node (node);
941 edge e = translate_isl_ast (context_loop, n, next_e, ip);
942 isl_ast_node_free (n);
943 return e;
946 default:
947 gcc_unreachable ();
951 /* Return true when BB contains loop close phi nodes. A loop close phi node is
952 at the exit of loop which takes one argument that is the last value of the
953 variable being used out of the loop. */
955 static bool
956 bb_contains_loop_close_phi_nodes (basic_block bb)
958 return single_pred_p (bb)
959 && bb->loop_father != single_pred_edge (bb)->src->loop_father;
962 /* Return true when BB contains loop phi nodes. A loop phi node is the loop
963 header containing phi nodes which has one init-edge and one back-edge. */
965 static bool
966 bb_contains_loop_phi_nodes (basic_block bb)
968 if (EDGE_COUNT (bb->preds) != 2)
969 return false;
971 unsigned depth = loop_depth (bb->loop_father);
973 edge preds[2] = { (*bb->preds)[0], (*bb->preds)[1] };
975 if (depth > loop_depth (preds[0]->src->loop_father)
976 || depth > loop_depth (preds[1]->src->loop_father))
977 return true;
979 /* When one of the edges correspond to the same loop father and other
980 doesn't. */
981 if (bb->loop_father != preds[0]->src->loop_father
982 && bb->loop_father == preds[1]->src->loop_father)
983 return true;
985 if (bb->loop_father != preds[1]->src->loop_father
986 && bb->loop_father == preds[0]->src->loop_father)
987 return true;
989 return false;
992 /* Check if USE is defined in a basic block from where the definition of USE can
993 propagate from all the paths. FIXME: Verify checks for virtual operands. */
995 static bool
996 is_loop_closed_ssa_use (basic_block bb, tree use)
998 if (TREE_CODE (use) != SSA_NAME || virtual_operand_p (use))
999 return true;
1001 /* For close-phi nodes def always comes from a loop which has a back-edge. */
1002 if (bb_contains_loop_close_phi_nodes (bb))
1003 return true;
1005 gimple *def = SSA_NAME_DEF_STMT (use);
1006 basic_block def_bb = gimple_bb (def);
1007 return (!def_bb
1008 || flow_bb_inside_loop_p (def_bb->loop_father, bb));
1011 /* Return the number of phi nodes in BB. */
1013 static int
1014 number_of_phi_nodes (basic_block bb)
1016 int num_phis = 0;
1017 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1018 gsi_next (&psi))
1019 num_phis++;
1020 return num_phis;
1023 /* Returns true if BB uses name in one of its PHIs. */
1025 static bool
1026 phi_uses_name (basic_block bb, tree name)
1028 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1029 gsi_next (&psi))
1031 gphi *phi = psi.phi ();
1032 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
1034 tree use_arg = gimple_phi_arg_def (phi, i);
1035 if (use_arg == name)
1036 return true;
1039 return false;
1042 /* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
1043 definition should flow into use, and the use should respect the loop-closed
1044 SSA form. */
1046 bool translate_isl_ast_to_gimple::
1047 is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
1048 phi_node_kind phi_kind, tree old_name, basic_block old_bb) const
1050 if (SSA_NAME_IS_DEFAULT_DEF (rename))
1051 return true;
1053 /* The def of the rename must either dominate the uses or come from a
1054 back-edge. Also the def must respect the loop closed ssa form. */
1055 if (!is_loop_closed_ssa_use (use_bb, rename))
1057 if (dump_file)
1059 fprintf (dump_file, "[codegen] rename not in loop closed ssa: ");
1060 print_generic_expr (dump_file, rename);
1061 fprintf (dump_file, "\n");
1063 return false;
1066 if (dominated_by_p (CDI_DOMINATORS, use_bb, def_bb))
1067 return true;
1069 if (bb_contains_loop_phi_nodes (use_bb) && phi_kind == loop_phi)
1071 /* The loop-header dominates the loop-body. */
1072 if (!dominated_by_p (CDI_DOMINATORS, def_bb, use_bb))
1073 return false;
1075 /* RENAME would be used in loop-phi. */
1076 gcc_assert (number_of_phi_nodes (use_bb));
1078 /* For definitions coming from back edges, we should check that
1079 old_name is used in a loop PHI node.
1080 FIXME: Verify if this is true. */
1081 if (phi_uses_name (old_bb, old_name))
1082 return true;
1084 return false;
1087 /* Returns the expression associated to OLD_NAME (which is used in OLD_BB), in
1088 NEW_BB from RENAME_MAP. PHI_KIND determines the kind of phi node. */
1090 tree translate_isl_ast_to_gimple::
1091 get_rename (basic_block new_bb, tree old_name, basic_block old_bb,
1092 phi_node_kind phi_kind) const
1094 gcc_assert (TREE_CODE (old_name) == SSA_NAME);
1095 vec <tree> *renames = region->rename_map->get (old_name);
1097 if (!renames || renames->is_empty ())
1098 return NULL_TREE;
1100 if (1 == renames->length ())
1102 tree rename = (*renames)[0];
1103 if (TREE_CODE (rename) == SSA_NAME)
1105 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (rename));
1106 if (is_valid_rename (rename, bb, new_bb, phi_kind, old_name, old_bb)
1107 && (phi_kind == close_phi
1108 || ! bb
1109 || flow_bb_inside_loop_p (bb->loop_father, new_bb)))
1110 return rename;
1111 return NULL_TREE;
1114 if (is_constant (rename))
1115 return rename;
1117 return NULL_TREE;
1120 /* More than one renames corresponding to the old_name. Find the rename for
1121 which the definition flows into usage at new_bb. */
1122 int i;
1123 tree t1 = NULL_TREE, t2;
1124 basic_block t1_bb = NULL;
1125 FOR_EACH_VEC_ELT (*renames, i, t2)
1127 basic_block t2_bb = gimple_bb (SSA_NAME_DEF_STMT (t2));
1129 /* Defined in the same basic block as used. */
1130 if (t2_bb == new_bb)
1131 return t2;
1133 /* NEW_BB and T2_BB are in two unrelated if-clauses. */
1134 if (!dominated_by_p (CDI_DOMINATORS, new_bb, t2_bb))
1135 continue;
1137 if (!flow_bb_inside_loop_p (t2_bb->loop_father, new_bb))
1138 continue;
1140 /* Compute the nearest dominator. */
1141 if (!t1 || dominated_by_p (CDI_DOMINATORS, t2_bb, t1_bb))
1143 t1_bb = t2_bb;
1144 t1 = t2;
1148 return t1;
1151 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
1152 When OLD_NAME and EXPR are the same we assert. */
1154 void translate_isl_ast_to_gimple::
1155 set_rename (tree old_name, tree expr)
1157 if (dump_file)
1159 fprintf (dump_file, "[codegen] setting rename: old_name = ");
1160 print_generic_expr (dump_file, old_name);
1161 fprintf (dump_file, ", new_name = ");
1162 print_generic_expr (dump_file, expr);
1163 fprintf (dump_file, "\n");
1166 if (old_name == expr)
1167 return;
1169 vec <tree> *renames = region->rename_map->get (old_name);
1171 if (renames)
1172 renames->safe_push (expr);
1173 else
1175 vec<tree> r;
1176 r.create (2);
1177 r.safe_push (expr);
1178 region->rename_map->put (old_name, r);
1181 tree t;
1182 int i;
1183 /* For a parameter of a scop we don't want to rename it. */
1184 FOR_EACH_VEC_ELT (region->params, i, t)
1185 if (old_name == t)
1186 region->parameter_rename_map->put(old_name, expr);
1189 /* Return an iterator to the instructions comes last in the execution order.
1190 Either GSI1 and GSI2 should belong to the same basic block or one of their
1191 respective basic blocks should dominate the other. */
1193 gimple_stmt_iterator
1194 later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
1196 basic_block bb1 = gsi_bb (gsi1);
1197 basic_block bb2 = gsi_bb (gsi2);
1199 /* Find the iterator which is the latest. */
1200 if (bb1 == bb2)
1202 gimple *stmt1 = gsi_stmt (gsi1);
1203 gimple *stmt2 = gsi_stmt (gsi2);
1205 if (stmt1 != NULL && stmt2 != NULL)
1207 bool is_phi1 = gimple_code (stmt1) == GIMPLE_PHI;
1208 bool is_phi2 = gimple_code (stmt2) == GIMPLE_PHI;
1210 if (is_phi1 != is_phi2)
1211 return is_phi1 ? gsi2 : gsi1;
1214 /* For empty basic blocks gsis point to the end of the sequence. Since
1215 there is no operator== defined for gimple_stmt_iterator and for gsis
1216 not pointing to a valid statement gsi_next would assert. */
1217 gimple_stmt_iterator gsi = gsi1;
1218 do {
1219 if (gsi_stmt (gsi) == gsi_stmt (gsi2))
1220 return gsi2;
1221 gsi_next (&gsi);
1222 } while (!gsi_end_p (gsi));
1224 return gsi1;
1227 /* Find the basic block closest to the basic block which defines stmt. */
1228 if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
1229 return gsi1;
1231 gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
1232 return gsi2;
1235 /* Insert each statement from SEQ at its earliest insertion p. */
1237 void translate_isl_ast_to_gimple::
1238 gsi_insert_earliest (gimple_seq seq)
1240 update_modified_stmts (seq);
1241 sese_l &codegen_region = region->if_region->true_region->region;
1242 basic_block begin_bb = get_entry_bb (codegen_region);
1244 /* Inserting the gimple statements in a vector because gimple_seq behave
1245 in strage ways when inserting the stmts from it into different basic
1246 blocks one at a time. */
1247 auto_vec<gimple *, 3> stmts;
1248 for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
1249 gsi_next (&gsi))
1250 stmts.safe_push (gsi_stmt (gsi));
1252 int i;
1253 gimple *use_stmt;
1254 FOR_EACH_VEC_ELT (stmts, i, use_stmt)
1256 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1257 gimple_stmt_iterator gsi_def_stmt = gsi_start_bb_nondebug (begin_bb);
1259 use_operand_p use_p;
1260 ssa_op_iter op_iter;
1261 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
1263 /* Iterator to the current def of use_p. For function parameters or
1264 anything where def is not found, insert at the beginning of the
1265 generated region. */
1266 gimple_stmt_iterator gsi_stmt = gsi_def_stmt;
1268 tree op = USE_FROM_PTR (use_p);
1269 gimple *stmt = SSA_NAME_DEF_STMT (op);
1270 if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
1271 gsi_stmt = gsi_for_stmt (stmt);
1273 /* For region parameters, insert at the beginning of the generated
1274 region. */
1275 if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
1276 gsi_stmt = gsi_def_stmt;
1278 gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
1281 if (!gsi_stmt (gsi_def_stmt))
1283 gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
1284 gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
1286 else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
1288 gimple_stmt_iterator bsi
1289 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt));
1290 /* Insert right after the PHI statements. */
1291 gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
1293 else
1294 gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);
1296 if (dump_file)
1298 fprintf (dump_file, "[codegen] inserting statement: ");
1299 print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
1300 print_loops_bb (dump_file, gimple_bb (use_stmt), 0, 3);
1305 /* Collect all the operands of NEW_EXPR by recursively visiting each
1306 operand. */
1308 void translate_isl_ast_to_gimple::
1309 collect_all_ssa_names (tree new_expr, vec<tree> *vec_ssa)
1311 if (new_expr == NULL_TREE)
1312 return;
1314 /* Rename all uses in new_expr. */
1315 if (TREE_CODE (new_expr) == SSA_NAME)
1317 vec_ssa->safe_push (new_expr);
1318 return;
1321 /* Iterate over SSA_NAMES in NEW_EXPR. */
1322 for (int i = 0; i < (TREE_CODE_LENGTH (TREE_CODE (new_expr))); i++)
1324 tree op = TREE_OPERAND (new_expr, i);
1325 collect_all_ssa_names (op, vec_ssa);
1329 /* This is abridged version of the function copied from:
1330 tree.c:substitute_in_expr (tree exp, tree f, tree r). */
1332 static tree
1333 substitute_ssa_name (tree exp, tree f, tree r)
1335 enum tree_code code = TREE_CODE (exp);
1336 tree op0, op1, op2, op3;
1337 tree new_tree;
1339 /* We handle TREE_LIST and COMPONENT_REF separately. */
1340 if (code == TREE_LIST)
1342 op0 = substitute_ssa_name (TREE_CHAIN (exp), f, r);
1343 op1 = substitute_ssa_name (TREE_VALUE (exp), f, r);
1344 if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
1345 return exp;
1347 return tree_cons (TREE_PURPOSE (exp), op1, op0);
1349 else if (code == COMPONENT_REF)
1351 tree inner;
1353 /* If this expression is getting a value from a PLACEHOLDER_EXPR
1354 and it is the right field, replace it with R. */
1355 for (inner = TREE_OPERAND (exp, 0);
1356 REFERENCE_CLASS_P (inner);
1357 inner = TREE_OPERAND (inner, 0))
1360 /* The field. */
1361 op1 = TREE_OPERAND (exp, 1);
1363 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
1364 return r;
1366 /* If this expression hasn't been completed let, leave it alone. */
1367 if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
1368 return exp;
1370 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1371 if (op0 == TREE_OPERAND (exp, 0))
1372 return exp;
1374 new_tree
1375 = fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
1377 else
1378 switch (TREE_CODE_CLASS (code))
1380 case tcc_constant:
1381 return exp;
1383 case tcc_declaration:
1384 if (exp == f)
1385 return r;
1386 else
1387 return exp;
1389 case tcc_expression:
1390 if (exp == f)
1391 return r;
1393 /* Fall through. */
1395 case tcc_exceptional:
1396 case tcc_unary:
1397 case tcc_binary:
1398 case tcc_comparison:
1399 case tcc_reference:
1400 switch (TREE_CODE_LENGTH (code))
1402 case 0:
1403 if (exp == f)
1404 return r;
1405 return exp;
1407 case 1:
1408 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1409 if (op0 == TREE_OPERAND (exp, 0))
1410 return exp;
1412 new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
1413 break;
1415 case 2:
1416 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1417 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1419 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
1420 return exp;
1422 new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
1423 break;
1425 case 3:
1426 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1427 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1428 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1430 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1431 && op2 == TREE_OPERAND (exp, 2))
1432 return exp;
1434 new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
1435 break;
1437 case 4:
1438 op0 = substitute_ssa_name (TREE_OPERAND (exp, 0), f, r);
1439 op1 = substitute_ssa_name (TREE_OPERAND (exp, 1), f, r);
1440 op2 = substitute_ssa_name (TREE_OPERAND (exp, 2), f, r);
1441 op3 = substitute_ssa_name (TREE_OPERAND (exp, 3), f, r);
1443 if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
1444 && op2 == TREE_OPERAND (exp, 2)
1445 && op3 == TREE_OPERAND (exp, 3))
1446 return exp;
1448 new_tree
1449 = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
1450 break;
1452 default:
1453 gcc_unreachable ();
1455 break;
1457 case tcc_vl_exp:
1458 default:
1459 gcc_unreachable ();
1462 TREE_READONLY (new_tree) |= TREE_READONLY (exp);
1464 if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
1465 TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
1467 return new_tree;
1470 /* Rename all the operands of NEW_EXPR by recursively visiting each operand. */
1472 tree translate_isl_ast_to_gimple::
1473 rename_all_uses (tree new_expr, basic_block new_bb, basic_block old_bb)
1475 auto_vec<tree, 2> ssa_names;
1476 collect_all_ssa_names (new_expr, &ssa_names);
1477 tree t;
1478 int i;
1479 FOR_EACH_VEC_ELT (ssa_names, i, t)
1480 if (tree r = get_rename (new_bb, t, old_bb, unknown_phi))
1481 new_expr = substitute_ssa_name (new_expr, t, r);
1483 return new_expr;
1486 /* For ops which are scev_analyzeable, we can regenerate a new name from its
1487 scalar evolution around LOOP. */
1489 tree translate_isl_ast_to_gimple::
1490 get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
1491 basic_block new_bb, basic_block old_bb,
1492 vec<tree> iv_map)
1494 tree scev = scalar_evolution_in_region (region->region, loop, old_name);
1496 /* At this point we should know the exact scev for each
1497 scalar SSA_NAME used in the scop: all the other scalar
1498 SSA_NAMEs should have been translated out of SSA using
1499 arrays with one element. */
1500 tree new_expr;
1501 if (chrec_contains_undetermined (scev))
1503 set_codegen_error ();
1504 return build_zero_cst (TREE_TYPE (old_name));
1507 new_expr = chrec_apply_map (scev, iv_map);
1509 /* The apply should produce an expression tree containing
1510 the uses of the new induction variables. We should be
1511 able to use new_expr instead of the old_name in the newly
1512 generated loop nest. */
1513 if (chrec_contains_undetermined (new_expr)
1514 || tree_contains_chrecs (new_expr, NULL))
1516 set_codegen_error ();
1517 return build_zero_cst (TREE_TYPE (old_name));
1520 if (TREE_CODE (new_expr) == SSA_NAME)
1522 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_expr));
1523 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1525 set_codegen_error ();
1526 return build_zero_cst (TREE_TYPE (old_name));
1530 new_expr = rename_all_uses (new_expr, new_bb, old_bb);
1532 /* We check all the operands and all of them should dominate the use at
1533 new_expr. */
1534 auto_vec <tree, 2> new_ssa_names;
1535 collect_all_ssa_names (new_expr, &new_ssa_names);
1536 int i;
1537 tree new_ssa_name;
1538 FOR_EACH_VEC_ELT (new_ssa_names, i, new_ssa_name)
1540 if (TREE_CODE (new_ssa_name) == SSA_NAME)
1542 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_ssa_name));
1543 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1545 set_codegen_error ();
1546 return build_zero_cst (TREE_TYPE (old_name));
1551 /* Replace the old_name with the new_expr. */
1552 return force_gimple_operand (unshare_expr (new_expr), stmts,
1553 true, NULL_TREE);
1556 /* Renames the scalar uses of the statement COPY, using the
1557 substitution map RENAME_MAP, inserting the gimplification code at
1558 GSI_TGT, for the translation REGION, with the original copied
1559 statement in LOOP, and using the induction variable renaming map
1560 IV_MAP. Returns true when something has been renamed. */
1562 bool translate_isl_ast_to_gimple::
1563 rename_uses (gimple *copy, gimple_stmt_iterator *gsi_tgt, basic_block old_bb,
1564 loop_p loop, vec<tree> iv_map)
1566 bool changed = false;
1568 if (is_gimple_debug (copy))
1570 if (gimple_debug_bind_p (copy))
1571 gimple_debug_bind_reset_value (copy);
1572 else if (gimple_debug_source_bind_p (copy))
1573 return false;
1574 else
1575 gcc_unreachable ();
1577 return false;
1580 if (dump_file)
1582 fprintf (dump_file, "[codegen] renaming uses of stmt: ");
1583 print_gimple_stmt (dump_file, copy, 0);
1586 use_operand_p use_p;
1587 ssa_op_iter op_iter;
1588 FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_USE)
1590 tree old_name = USE_FROM_PTR (use_p);
1592 if (dump_file)
1594 fprintf (dump_file, "[codegen] renaming old_name = ");
1595 print_generic_expr (dump_file, old_name);
1596 fprintf (dump_file, "\n");
1599 if (TREE_CODE (old_name) != SSA_NAME
1600 || SSA_NAME_IS_DEFAULT_DEF (old_name))
1601 continue;
1603 changed = true;
1604 tree new_expr = get_rename (gsi_tgt->bb, old_name,
1605 old_bb, unknown_phi);
1607 if (new_expr)
1609 tree type_old_name = TREE_TYPE (old_name);
1610 tree type_new_expr = TREE_TYPE (new_expr);
1612 if (dump_file)
1614 fprintf (dump_file, "[codegen] from rename_map: new_name = ");
1615 print_generic_expr (dump_file, new_expr);
1616 fprintf (dump_file, "\n");
1619 if (type_old_name != type_new_expr
1620 || TREE_CODE (new_expr) != SSA_NAME)
1622 tree var = create_tmp_var (type_old_name, "var");
1624 if (!useless_type_conversion_p (type_old_name, type_new_expr))
1625 new_expr = fold_convert (type_old_name, new_expr);
1627 gimple_seq stmts;
1628 new_expr = force_gimple_operand (new_expr, &stmts, true, var);
1629 gsi_insert_earliest (stmts);
1632 replace_exp (use_p, new_expr);
1633 continue;
1636 gimple_seq stmts;
1637 new_expr = get_rename_from_scev (old_name, &stmts, loop, gimple_bb (copy),
1638 old_bb, iv_map);
1639 if (!new_expr || codegen_error_p ())
1640 return false;
1642 if (dump_file)
1644 fprintf (dump_file, "[codegen] not in rename map, scev: ");
1645 print_generic_expr (dump_file, new_expr);
1646 fprintf (dump_file, "\n");
1649 gsi_insert_earliest (stmts);
1650 replace_exp (use_p, new_expr);
1652 if (TREE_CODE (new_expr) == INTEGER_CST
1653 && is_gimple_assign (copy))
1655 tree rhs = gimple_assign_rhs1 (copy);
1657 if (TREE_CODE (rhs) == ADDR_EXPR)
1658 recompute_tree_invariant_for_addr_expr (rhs);
1661 set_rename (old_name, new_expr);
1664 return changed;
1667 /* Returns a basic block that could correspond to where a constant was defined
1668 in the original code. In the original code OLD_BB had the definition, we
1669 need to find which basic block out of the copies of old_bb, in the new
1670 region, should a definition correspond to if it has to reach BB. */
1672 basic_block translate_isl_ast_to_gimple::
1673 get_def_bb_for_const (basic_block bb, basic_block old_bb) const
1675 vec <basic_block> *bbs = region->copied_bb_map->get (old_bb);
1677 if (!bbs || bbs->is_empty ())
1678 return NULL;
1680 if (1 == bbs->length ())
1681 return (*bbs)[0];
1683 int i;
1684 basic_block b1 = NULL, b2;
1685 FOR_EACH_VEC_ELT (*bbs, i, b2)
1687 if (b2 == bb)
1688 return bb;
1690 /* BB and B2 are in two unrelated if-clauses. */
1691 if (!dominated_by_p (CDI_DOMINATORS, bb, b2))
1692 continue;
1694 /* Compute the nearest dominator. */
1695 if (!b1 || dominated_by_p (CDI_DOMINATORS, b2, b1))
1696 b1 = b2;
1699 return b1;
1702 /* Get the new name of OP (from OLD_BB) to be used in NEW_BB. PHI_KIND
1703 determines the kind of phi node. */
1705 tree translate_isl_ast_to_gimple::
1706 get_new_name (basic_block new_bb, tree op,
1707 basic_block old_bb, phi_node_kind phi_kind) const
1709 /* For constants the names are the same. */
1710 if (TREE_CODE (op) != SSA_NAME)
1711 return op;
1713 return get_rename (new_bb, op, old_bb, phi_kind);
1716 /* Return a debug location for OP. */
1718 static location_t
1719 get_loc (tree op)
1721 location_t loc = UNKNOWN_LOCATION;
1723 if (TREE_CODE (op) == SSA_NAME)
1724 loc = gimple_location (SSA_NAME_DEF_STMT (op));
1725 return loc;
1728 /* Returns the incoming edges of basic_block BB in the pair. The first edge is
1729 the init edge (from outside the loop) and the second one is the back edge
1730 from the same loop. */
1732 std::pair<edge, edge>
1733 get_edges (basic_block bb)
1735 std::pair<edge, edge> edges;
1736 edge e;
1737 edge_iterator ei;
1738 FOR_EACH_EDGE (e, ei, bb->preds)
1739 if (bb->loop_father != e->src->loop_father)
1740 edges.first = e;
1741 else
1742 edges.second = e;
1743 return edges;
1746 /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI
1747 must be found unless they can be POSTPONEd for later. */
1749 bool translate_isl_ast_to_gimple::
1750 copy_loop_phi_args (gphi *old_phi, init_back_edge_pair_t &ibp_old_bb,
1751 gphi *new_phi, init_back_edge_pair_t &ibp_new_bb,
1752 bool postpone)
1754 gcc_assert (gimple_phi_num_args (old_phi) == gimple_phi_num_args (new_phi));
1756 basic_block new_bb = gimple_bb (new_phi);
1757 for (unsigned i = 0; i < gimple_phi_num_args (old_phi); i++)
1759 edge e;
1760 if (gimple_phi_arg_edge (old_phi, i) == ibp_old_bb.first)
1761 e = ibp_new_bb.first;
1762 else
1763 e = ibp_new_bb.second;
1765 tree old_name = gimple_phi_arg_def (old_phi, i);
1766 tree new_name = get_new_name (new_bb, old_name,
1767 gimple_bb (old_phi), loop_phi);
1768 if (new_name)
1770 add_phi_arg (new_phi, new_name, e, get_loc (old_name));
1771 continue;
1774 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
1775 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
1776 /* If the phi arg was a function arg, or wasn't defined, just use the
1777 old name. */
1778 add_phi_arg (new_phi, old_name, e, get_loc (old_name));
1779 else if (postpone)
1781 /* Postpone code gen for later for those back-edges we don't have the
1782 names yet. */
1783 region->incomplete_phis.safe_push (std::make_pair (old_phi, new_phi));
1784 if (dump_file)
1785 fprintf (dump_file, "[codegen] postpone loop phi nodes.\n");
1787 else
1788 /* Either we should add the arg to phi or, we should postpone. */
1789 return false;
1791 return true;
1794 /* Copy loop phi nodes from BB to NEW_BB. */
1796 bool translate_isl_ast_to_gimple::
1797 copy_loop_phi_nodes (basic_block bb, basic_block new_bb)
1799 if (dump_file)
1800 fprintf (dump_file, "[codegen] copying loop phi nodes in bb_%d.\n",
1801 new_bb->index);
1803 /* Loop phi nodes should have only two arguments. */
1804 gcc_assert (2 == EDGE_COUNT (bb->preds));
1806 /* First edge is the init edge and second is the back edge. */
1807 init_back_edge_pair_t ibp_old_bb = get_edges (bb);
1809 /* First edge is the init edge and second is the back edge. */
1810 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
1812 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1813 gsi_next (&psi))
1815 gphi *phi = psi.phi ();
1816 tree res = gimple_phi_result (phi);
1817 if (virtual_operand_p (res))
1818 continue;
1819 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
1820 continue;
1822 gphi *new_phi = create_phi_node (NULL_TREE, new_bb);
1823 tree new_res = create_new_def_for (res, new_phi,
1824 gimple_phi_result_ptr (new_phi));
1825 set_rename (res, new_res);
1826 if (!copy_loop_phi_args (phi, ibp_old_bb, new_phi, ibp_new_bb, true))
1827 set_codegen_error ();
1828 update_stmt (new_phi);
1830 if (dump_file)
1832 fprintf (dump_file, "[codegen] creating loop-phi node: ");
1833 print_gimple_stmt (dump_file, new_phi, 0);
1837 return true;
1840 /* Return the init value of PHI, the value coming from outside the loop. */
1842 static tree
1843 get_loop_init_value (gphi *phi)
1846 loop_p loop = gimple_bb (phi)->loop_father;
1848 edge e;
1849 edge_iterator ei;
1850 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
1851 if (e->src->loop_father != loop)
1852 return gimple_phi_arg_def (phi, e->dest_idx);
1854 return NULL_TREE;
1857 /* Find the init value (the value which comes from outside the loop), of one of
1858 the operands of DEF which is defined by a loop phi. */
1860 static tree
1861 find_init_value (gimple *def)
1863 if (gimple_code (def) == GIMPLE_PHI)
1864 return get_loop_init_value (as_a <gphi*> (def));
1866 if (gimple_vuse (def))
1867 return NULL_TREE;
1869 ssa_op_iter iter;
1870 use_operand_p use_p;
1871 FOR_EACH_SSA_USE_OPERAND (use_p, def, iter, SSA_OP_USE)
1873 tree use = USE_FROM_PTR (use_p);
1874 if (TREE_CODE (use) == SSA_NAME)
1876 if (tree res = find_init_value (SSA_NAME_DEF_STMT (use)))
1877 return res;
1881 return NULL_TREE;
1884 /* Return the init value, the value coming from outside the loop. */
1886 static tree
1887 find_init_value_close_phi (gphi *phi)
1889 gcc_assert (gimple_phi_num_args (phi) == 1);
1890 tree use_arg = gimple_phi_arg_def (phi, 0);
1891 gimple *def = SSA_NAME_DEF_STMT (use_arg);
1892 return find_init_value (def);
1896 tree translate_isl_ast_to_gimple::
1897 add_close_phis_to_outer_loops (tree last_merge_name, edge last_e,
1898 gimple *old_close_phi)
1900 sese_l &codegen_region = region->if_region->true_region->region;
1901 gimple *stmt = SSA_NAME_DEF_STMT (last_merge_name);
1902 basic_block bb = gimple_bb (stmt);
1903 if (!bb_in_sese_p (bb, codegen_region))
1904 return last_merge_name;
1906 loop_p loop = bb->loop_father;
1907 if (!loop_in_sese_p (loop, codegen_region))
1908 return last_merge_name;
1910 edge e = single_exit (loop);
1912 if (dominated_by_p (CDI_DOMINATORS, e->dest, last_e->src))
1913 return last_merge_name;
1915 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
1916 tree old_close_phi_name = gimple_phi_result (old_close_phi);
1918 bb = e->dest;
1919 if (!bb_contains_loop_close_phi_nodes (bb) || !single_succ_p (bb))
1920 bb = split_edge (e);
1922 gphi *close_phi = create_phi_node (NULL_TREE, bb);
1923 tree res = create_new_def_for (last_merge_name, close_phi,
1924 gimple_phi_result_ptr (close_phi));
1925 set_rename (old_close_phi_name, res);
1926 add_phi_arg (close_phi, last_merge_name, e, get_loc (old_name));
1927 last_merge_name = res;
1929 return add_close_phis_to_outer_loops (last_merge_name, last_e, old_close_phi);
1932 /* Add phi nodes to all merge points of all the diamonds enclosing the loop of
1933 the close phi node PHI. */
1935 bool translate_isl_ast_to_gimple::
1936 add_close_phis_to_merge_points (gphi *old_close_phi, gphi *new_close_phi,
1937 tree default_value)
1939 sese_l &codegen_region = region->if_region->true_region->region;
1940 basic_block default_value_bb = get_entry_bb (codegen_region);
1941 if (SSA_NAME == TREE_CODE (default_value))
1943 gimple *stmt = SSA_NAME_DEF_STMT (default_value);
1944 if (!stmt || gimple_code (stmt) == GIMPLE_NOP)
1945 return false;
1946 default_value_bb = gimple_bb (stmt);
1949 basic_block new_close_phi_bb = gimple_bb (new_close_phi);
1951 tree old_close_phi_name = gimple_phi_result (old_close_phi);
1952 tree new_close_phi_name = gimple_phi_result (new_close_phi);
1953 tree last_merge_name = new_close_phi_name;
1954 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
1956 int i;
1957 edge merge_e;
1958 FOR_EACH_VEC_ELT_REVERSE (merge_points, i, merge_e)
1960 basic_block new_merge_bb = merge_e->src;
1961 if (!dominated_by_p (CDI_DOMINATORS, new_merge_bb, default_value_bb))
1962 continue;
1964 last_merge_name = add_close_phis_to_outer_loops (last_merge_name, merge_e,
1965 old_close_phi);
1967 gphi *merge_phi = create_phi_node (NULL_TREE, new_merge_bb);
1968 tree merge_res = create_new_def_for (old_close_phi_name, merge_phi,
1969 gimple_phi_result_ptr (merge_phi));
1970 set_rename (old_close_phi_name, merge_res);
1972 edge from_loop = NULL, from_default_value = NULL;
1973 edge e;
1974 edge_iterator ei;
1975 FOR_EACH_EDGE (e, ei, new_merge_bb->preds)
1976 if (dominated_by_p (CDI_DOMINATORS, e->src, new_close_phi_bb))
1977 from_loop = e;
1978 else
1979 from_default_value = e;
1981 /* Because CDI_POST_DOMINATORS are not updated, we only rely on
1982 CDI_DOMINATORS, which may not handle all cases where new_close_phi_bb
1983 is contained in another condition. */
1984 if (!from_default_value || !from_loop)
1985 return false;
1987 add_phi_arg (merge_phi, last_merge_name, from_loop, get_loc (old_name));
1988 add_phi_arg (merge_phi, default_value, from_default_value, get_loc (old_name));
1990 if (dump_file)
1992 fprintf (dump_file, "[codegen] Adding guard-phi: ");
1993 print_gimple_stmt (dump_file, merge_phi, 0);
1996 update_stmt (merge_phi);
1997 last_merge_name = merge_res;
2000 return true;
2003 /* Copy all the loop-close phi args from BB to NEW_BB. */
2005 bool translate_isl_ast_to_gimple::
2006 copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
2007 vec<tree> iv_map, bool postpone)
2009 for (gphi_iterator psi = gsi_start_phis (old_bb); !gsi_end_p (psi);
2010 gsi_next (&psi))
2012 gphi *old_close_phi = psi.phi ();
2013 tree res = gimple_phi_result (old_close_phi);
2014 if (virtual_operand_p (res))
2015 continue;
2017 gphi *new_close_phi = create_phi_node (NULL_TREE, new_bb);
2018 tree new_res = create_new_def_for (res, new_close_phi,
2019 gimple_phi_result_ptr (new_close_phi));
2020 set_rename (res, new_res);
2022 tree old_name = gimple_phi_arg_def (old_close_phi, 0);
2023 tree new_name;
2024 if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
2026 gimple_seq stmts;
2027 new_name = get_rename_from_scev (old_name, &stmts,
2028 old_bb->loop_father,
2029 new_bb, old_bb, iv_map);
2030 if (! codegen_error_p ())
2031 gsi_insert_earliest (stmts);
2033 else
2034 new_name = get_new_name (new_bb, old_name, old_bb, close_phi);
2036 /* Predecessor basic blocks of a loop close phi should have been code
2037 generated before. FIXME: This is fixable by merging PHIs from inner
2038 loops as well. See: gfortran.dg/graphite/interchange-3.f90. */
2039 if (!new_name || codegen_error_p ())
2040 return false;
2042 add_phi_arg (new_close_phi, new_name, single_pred_edge (new_bb),
2043 get_loc (old_name));
2044 if (dump_file)
2046 fprintf (dump_file, "[codegen] Adding loop close phi: ");
2047 print_gimple_stmt (dump_file, new_close_phi, 0);
2050 update_stmt (new_close_phi);
2052 /* When there is no loop guard around this codegenerated loop, there is no
2053 need to collect the close-phi arg. */
2054 if (merge_points.is_empty ())
2055 continue;
2057 /* Add a PHI in the succ_new_bb for each close phi of the loop. */
2058 tree default_value = find_init_value_close_phi (new_close_phi);
2060 /* A close phi must come from a loop-phi having a default value. */
2061 if (!default_value)
2063 if (!postpone)
2064 return false;
2066 region->incomplete_phis.safe_push (std::make_pair (old_close_phi,
2067 new_close_phi));
2068 if (dump_file)
2070 fprintf (dump_file, "[codegen] postpone close phi nodes: ");
2071 print_gimple_stmt (dump_file, new_close_phi, 0);
2073 continue;
2076 if (!add_close_phis_to_merge_points (old_close_phi, new_close_phi,
2077 default_value))
2078 return false;
2081 return true;
2084 /* Copy loop close phi nodes from BB to NEW_BB. */
2086 bool translate_isl_ast_to_gimple::
2087 copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb,
2088 vec<tree> iv_map)
2090 if (dump_file)
2091 fprintf (dump_file, "[codegen] copying loop close phi nodes in bb_%d.\n",
2092 new_bb->index);
2093 /* Loop close phi nodes should have only one argument. */
2094 gcc_assert (1 == EDGE_COUNT (old_bb->preds));
2096 return copy_loop_close_phi_args (old_bb, new_bb, iv_map, true);
2100 /* Add NEW_NAME as the ARGNUM-th arg of NEW_PHI which is in NEW_BB.
2101 DOMINATING_PRED is the predecessor basic block of OLD_BB which dominates the
2102 other pred of OLD_BB as well. If no such basic block exists then it is NULL.
2103 NON_DOMINATING_PRED is a pred which does not dominate OLD_BB, it cannot be
2104 NULL.
2106 Case1: OLD_BB->preds {BB1, BB2} and BB1 does not dominate BB2 and vice versa.
2107 In this case DOMINATING_PRED = NULL.
2109 Case2: OLD_BB->preds {BB1, BB2} and BB1 dominates BB2.
2111 Returns true on successful copy of the args, false otherwise. */
2113 bool translate_isl_ast_to_gimple::
2114 add_phi_arg_for_new_expr (tree old_phi_args[2], tree new_phi_args[2],
2115 edge old_bb_dominating_edge,
2116 edge old_bb_non_dominating_edge,
2117 gphi *phi, gphi *new_phi,
2118 basic_block new_bb)
2120 basic_block def_pred[2] = { NULL, NULL };
2121 int not_found_bb_index = -1;
2122 for (int i = 0; i < 2; i++)
2124 /* If the corresponding def_bb could not be found the entry will be
2125 NULL. */
2126 if (TREE_CODE (old_phi_args[i]) == INTEGER_CST)
2127 def_pred[i] = get_def_bb_for_const (new_bb,
2128 gimple_phi_arg_edge (phi, i)->src);
2129 else if (new_phi_args[i] && (TREE_CODE (new_phi_args[i]) == SSA_NAME))
2130 def_pred[i] = gimple_bb (SSA_NAME_DEF_STMT (new_phi_args[i]));
2132 if (!def_pred[i])
2134 /* When non are available bail out. */
2135 if (not_found_bb_index != -1)
2136 return false;
2137 not_found_bb_index = i;
2141 /* Here we are pattern matching on the structure of CFG w.r.t. old one. */
2142 if (old_bb_dominating_edge)
2144 if (not_found_bb_index != -1)
2145 return false;
2147 basic_block new_pred1 = (*new_bb->preds)[0]->src;
2148 basic_block new_pred2 = (*new_bb->preds)[1]->src;
2149 vec <basic_block> *bbs
2150 = region->copied_bb_map->get (old_bb_non_dominating_edge->src);
2152 /* Could not find a mapping. */
2153 if (!bbs)
2154 return false;
2156 basic_block new_pred = NULL;
2157 basic_block b;
2158 int i;
2159 FOR_EACH_VEC_ELT (*bbs, i, b)
2161 if (dominated_by_p (CDI_DOMINATORS, new_pred1, b))
2163 /* FIXME: If we have already found new_pred then we have to
2164 disambiguate, bail out for now. */
2165 if (new_pred)
2166 return false;
2167 new_pred = new_pred1;
2169 if (dominated_by_p (CDI_DOMINATORS, new_pred2, b))
2171 /* FIXME: If we have already found new_pred then we have to either
2172 it dominates both or we have to disambiguate, bail out. */
2173 if (new_pred)
2174 return false;
2175 new_pred = new_pred2;
2179 if (!new_pred)
2180 return false;
2182 edge new_non_dominating_edge = find_edge (new_pred, new_bb);
2183 gcc_assert (new_non_dominating_edge);
2184 /* FIXME: Validate each args just like in loop-phis. */
2185 /* By the process of elimination we first insert insert phi-edge for
2186 non-dominating pred which is computed above and then we insert the
2187 remaining one. */
2188 int inserted_edge = 0;
2189 for (; inserted_edge < 2; inserted_edge++)
2191 edge new_bb_pred_edge = gimple_phi_arg_edge (new_phi, inserted_edge);
2192 if (new_non_dominating_edge == new_bb_pred_edge)
2194 add_phi_arg (new_phi, new_phi_args[inserted_edge],
2195 new_non_dominating_edge,
2196 get_loc (old_phi_args[inserted_edge]));
2197 break;
2200 if (inserted_edge == 2)
2201 return false;
2203 int edge_dominating = inserted_edge == 0 ? 1 : 0;
2205 edge new_dominating_edge = NULL;
2206 for (inserted_edge = 0; inserted_edge < 2; inserted_edge++)
2208 edge e = gimple_phi_arg_edge (new_phi, inserted_edge);
2209 if (e != new_non_dominating_edge)
2211 new_dominating_edge = e;
2212 add_phi_arg (new_phi, new_phi_args[edge_dominating],
2213 new_dominating_edge,
2214 get_loc (old_phi_args[inserted_edge]));
2215 break;
2218 gcc_assert (new_dominating_edge);
2220 else
2222 /* Classic diamond structure: both edges are non-dominating. We need to
2223 find one unique edge then the other can be found be elimination. If
2224 any definition (def_pred) dominates both the preds of new_bb then we
2225 bail out. Entries of def_pred maybe NULL, in that case we must
2226 uniquely find pred with help of only one entry. */
2227 edge new_e[2] = { NULL, NULL };
2228 for (int i = 0; i < 2; i++)
2230 edge e;
2231 edge_iterator ei;
2232 FOR_EACH_EDGE (e, ei, new_bb->preds)
2233 if (def_pred[i]
2234 && dominated_by_p (CDI_DOMINATORS, e->src, def_pred[i]))
2236 if (new_e[i])
2237 /* We do not know how to handle the case when def_pred
2238 dominates more than a predecessor. */
2239 return false;
2240 new_e[i] = e;
2244 gcc_assert (new_e[0] || new_e[1]);
2246 /* Find the other edge by process of elimination. */
2247 if (not_found_bb_index != -1)
2249 gcc_assert (!new_e[not_found_bb_index]);
2250 int found_bb_index = not_found_bb_index == 1 ? 0 : 1;
2251 edge e;
2252 edge_iterator ei;
2253 FOR_EACH_EDGE (e, ei, new_bb->preds)
2255 if (new_e[found_bb_index] == e)
2256 continue;
2257 new_e[not_found_bb_index] = e;
2261 /* Add edges to phi args. */
2262 for (int i = 0; i < 2; i++)
2263 add_phi_arg (new_phi, new_phi_args[i], new_e[i],
2264 get_loc (old_phi_args[i]));
2267 return true;
2270 /* Copy the arguments of cond-phi node PHI, to NEW_PHI in the codegenerated
2271 region. If postpone is true and it isn't possible to copy any arg of PHI,
2272 the PHI is added to the REGION->INCOMPLETE_PHIS to be codegenerated later.
2273 Returns false if the copying was unsuccessful. */
2275 bool translate_isl_ast_to_gimple::
2276 copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map, bool postpone)
2278 if (dump_file)
2279 fprintf (dump_file, "[codegen] copying cond phi args.\n");
2280 gcc_assert (2 == gimple_phi_num_args (phi));
2282 basic_block new_bb = gimple_bb (new_phi);
2283 loop_p loop = gimple_bb (phi)->loop_father;
2285 basic_block old_bb = gimple_bb (phi);
2286 edge old_bb_non_dominating_edge = NULL, old_bb_dominating_edge = NULL;
2288 edge e;
2289 edge_iterator ei;
2290 FOR_EACH_EDGE (e, ei, old_bb->preds)
2291 if (!dominated_by_p (CDI_DOMINATORS, old_bb, e->src))
2292 old_bb_non_dominating_edge = e;
2293 else
2294 old_bb_dominating_edge = e;
2296 gcc_assert (!dominated_by_p (CDI_DOMINATORS, old_bb,
2297 old_bb_non_dominating_edge->src));
2299 tree new_phi_args[2];
2300 tree old_phi_args[2];
2302 for (unsigned i = 0; i < gimple_phi_num_args (phi); i++)
2304 tree old_name = gimple_phi_arg_def (phi, i);
2305 tree new_name = get_new_name (new_bb, old_name, old_bb, cond_phi);
2306 old_phi_args[i] = old_name;
2307 if (new_name)
2309 new_phi_args [i] = new_name;
2310 continue;
2313 /* If the phi-arg was a parameter. */
2314 if (vec_find (region->params, old_name) != -1)
2316 new_phi_args [i] = old_name;
2317 if (dump_file)
2319 fprintf (dump_file,
2320 "[codegen] parameter argument to phi, new_expr: ");
2321 print_generic_expr (dump_file, new_phi_args[i]);
2322 fprintf (dump_file, "\n");
2324 continue;
2327 gimple *old_def_stmt = SSA_NAME_DEF_STMT (old_name);
2328 if (!old_def_stmt || gimple_code (old_def_stmt) == GIMPLE_NOP)
2329 /* FIXME: If the phi arg was a function arg, or wasn't defined, just use
2330 the old name. */
2331 return false;
2333 if (postpone)
2335 /* If the phi-arg is scev-analyzeable but only in the first stage. */
2336 if (is_gimple_reg (old_name)
2337 && scev_analyzable_p (old_name, region->region))
2339 gimple_seq stmts;
2340 tree new_expr = get_rename_from_scev (old_name, &stmts, loop,
2341 new_bb, old_bb, iv_map);
2342 if (codegen_error_p ())
2343 return false;
2345 gcc_assert (new_expr);
2346 if (dump_file)
2348 fprintf (dump_file,
2349 "[codegen] scev analyzeable, new_expr: ");
2350 print_generic_expr (dump_file, new_expr);
2351 fprintf (dump_file, "\n");
2353 gsi_insert_earliest (stmts);
2354 new_phi_args[i] = new_expr;
2355 continue;
2358 /* Postpone code gen for later for back-edges. */
2359 region->incomplete_phis.safe_push (std::make_pair (phi, new_phi));
2361 if (dump_file)
2363 fprintf (dump_file, "[codegen] postpone cond phi nodes: ");
2364 print_gimple_stmt (dump_file, new_phi, 0);
2367 new_phi_args [i] = NULL_TREE;
2368 continue;
2370 else
2371 /* Either we should add the arg to phi or, we should postpone. */
2372 return false;
2375 /* If none of the args have been determined in the first stage then wait until
2376 later. */
2377 if (postpone && !new_phi_args[0] && !new_phi_args[1])
2378 return true;
2380 return add_phi_arg_for_new_expr (old_phi_args, new_phi_args,
2381 old_bb_dominating_edge,
2382 old_bb_non_dominating_edge,
2383 phi, new_phi, new_bb);
2386 /* Copy cond phi nodes from BB to NEW_BB. A cond-phi node is a basic block
2387 containing phi nodes coming from two predecessors, and none of them are back
2388 edges. */
2390 bool translate_isl_ast_to_gimple::
2391 copy_cond_phi_nodes (basic_block bb, basic_block new_bb, vec<tree> iv_map)
2394 gcc_assert (!bb_contains_loop_close_phi_nodes (bb));
2396 /* TODO: Handle cond phi nodes with more than 2 predecessors. */
2397 if (EDGE_COUNT (bb->preds) != 2)
2398 return false;
2400 if (dump_file)
2401 fprintf (dump_file, "[codegen] copying cond phi nodes in bb_%d.\n",
2402 new_bb->index);
2404 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2405 gsi_next (&psi))
2407 gphi *phi = psi.phi ();
2408 tree res = gimple_phi_result (phi);
2409 if (virtual_operand_p (res))
2410 continue;
2412 gphi *new_phi = create_phi_node (NULL_TREE, new_bb);
2413 tree new_res = create_new_def_for (res, new_phi,
2414 gimple_phi_result_ptr (new_phi));
2415 set_rename (res, new_res);
2417 if (!copy_cond_phi_args (phi, new_phi, iv_map, true))
2418 return false;
2420 update_stmt (new_phi);
2423 return true;
2426 /* Return true if STMT should be copied from region to the new code-generated
2427 region. LABELs, CONDITIONS, induction-variables and region parameters need
2428 not be copied. */
2430 static bool
2431 should_copy_to_new_region (gimple *stmt, sese_info_p region)
2433 /* Do not copy labels or conditions. */
2434 if (gimple_code (stmt) == GIMPLE_LABEL
2435 || gimple_code (stmt) == GIMPLE_COND)
2436 return false;
2438 tree lhs;
2439 /* Do not copy induction variables. */
2440 if (is_gimple_assign (stmt)
2441 && (lhs = gimple_assign_lhs (stmt))
2442 && TREE_CODE (lhs) == SSA_NAME
2443 && is_gimple_reg (lhs)
2444 && scev_analyzable_p (lhs, region->region))
2445 return false;
2447 /* Do not copy parameters that have been generated in the header of the
2448 scop. */
2449 if (is_gimple_assign (stmt)
2450 && (lhs = gimple_assign_lhs (stmt))
2451 && TREE_CODE (lhs) == SSA_NAME
2452 && region->parameter_rename_map->get(lhs))
2453 return false;
2455 return true;
2458 /* Create new names for all the definitions created by COPY and add replacement
2459 mappings for each new name. */
2461 void translate_isl_ast_to_gimple::
2462 set_rename_for_each_def (gimple *stmt)
2464 def_operand_p def_p;
2465 ssa_op_iter op_iter;
2466 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
2468 tree old_name = DEF_FROM_PTR (def_p);
2469 tree new_name = create_new_def_for (old_name, stmt, def_p);
2470 set_rename (old_name, new_name);
2474 /* Duplicates the statements of basic block BB into basic block NEW_BB
2475 and compute the new induction variables according to the IV_MAP. */
2477 bool translate_isl_ast_to_gimple::
2478 graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
2479 vec<tree> iv_map)
2481 /* Iterator poining to the place where new statement (s) will be inserted. */
2482 gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
2484 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
2485 gsi_next (&gsi))
2487 gimple *stmt = gsi_stmt (gsi);
2488 if (!should_copy_to_new_region (stmt, region))
2489 continue;
2491 /* Create a new copy of STMT and duplicate STMT's virtual
2492 operands. */
2493 gimple *copy = gimple_copy (stmt);
2494 gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
2496 if (dump_file)
2498 fprintf (dump_file, "[codegen] inserting statement: ");
2499 print_gimple_stmt (dump_file, copy, 0);
2502 maybe_duplicate_eh_stmt (copy, stmt);
2503 gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
2505 /* Crete new names for each def in the copied stmt. */
2506 set_rename_for_each_def (copy);
2508 loop_p loop = bb->loop_father;
2509 if (rename_uses (copy, &gsi_tgt, bb, loop, iv_map))
2511 fold_stmt_inplace (&gsi_tgt);
2512 gcc_assert (gsi_stmt (gsi_tgt) == copy);
2515 if (codegen_error_p ())
2516 return false;
2518 /* For each SSA_NAME in the parameter_rename_map rename their usage. */
2519 ssa_op_iter iter;
2520 use_operand_p use_p;
2521 if (!is_gimple_debug (copy))
2522 FOR_EACH_SSA_USE_OPERAND (use_p, copy, iter, SSA_OP_USE)
2524 tree old_name = USE_FROM_PTR (use_p);
2526 if (TREE_CODE (old_name) != SSA_NAME
2527 || SSA_NAME_IS_DEFAULT_DEF (old_name))
2528 continue;
2530 tree *new_expr = region->parameter_rename_map->get (old_name);
2531 if (!new_expr)
2532 continue;
2534 replace_exp (use_p, *new_expr);
2537 update_stmt (copy);
2540 return true;
2544 /* Given a basic block containing close-phi it returns the new basic block where
2545 to insert a copy of the close-phi nodes. All the uses in close phis should
2546 come from a single loop otherwise it returns NULL. */
2548 edge translate_isl_ast_to_gimple::
2549 edge_for_new_close_phis (basic_block bb)
2551 /* Make sure that NEW_BB is the new_loop->exit->dest. We find the definition
2552 of close phi in the original code and then find the mapping of basic block
2553 defining that variable. If there are multiple close-phis and they are
2554 defined in different loops (in the original or in the new code) because of
2555 loop splitting, then we bail out. */
2556 loop_p new_loop = NULL;
2557 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
2558 gsi_next (&psi))
2560 gphi *phi = psi.phi ();
2561 tree name = gimple_phi_arg_def (phi, 0);
2562 basic_block old_loop_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
2564 vec <basic_block> *bbs = region->copied_bb_map->get (old_loop_bb);
2565 if (!bbs || bbs->length () != 1)
2566 /* This is one of the places which shows preserving original structure
2567 is not always possible, as we may need to insert close PHI for a loop
2568 where the latch does not have any mapping, or the mapping is
2569 ambiguous. */
2570 return NULL;
2572 if (!new_loop)
2573 new_loop = (*bbs)[0]->loop_father;
2574 else if (new_loop != (*bbs)[0]->loop_father)
2575 return NULL;
2578 if (!new_loop)
2579 return NULL;
2581 return single_exit (new_loop);
2584 /* Copies BB and includes in the copied BB all the statements that can
2585 be reached following the use-def chains from the memory accesses,
2586 and returns the next edge following this new block. */
2588 edge translate_isl_ast_to_gimple::
2589 copy_bb_and_scalar_dependences (basic_block bb, edge next_e, vec<tree> iv_map)
2591 int num_phis = number_of_phi_nodes (bb);
2592 basic_block new_bb = NULL;
2593 if (bb_contains_loop_close_phi_nodes (bb))
2595 if (dump_file)
2596 fprintf (dump_file, "[codegen] bb_%d contains close phi nodes.\n",
2597 bb->index);
2599 edge e = edge_for_new_close_phis (bb);
2600 if (!e)
2602 set_codegen_error ();
2603 return NULL;
2606 basic_block phi_bb = e->dest;
2608 if (!bb_contains_loop_close_phi_nodes (phi_bb) || !single_succ_p (phi_bb))
2609 phi_bb = split_edge (e);
2611 gcc_assert (single_pred_edge (phi_bb)->src->loop_father
2612 != single_pred_edge (phi_bb)->dest->loop_father);
2614 if (!copy_loop_close_phi_nodes (bb, phi_bb, iv_map))
2616 set_codegen_error ();
2617 return NULL;
2620 if (e == next_e)
2621 new_bb = phi_bb;
2622 else
2623 new_bb = split_edge (next_e);
2625 else
2627 new_bb = split_edge (next_e);
2628 if (num_phis > 0 && bb_contains_loop_phi_nodes (bb))
2630 basic_block phi_bb = next_e->dest->loop_father->header;
2632 /* At this point we are unable to codegenerate by still preserving the SSA
2633 structure because maybe the loop is completely unrolled and the PHIs
2634 and cross-bb scalar dependencies are untrackable w.r.t. the original
2635 code. See gfortran.dg/graphite/pr29832.f90. */
2636 if (EDGE_COUNT (bb->preds) != EDGE_COUNT (phi_bb->preds))
2638 set_codegen_error ();
2639 return NULL;
2642 /* In case isl did some loop peeling, like this:
2644 S_8(0);
2645 for (int c1 = 1; c1 <= 5; c1 += 1) {
2646 S_8(c1);
2648 S_8(6);
2650 there should be no loop-phi nodes in S_8(0).
2652 FIXME: We need to reason about dynamic instances of S_8, i.e., the
2653 values of all scalar variables: for the moment we instantiate only
2654 SCEV analyzable expressions on the iteration domain, and we need to
2655 extend that to reductions that cannot be analyzed by SCEV. */
2656 if (!bb_in_sese_p (phi_bb, region->if_region->true_region->region))
2658 set_codegen_error ();
2659 return NULL;
2662 if (dump_file)
2663 fprintf (dump_file, "[codegen] bb_%d contains loop phi nodes.\n",
2664 bb->index);
2665 if (!copy_loop_phi_nodes (bb, phi_bb))
2667 set_codegen_error ();
2668 return NULL;
2671 else if (num_phis > 0)
2673 if (dump_file)
2674 fprintf (dump_file, "[codegen] bb_%d contains cond phi nodes.\n",
2675 bb->index);
2677 basic_block phi_bb = single_pred (new_bb);
2678 loop_p loop_father = new_bb->loop_father;
2680 /* Move back until we find the block with two predecessors. */
2681 while (single_pred_p (phi_bb))
2682 phi_bb = single_pred_edge (phi_bb)->src;
2684 /* If a corresponding merge-point was not found, then abort codegen. */
2685 if (phi_bb->loop_father != loop_father
2686 || !bb_in_sese_p (phi_bb, region->if_region->true_region->region)
2687 || !copy_cond_phi_nodes (bb, phi_bb, iv_map))
2689 set_codegen_error ();
2690 return NULL;
2695 if (dump_file)
2696 fprintf (dump_file, "[codegen] copying from bb_%d to bb_%d.\n",
2697 bb->index, new_bb->index);
2699 vec <basic_block> *copied_bbs = region->copied_bb_map->get (bb);
2700 if (copied_bbs)
2701 copied_bbs->safe_push (new_bb);
2702 else
2704 vec<basic_block> bbs;
2705 bbs.create (2);
2706 bbs.safe_push (new_bb);
2707 region->copied_bb_map->put (bb, bbs);
2710 if (!graphite_copy_stmts_from_block (bb, new_bb, iv_map))
2712 set_codegen_error ();
2713 return NULL;
2716 return single_succ_edge (new_bb);
2719 /* Patch the missing arguments of the phi nodes. */
2721 void translate_isl_ast_to_gimple::
2722 translate_pending_phi_nodes ()
2724 int i;
2725 phi_rename *rename;
2726 FOR_EACH_VEC_ELT (region->incomplete_phis, i, rename)
2728 gphi *old_phi = rename->first;
2729 gphi *new_phi = rename->second;
2730 basic_block old_bb = gimple_bb (old_phi);
2731 basic_block new_bb = gimple_bb (new_phi);
2733 /* First edge is the init edge and second is the back edge. */
2734 init_back_edge_pair_t ibp_old_bb = get_edges (old_bb);
2735 init_back_edge_pair_t ibp_new_bb = get_edges (new_bb);
2737 if (dump_file)
2739 fprintf (dump_file, "[codegen] translating pending old-phi: ");
2740 print_gimple_stmt (dump_file, old_phi, 0);
2743 auto_vec <tree, 1> iv_map;
2744 if (bb_contains_loop_phi_nodes (new_bb)
2745 && bb_contains_loop_phi_nodes (old_bb))
2747 if (!copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
2748 ibp_new_bb, false))
2749 set_codegen_error ();
2751 else if (bb_contains_loop_close_phi_nodes (new_bb))
2753 if (!copy_loop_close_phi_args (old_bb, new_bb, iv_map, false))
2754 set_codegen_error ();
2756 else if (!copy_cond_phi_args (old_phi, new_phi, iv_map, false))
2757 set_codegen_error ();
2759 if (dump_file)
2761 fprintf (dump_file, "[codegen] to new-phi: ");
2762 print_gimple_stmt (dump_file, new_phi, 0);
2764 if (codegen_error_p ())
2765 return;
2769 /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
2771 void translate_isl_ast_to_gimple::
2772 add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
2774 sese_info_p region = scop->scop_info;
2775 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
2776 gcc_assert (nb_parameters == region->params.length ());
2777 unsigned i;
2778 for (i = 0; i < nb_parameters; i++)
2780 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
2781 isl_dim_param, i);
2782 ip[tmp_id] = region->params[i];
2787 /* Generates a build, which specifies the constraints on the parameters. */
2789 __isl_give isl_ast_build *translate_isl_ast_to_gimple::
2790 generate_isl_context (scop_p scop)
2792 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
2793 return isl_ast_build_from_context (context_isl);
2796 /* This method is executed before the construction of a for node. */
2797 __isl_give isl_id *
2798 ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
2800 isl_union_map *dependences = (isl_union_map *) user;
2801 ast_build_info *for_info = XNEW (struct ast_build_info);
2802 isl_union_map *schedule = isl_ast_build_get_schedule (build);
2803 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
2804 int dimension = isl_space_dim (schedule_space, isl_dim_out);
2805 for_info->is_parallelizable =
2806 !carries_deps (schedule, dependences, dimension);
2807 isl_union_map_free (schedule);
2808 isl_space_free (schedule_space);
2809 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
2810 return id;
2813 /* Generate isl AST from schedule of SCOP. */
2815 __isl_give isl_ast_node *translate_isl_ast_to_gimple::
2816 scop_to_isl_ast (scop_p scop)
2818 gcc_assert (scop->transformed_schedule);
2820 /* Set the separate option to reduce control flow overhead. */
2821 isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
2822 (isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
2823 isl_ast_build *context_isl = generate_isl_context (scop);
2825 if (flag_loop_parallelize_all)
2827 scop_get_dependences (scop);
2828 context_isl =
2829 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
2830 scop->dependence);
2833 isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
2834 (context_isl, schedule);
2835 isl_ast_build_free (context_isl);
2836 return ast_isl;
2839 /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
2840 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
2842 static void
2843 copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
2844 gimple_stmt_iterator *gsi)
2846 if (!defined_in_sese_p (tr, region->region))
2847 return;
2849 ssa_op_iter iter;
2850 use_operand_p use_p;
2851 FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
2853 tree use_tr = USE_FROM_PTR (use_p);
2855 /* Do not copy parameters that have been generated in the header of the
2856 scop. */
2857 if (region->parameter_rename_map->get(use_tr))
2858 continue;
2860 gimple *def_of_use = SSA_NAME_DEF_STMT (use_tr);
2861 if (!def_of_use)
2862 continue;
2864 copy_def (use_tr, def_of_use, region, to_region, gsi);
2867 gimple *copy = gimple_copy (def_stmt);
2868 gsi_insert_after (gsi, copy, GSI_NEW_STMT);
2870 /* Create new names for all the definitions created by COPY and
2871 add replacement mappings for each new name. */
2872 def_operand_p def_p;
2873 ssa_op_iter op_iter;
2874 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
2876 tree old_name = DEF_FROM_PTR (def_p);
2877 tree new_name = create_new_def_for (old_name, copy, def_p);
2878 region->parameter_rename_map->put(old_name, new_name);
2881 update_stmt (copy);
2884 static void
2885 copy_internal_parameters (sese_info_p region, sese_info_p to_region)
2887 /* For all the parameters which definitino is in the if_region->false_region,
2888 insert code on true_region (if_region->true_region->entry). */
2890 int i;
2891 tree tr;
2892 gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
2894 FOR_EACH_VEC_ELT (region->params, i, tr)
2896 // If def is not in region.
2897 gimple *def_stmt = SSA_NAME_DEF_STMT (tr);
2898 if (def_stmt)
2899 copy_def (tr, def_stmt, region, to_region, &gsi);
2903 /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
2904 Return true if code generation succeeded. */
2906 bool
2907 graphite_regenerate_ast_isl (scop_p scop)
2909 sese_info_p region = scop->scop_info;
2910 translate_isl_ast_to_gimple t (region);
2912 ifsese if_region = NULL;
2913 isl_ast_node *root_node;
2914 ivs_params ip;
2916 timevar_push (TV_GRAPHITE_CODE_GEN);
2917 t.add_parameters_to_ivs_params (scop, ip);
2918 root_node = t.scop_to_isl_ast (scop);
2920 if (dump_file && (dump_flags & TDF_DETAILS))
2922 fprintf (dump_file, "[scheduler] original schedule:\n");
2923 print_isl_schedule (dump_file, scop->original_schedule);
2924 fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
2925 print_isl_schedule (dump_file, scop->transformed_schedule);
2927 fprintf (dump_file, "[scheduler] original ast:\n");
2928 print_schedule_ast (dump_file, scop->original_schedule, scop);
2929 fprintf (dump_file, "[scheduler] AST generated by isl:\n");
2930 print_isl_ast (dump_file, root_node);
2933 if_region = move_sese_in_condition (region);
2934 region->if_region = if_region;
2936 loop_p context_loop = region->region.entry->src->loop_father;
2938 /* Copy all the parameters which are defined in the region. */
2939 copy_internal_parameters(if_region->false_region, if_region->true_region);
2941 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
2942 basic_block bb = split_edge (e);
2944 /* Update the true_region exit edge. */
2945 region->if_region->true_region->region.exit = single_succ_edge (bb);
2947 t.translate_isl_ast (context_loop, root_node, e, ip);
2948 if (! t.codegen_error_p ())
2949 t.translate_pending_phi_nodes ();
2950 if (! t.codegen_error_p ())
2952 sese_insert_phis_for_liveouts (region,
2953 if_region->region->region.exit->src,
2954 if_region->false_region->region.exit,
2955 if_region->true_region->region.exit);
2956 if (dump_file)
2957 fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
2959 mark_virtual_operands_for_renaming (cfun);
2960 update_ssa (TODO_update_ssa);
2963 if (t.codegen_error_p ())
2965 if (dump_file)
2966 fprintf (dump_file, "codegen error: "
2967 "reverting back to the original code.\n");
2968 set_ifsese_condition (if_region, integer_zero_node);
2970 /* We registered new names, scrap that. */
2971 if (need_ssa_update_p (cfun))
2972 delete_update_ssa ();
2973 /* Remove the unreachable region. */
2974 remove_edge_and_dominated_blocks (if_region->true_region->region.entry);
2975 basic_block ifb = if_region->false_region->region.entry->src;
2976 gimple_stmt_iterator gsi = gsi_last_bb (ifb);
2977 gsi_remove (&gsi, true);
2978 if_region->false_region->region.entry->flags &= ~EDGE_FALSE_VALUE;
2979 if_region->false_region->region.entry->flags |= EDGE_FALLTHRU;
2980 /* remove_edge_and_dominated_blocks marks loops for removal but
2981 doesn't actually remove them (fix that...). */
2982 loop_p loop;
2983 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
2984 if (! loop->header)
2985 delete_loop (loop);
2988 /* Verifies properties that GRAPHITE should maintain during translation. */
2989 checking_verify_loop_structure ();
2990 checking_verify_loop_closed_ssa (true);
2992 free (if_region->true_region);
2993 free (if_region->region);
2994 free (if_region);
2996 ivs_params_clear (ip);
2997 isl_ast_node_free (root_node);
2998 timevar_pop (TV_GRAPHITE_CODE_GEN);
3000 return !t.codegen_error_p ();
3003 #endif /* HAVE_isl */