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)
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/>. */
29 #include "coretypes.h"
35 #include "fold-const.h"
36 #include "gimple-fold.h"
37 #include "gimple-iterator.h"
39 #include "gimplify-me.h"
41 #include "tree-ssa-loop.h"
42 #include "tree-ssa-operands.h"
43 #include "tree-ssa-propagate.h"
44 #include "tree-pass.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"
54 #include "gimple-pretty-print.h"
56 #include "value-prof.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 (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
;
71 : is_parallelizable(false)
73 bool is_parallelizable
;
76 /* Converts a GMP constant VAL to a tree and returns it. */
79 gmp_cst_to_tree (tree type
, mpz_t val
)
81 tree t
= type
? type
: integer_type_node
;
86 wide_int wi
= wi::from_mpz (t
, tmp
, true);
89 return wide_int_to_tree (t
, wi
);
92 /* Verifies properties that GRAPHITE should maintain during translation. */
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
)
128 if (isl_schedule_node_get_type (node
) != isl_schedule_node_band
)
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
);
140 /* Print SCHEDULE under an AST form on file F. */
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
);
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
);
155 debug_schedule_ast (__isl_keep isl_schedule
*s
, scop_p scop
)
157 print_schedule_ast (stderr
, s
, scop
);
170 class translate_isl_ast_to_gimple
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
,
183 tree type
, tree lb
, tree ub
,
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
,
195 tree
binary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
197 tree
ternary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
199 tree
nary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
201 tree
gcc_expression_from_isl_expression (tree type
,
202 __isl_take isl_ast_expr
*,
204 tree
gcc_expression_from_isl_ast_expr_id (tree type
,
205 __isl_keep isl_ast_expr
*expr_id
,
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
,
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
,
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
,
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
,
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
);
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
);
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
,
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
,
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
,
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
,
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
,
266 bool copy_cond_phi_nodes (basic_block bb
, basic_block new_bb
,
268 bool graphite_copy_stmts_from_block (basic_block bb
, basic_block new_bb
,
270 edge
copy_bb_and_scalar_dependences (basic_block bb
, edge next_e
,
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
,
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
;
294 /* The region to be translated. */
297 /* This flag is set when an error occurred during the translation of isl AST
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
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
,
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
);
331 return fold_convert (type
, *val
);
334 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
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
);
343 mpz_init (val_mpz_t
);
345 if (isl_val_get_num_gmp (val
, val_mpz_t
) == -1)
348 res
= gmp_cst_to_tree (type
, val_mpz_t
);
350 isl_ast_expr_free (expr
);
351 mpz_clear (val_mpz_t
);
355 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
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 ())
375 return fold_build2 (PLUS_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
378 return fold_build2 (MINUS_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
381 return fold_build2 (MULT_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
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;
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;
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
:
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;
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;
425 return fold_build2 (FLOOR_DIV_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
428 return fold_build2 (TRUTH_ANDIF_EXPR
, type
,
429 tree_lhs_expr
, tree_rhs_expr
);
432 return fold_build2 (TRUTH_ORIF_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
435 return fold_build2 (EQ_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
438 return fold_build2 (LE_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
441 return fold_build2 (LT_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
444 return fold_build2 (GE_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
447 return fold_build2 (GT_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
454 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
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 ())
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
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
))
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
);
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
);
531 res
= fold_build2 (op_code
, type
, res
, t
);
533 isl_ast_expr_free (expr
);
537 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
540 tree
translate_isl_ast_to_gimple::
541 gcc_expression_from_isl_expr_op (tree type
, __isl_take isl_ast_expr
*expr
,
544 if (codegen_error_p ())
546 isl_ast_expr_free (expr
);
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
:
562 return nary_op_to_tree (type
, expr
, ip
);
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
:
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
);
598 /* Converts an isl AST expression E back to a GCC expression tree of
601 tree
translate_isl_ast_to_gimple::
602 gcc_expression_from_isl_expression (tree type
, __isl_take isl_ast_expr
*expr
,
605 if (codegen_error_p ())
607 isl_ast_expr_free (expr
);
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
);
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
,
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
;
660 isl_id_free (res
->first
);
662 isl_ast_expr_free (for_iterator
);
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
,
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
,
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 ())
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
);
700 ast_build_info
*for_info
= (ast_build_info
*) isl_id_get_user (id
);
701 loop
->can_be_parallel
= for_info
->is_parallelizable
;
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
);
742 switch (isl_ast_expr_get_op_type (for_cond
))
745 res
= isl_ast_expr_get_op_arg (for_cond
, 1);
750 /* (iterator < ub) => (iterator <= ub - 1). */
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
));
761 isl_ast_expr_free (for_cond
);
765 /* All loops generated by create_empty_loop_on_edge have the form of
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
);
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
);
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,
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
;
824 exit_edge
= create_empty_if_region_on_edge (entry_edge
,
825 unshare_expr (cond_expr
));
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
);
838 edge last_e
= graphite_create_new_loop_guard (next_e
, node
, &type
,
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
,
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
);
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
,
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
);
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
);
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
);
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
);
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
);
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
);
940 if (codegen_error_p ())
945 fprintf (dump_file
, "[codegen] (after copy) new basic block\n");
946 print_loops_bb (dump_file
, next_e
->src
, 0, 3);
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
);
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
);
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
,
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
);
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
);
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 ())
1026 switch (isl_ast_node_get_type (node
))
1028 case isl_ast_node_error
:
1031 case isl_ast_node_for
:
1032 return translate_isl_ast_node_for (context_loop
, node
,
1035 case isl_ast_node_if
:
1036 return translate_isl_ast_node_if (context_loop
, node
,
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
,
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
);
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. */
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. */
1076 bb_contains_loop_phi_nodes (basic_block bb
)
1078 if (EDGE_COUNT (bb
->preds
) != 2)
1081 unsigned depth
= loop_depth (bb
->loop_father
);
1083 edge preds
[2] = { (*bb
->preds
)[0], (*bb
->preds
)[1] };
1085 if (depth
> loop_depth (preds
[0]->src
->loop_father
)
1086 || depth
> loop_depth (preds
[1]->src
->loop_father
))
1089 /* When one of the edges correspond to the same loop father and other
1091 if (bb
->loop_father
!= preds
[0]->src
->loop_father
1092 && bb
->loop_father
== preds
[1]->src
->loop_father
)
1095 if (bb
->loop_father
!= preds
[1]->src
->loop_father
1096 && bb
->loop_father
== preds
[0]->src
->loop_father
)
1102 /* Check if USE is defined in a basic block from where the definition of USE can
1103 propagate from all the paths. FIXME: Verify checks for virtual operands. */
1106 is_loop_closed_ssa_use (basic_block bb
, tree use
)
1108 if (TREE_CODE (use
) != SSA_NAME
|| virtual_operand_p (use
))
1111 /* For close-phi nodes def always comes from a loop which has a back-edge. */
1112 if (bb_contains_loop_close_phi_nodes (bb
))
1115 gimple
*def
= SSA_NAME_DEF_STMT (use
);
1116 basic_block def_bb
= gimple_bb (def
);
1118 || flow_bb_inside_loop_p (def_bb
->loop_father
, bb
));
1121 /* Return the number of phi nodes in BB. */
1124 number_of_phi_nodes (basic_block bb
)
1127 for (gphi_iterator psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);
1133 /* Returns true if BB uses name in one of its PHIs. */
1136 phi_uses_name (basic_block bb
, tree name
)
1138 for (gphi_iterator psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);
1141 gphi
*phi
= psi
.phi ();
1142 for (unsigned i
= 0; i
< gimple_phi_num_args (phi
); i
++)
1144 tree use_arg
= gimple_phi_arg_def (phi
, i
);
1145 if (use_arg
== name
)
1152 /* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
1153 definition should flow into use, and the use should respect the loop-closed
1156 bool translate_isl_ast_to_gimple::
1157 is_valid_rename (tree rename
, basic_block def_bb
, basic_block use_bb
,
1158 phi_node_kind phi_kind
, tree old_name
, basic_block old_bb
) const
1160 /* The def of the rename must either dominate the uses or come from a
1161 back-edge. Also the def must respect the loop closed ssa form. */
1162 if (!is_loop_closed_ssa_use (use_bb
, rename
))
1166 fprintf (dump_file
, "[codegen] rename not in loop closed ssa: ");
1167 print_generic_expr (dump_file
, rename
, 0);
1168 fprintf (dump_file
, "\n");
1173 if (dominated_by_p (CDI_DOMINATORS
, use_bb
, def_bb
))
1176 if (bb_contains_loop_phi_nodes (use_bb
) && phi_kind
== loop_phi
)
1178 /* The loop-header dominates the loop-body. */
1179 if (!dominated_by_p (CDI_DOMINATORS
, def_bb
, use_bb
))
1182 /* RENAME would be used in loop-phi. */
1183 gcc_assert (number_of_phi_nodes (use_bb
));
1185 /* For definitions coming from back edges, we should check that
1186 old_name is used in a loop PHI node.
1187 FIXME: Verify if this is true. */
1188 if (phi_uses_name (old_bb
, old_name
))
1194 /* Returns the expression associated to OLD_NAME (which is used in OLD_BB), in
1195 NEW_BB from RENAME_MAP. PHI_KIND determines the kind of phi node. */
1197 tree
translate_isl_ast_to_gimple::
1198 get_rename (basic_block new_bb
, tree old_name
, basic_block old_bb
,
1199 phi_node_kind phi_kind
) const
1201 gcc_assert (TREE_CODE (old_name
) == SSA_NAME
);
1202 vec
<tree
> *renames
= region
->rename_map
->get (old_name
);
1204 if (!renames
|| renames
->is_empty ())
1207 if (1 == renames
->length ())
1209 tree rename
= (*renames
)[0];
1210 if (TREE_CODE (rename
) == SSA_NAME
)
1212 basic_block bb
= gimple_bb (SSA_NAME_DEF_STMT (rename
));
1213 if (is_valid_rename (rename
, bb
, new_bb
, phi_kind
, old_name
, old_bb
)
1214 && (phi_kind
== close_phi
1215 || flow_bb_inside_loop_p (bb
->loop_father
, new_bb
)))
1220 if (is_constant (rename
))
1226 /* More than one renames corresponding to the old_name. Find the rename for
1227 which the definition flows into usage at new_bb. */
1229 tree t1
= NULL_TREE
, t2
;
1230 basic_block t1_bb
= NULL
;
1231 FOR_EACH_VEC_ELT (*renames
, i
, t2
)
1233 basic_block t2_bb
= gimple_bb (SSA_NAME_DEF_STMT (t2
));
1235 /* Defined in the same basic block as used. */
1236 if (t2_bb
== new_bb
)
1239 /* NEW_BB and T2_BB are in two unrelated if-clauses. */
1240 if (!dominated_by_p (CDI_DOMINATORS
, new_bb
, t2_bb
))
1243 if (!flow_bb_inside_loop_p (t2_bb
->loop_father
, new_bb
))
1246 /* Compute the nearest dominator. */
1247 if (!t1
|| dominated_by_p (CDI_DOMINATORS
, t2_bb
, t1_bb
))
1257 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
1258 When OLD_NAME and EXPR are the same we assert. */
1260 void translate_isl_ast_to_gimple::
1261 set_rename (tree old_name
, tree expr
)
1265 fprintf (dump_file
, "[codegen] setting rename: old_name = ");
1266 print_generic_expr (dump_file
, old_name
, 0);
1267 fprintf (dump_file
, ", new_name = ");
1268 print_generic_expr (dump_file
, expr
, 0);
1269 fprintf (dump_file
, "\n");
1272 if (old_name
== expr
)
1275 vec
<tree
> *renames
= region
->rename_map
->get (old_name
);
1278 renames
->safe_push (expr
);
1284 region
->rename_map
->put (old_name
, r
);
1289 /* For a parameter of a scop we don't want to rename it. */
1290 FOR_EACH_VEC_ELT (region
->params
, i
, t
)
1292 region
->parameter_rename_map
->put(old_name
, expr
);
1295 /* Return an iterator to the instructions comes last in the execution order.
1296 Either GSI1 and GSI2 should belong to the same basic block or one of their
1297 respective basic blocks should dominate the other. */
1299 gimple_stmt_iterator
1300 later_of_the_two (gimple_stmt_iterator gsi1
, gimple_stmt_iterator gsi2
)
1302 basic_block bb1
= gsi_bb (gsi1
);
1303 basic_block bb2
= gsi_bb (gsi2
);
1305 /* Find the iterator which is the latest. */
1308 gimple
*stmt1
= gsi_stmt (gsi1
);
1309 gimple
*stmt2
= gsi_stmt (gsi2
);
1311 if (stmt1
!= NULL
&& stmt2
!= NULL
)
1313 bool is_phi1
= gimple_code (stmt1
) == GIMPLE_PHI
;
1314 bool is_phi2
= gimple_code (stmt2
) == GIMPLE_PHI
;
1316 if (is_phi1
!= is_phi2
)
1317 return is_phi1
? gsi2
: gsi1
;
1320 /* For empty basic blocks gsis point to the end of the sequence. Since
1321 there is no operator== defined for gimple_stmt_iterator and for gsis
1322 not pointing to a valid statement gsi_next would assert. */
1323 gimple_stmt_iterator gsi
= gsi1
;
1325 if (gsi_stmt (gsi
) == gsi_stmt (gsi2
))
1328 } while (!gsi_end_p (gsi
));
1333 /* Find the basic block closest to the basic block which defines stmt. */
1334 if (dominated_by_p (CDI_DOMINATORS
, bb1
, bb2
))
1337 gcc_assert (dominated_by_p (CDI_DOMINATORS
, bb2
, bb1
));
1341 /* Insert each statement from SEQ at its earliest insertion p. */
1343 void translate_isl_ast_to_gimple::
1344 gsi_insert_earliest (gimple_seq seq
)
1346 update_modified_stmts (seq
);
1347 sese_l
&codegen_region
= region
->if_region
->true_region
->region
;
1348 basic_block begin_bb
= get_entry_bb (codegen_region
);
1350 /* Inserting the gimple statements in a vector because gimple_seq behave
1351 in strage ways when inserting the stmts from it into different basic
1352 blocks one at a time. */
1353 auto_vec
<gimple
*, 3> stmts
;
1354 for (gimple_stmt_iterator gsi
= gsi_start (seq
); !gsi_end_p (gsi
);
1356 stmts
.safe_push (gsi_stmt (gsi
));
1360 FOR_EACH_VEC_ELT (stmts
, i
, use_stmt
)
1362 gcc_assert (gimple_code (use_stmt
) != GIMPLE_PHI
);
1363 gimple_stmt_iterator gsi_def_stmt
= gsi_start_bb_nondebug (begin_bb
);
1365 use_operand_p use_p
;
1366 ssa_op_iter op_iter
;
1367 FOR_EACH_SSA_USE_OPERAND (use_p
, use_stmt
, op_iter
, SSA_OP_USE
)
1369 /* Iterator to the current def of use_p. For function parameters or
1370 anything where def is not found, insert at the beginning of the
1371 generated region. */
1372 gimple_stmt_iterator gsi_stmt
= gsi_def_stmt
;
1374 tree op
= USE_FROM_PTR (use_p
);
1375 gimple
*stmt
= SSA_NAME_DEF_STMT (op
);
1376 if (stmt
&& (gimple_code (stmt
) != GIMPLE_NOP
))
1377 gsi_stmt
= gsi_for_stmt (stmt
);
1379 /* For region parameters, insert at the beginning of the generated
1381 if (!bb_in_sese_p (gsi_bb (gsi_stmt
), codegen_region
))
1382 gsi_stmt
= gsi_def_stmt
;
1384 gsi_def_stmt
= later_of_the_two (gsi_stmt
, gsi_def_stmt
);
1387 if (!gsi_stmt (gsi_def_stmt
))
1389 gimple_stmt_iterator gsi
= gsi_after_labels (gsi_bb (gsi_def_stmt
));
1390 gsi_insert_before (&gsi
, use_stmt
, GSI_NEW_STMT
);
1392 else if (gimple_code (gsi_stmt (gsi_def_stmt
)) == GIMPLE_PHI
)
1394 gimple_stmt_iterator bsi
1395 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt
));
1396 /* Insert right after the PHI statements. */
1397 gsi_insert_before (&bsi
, use_stmt
, GSI_NEW_STMT
);
1400 gsi_insert_after (&gsi_def_stmt
, use_stmt
, GSI_NEW_STMT
);
1404 fprintf (dump_file
, "[codegen] inserting statement: ");
1405 print_gimple_stmt (dump_file
, use_stmt
, 0, TDF_VOPS
| TDF_MEMSYMS
);
1406 print_loops_bb (dump_file
, gimple_bb (use_stmt
), 0, 3);
1411 /* Collect all the operands of NEW_EXPR by recursively visiting each
1414 void translate_isl_ast_to_gimple::
1415 collect_all_ssa_names (tree new_expr
, vec
<tree
> *vec_ssa
)
1417 if (new_expr
== NULL_TREE
)
1420 /* Rename all uses in new_expr. */
1421 if (TREE_CODE (new_expr
) == SSA_NAME
)
1423 vec_ssa
->safe_push (new_expr
);
1427 /* Iterate over SSA_NAMES in NEW_EXPR. */
1428 for (int i
= 0; i
< (TREE_CODE_LENGTH (TREE_CODE (new_expr
))); i
++)
1430 tree op
= TREE_OPERAND (new_expr
, i
);
1431 collect_all_ssa_names (op
, vec_ssa
);
1435 /* This is abridged version of the function copied from:
1436 tree.c:substitute_in_expr (tree exp, tree f, tree r). */
1439 substitute_ssa_name (tree exp
, tree f
, tree r
)
1441 enum tree_code code
= TREE_CODE (exp
);
1442 tree op0
, op1
, op2
, op3
;
1445 /* We handle TREE_LIST and COMPONENT_REF separately. */
1446 if (code
== TREE_LIST
)
1448 op0
= substitute_ssa_name (TREE_CHAIN (exp
), f
, r
);
1449 op1
= substitute_ssa_name (TREE_VALUE (exp
), f
, r
);
1450 if (op0
== TREE_CHAIN (exp
) && op1
== TREE_VALUE (exp
))
1453 return tree_cons (TREE_PURPOSE (exp
), op1
, op0
);
1455 else if (code
== COMPONENT_REF
)
1459 /* If this expression is getting a value from a PLACEHOLDER_EXPR
1460 and it is the right field, replace it with R. */
1461 for (inner
= TREE_OPERAND (exp
, 0);
1462 REFERENCE_CLASS_P (inner
);
1463 inner
= TREE_OPERAND (inner
, 0))
1467 op1
= TREE_OPERAND (exp
, 1);
1469 if (TREE_CODE (inner
) == PLACEHOLDER_EXPR
&& op1
== f
)
1472 /* If this expression hasn't been completed let, leave it alone. */
1473 if (TREE_CODE (inner
) == PLACEHOLDER_EXPR
&& !TREE_TYPE (inner
))
1476 op0
= substitute_ssa_name (TREE_OPERAND (exp
, 0), f
, r
);
1477 if (op0
== TREE_OPERAND (exp
, 0))
1481 = fold_build3 (COMPONENT_REF
, TREE_TYPE (exp
), op0
, op1
, NULL_TREE
);
1484 switch (TREE_CODE_CLASS (code
))
1489 case tcc_declaration
:
1495 case tcc_expression
:
1501 case tcc_exceptional
:
1504 case tcc_comparison
:
1506 switch (TREE_CODE_LENGTH (code
))
1514 op0
= substitute_ssa_name (TREE_OPERAND (exp
, 0), f
, r
);
1515 if (op0
== TREE_OPERAND (exp
, 0))
1518 new_tree
= fold_build1 (code
, TREE_TYPE (exp
), op0
);
1522 op0
= substitute_ssa_name (TREE_OPERAND (exp
, 0), f
, r
);
1523 op1
= substitute_ssa_name (TREE_OPERAND (exp
, 1), f
, r
);
1525 if (op0
== TREE_OPERAND (exp
, 0) && op1
== TREE_OPERAND (exp
, 1))
1528 new_tree
= fold_build2 (code
, TREE_TYPE (exp
), op0
, op1
);
1532 op0
= substitute_ssa_name (TREE_OPERAND (exp
, 0), f
, r
);
1533 op1
= substitute_ssa_name (TREE_OPERAND (exp
, 1), f
, r
);
1534 op2
= substitute_ssa_name (TREE_OPERAND (exp
, 2), f
, r
);
1536 if (op0
== TREE_OPERAND (exp
, 0) && op1
== TREE_OPERAND (exp
, 1)
1537 && op2
== TREE_OPERAND (exp
, 2))
1540 new_tree
= fold_build3 (code
, TREE_TYPE (exp
), op0
, op1
, op2
);
1544 op0
= substitute_ssa_name (TREE_OPERAND (exp
, 0), f
, r
);
1545 op1
= substitute_ssa_name (TREE_OPERAND (exp
, 1), f
, r
);
1546 op2
= substitute_ssa_name (TREE_OPERAND (exp
, 2), f
, r
);
1547 op3
= substitute_ssa_name (TREE_OPERAND (exp
, 3), f
, r
);
1549 if (op0
== TREE_OPERAND (exp
, 0) && op1
== TREE_OPERAND (exp
, 1)
1550 && op2
== TREE_OPERAND (exp
, 2)
1551 && op3
== TREE_OPERAND (exp
, 3))
1555 = fold (build4 (code
, TREE_TYPE (exp
), op0
, op1
, op2
, op3
));
1568 TREE_READONLY (new_tree
) |= TREE_READONLY (exp
);
1570 if (code
== INDIRECT_REF
|| code
== ARRAY_REF
|| code
== ARRAY_RANGE_REF
)
1571 TREE_THIS_NOTRAP (new_tree
) |= TREE_THIS_NOTRAP (exp
);
1576 /* Rename all the operands of NEW_EXPR by recursively visiting each operand. */
1578 tree
translate_isl_ast_to_gimple::
1579 rename_all_uses (tree new_expr
, basic_block new_bb
, basic_block old_bb
)
1581 auto_vec
<tree
, 2> ssa_names
;
1582 collect_all_ssa_names (new_expr
, &ssa_names
);
1585 FOR_EACH_VEC_ELT (ssa_names
, i
, t
)
1586 if (tree r
= get_rename (new_bb
, t
, old_bb
, unknown_phi
))
1587 new_expr
= substitute_ssa_name (new_expr
, t
, r
);
1592 /* For ops which are scev_analyzeable, we can regenerate a new name from its
1593 scalar evolution around LOOP. */
1595 tree
translate_isl_ast_to_gimple::
1596 get_rename_from_scev (tree old_name
, gimple_seq
*stmts
, loop_p loop
,
1597 basic_block new_bb
, basic_block old_bb
,
1600 tree scev
= scalar_evolution_in_region (region
->region
, loop
, old_name
);
1602 /* At this point we should know the exact scev for each
1603 scalar SSA_NAME used in the scop: all the other scalar
1604 SSA_NAMEs should have been translated out of SSA using
1605 arrays with one element. */
1607 if (chrec_contains_undetermined (scev
))
1609 codegen_error
= true;
1610 return build_zero_cst (TREE_TYPE (old_name
));
1613 new_expr
= chrec_apply_map (scev
, iv_map
);
1615 /* The apply should produce an expression tree containing
1616 the uses of the new induction variables. We should be
1617 able to use new_expr instead of the old_name in the newly
1618 generated loop nest. */
1619 if (chrec_contains_undetermined (new_expr
)
1620 || tree_contains_chrecs (new_expr
, NULL
))
1622 codegen_error
= true;
1623 return build_zero_cst (TREE_TYPE (old_name
));
1626 if (TREE_CODE (new_expr
) == SSA_NAME
)
1628 basic_block bb
= gimple_bb (SSA_NAME_DEF_STMT (new_expr
));
1629 if (bb
&& !dominated_by_p (CDI_DOMINATORS
, new_bb
, bb
))
1631 codegen_error
= true;
1632 return build_zero_cst (TREE_TYPE (old_name
));
1636 new_expr
= rename_all_uses (new_expr
, new_bb
, old_bb
);
1638 /* We check all the operands and all of them should dominate the use at
1640 auto_vec
<tree
, 2> new_ssa_names
;
1641 collect_all_ssa_names (new_expr
, &new_ssa_names
);
1644 FOR_EACH_VEC_ELT (new_ssa_names
, i
, new_ssa_name
)
1646 if (TREE_CODE (new_ssa_name
) == SSA_NAME
)
1648 basic_block bb
= gimple_bb (SSA_NAME_DEF_STMT (new_ssa_name
));
1649 if (bb
&& !dominated_by_p (CDI_DOMINATORS
, new_bb
, bb
))
1651 codegen_error
= true;
1652 return build_zero_cst (TREE_TYPE (old_name
));
1657 /* Replace the old_name with the new_expr. */
1658 return force_gimple_operand (unshare_expr (new_expr
), stmts
,
1662 /* Renames the scalar uses of the statement COPY, using the
1663 substitution map RENAME_MAP, inserting the gimplification code at
1664 GSI_TGT, for the translation REGION, with the original copied
1665 statement in LOOP, and using the induction variable renaming map
1666 IV_MAP. Returns true when something has been renamed. */
1668 bool translate_isl_ast_to_gimple::
1669 rename_uses (gimple
*copy
, gimple_stmt_iterator
*gsi_tgt
, basic_block old_bb
,
1670 loop_p loop
, vec
<tree
> iv_map
)
1672 bool changed
= false;
1674 if (is_gimple_debug (copy
))
1676 if (gimple_debug_bind_p (copy
))
1677 gimple_debug_bind_reset_value (copy
);
1678 else if (gimple_debug_source_bind_p (copy
))
1688 fprintf (dump_file
, "[codegen] renaming uses of stmt: ");
1689 print_gimple_stmt (dump_file
, copy
, 0, 0);
1692 use_operand_p use_p
;
1693 ssa_op_iter op_iter
;
1694 FOR_EACH_SSA_USE_OPERAND (use_p
, copy
, op_iter
, SSA_OP_USE
)
1696 tree old_name
= USE_FROM_PTR (use_p
);
1700 fprintf (dump_file
, "[codegen] renaming old_name = ");
1701 print_generic_expr (dump_file
, old_name
, 0);
1702 fprintf (dump_file
, "\n");
1705 if (TREE_CODE (old_name
) != SSA_NAME
1706 || SSA_NAME_IS_DEFAULT_DEF (old_name
))
1710 tree new_expr
= get_rename (gsi_tgt
->bb
, old_name
,
1711 old_bb
, unknown_phi
);
1715 tree type_old_name
= TREE_TYPE (old_name
);
1716 tree type_new_expr
= TREE_TYPE (new_expr
);
1720 fprintf (dump_file
, "[codegen] from rename_map: new_name = ");
1721 print_generic_expr (dump_file
, new_expr
, 0);
1722 fprintf (dump_file
, "\n");
1725 if (type_old_name
!= type_new_expr
1726 || TREE_CODE (new_expr
) != SSA_NAME
)
1728 tree var
= create_tmp_var (type_old_name
, "var");
1730 if (!useless_type_conversion_p (type_old_name
, type_new_expr
))
1731 new_expr
= fold_convert (type_old_name
, new_expr
);
1734 new_expr
= force_gimple_operand (new_expr
, &stmts
, true, var
);
1735 gsi_insert_earliest (stmts
);
1738 replace_exp (use_p
, new_expr
);
1743 new_expr
= get_rename_from_scev (old_name
, &stmts
, loop
, gimple_bb (copy
),
1745 if (!new_expr
|| codegen_error_p ())
1750 fprintf (dump_file
, "[codegen] not in rename map, scev: ");
1751 print_generic_expr (dump_file
, new_expr
, 0);
1752 fprintf (dump_file
, "\n");
1755 gsi_insert_earliest (stmts
);
1756 replace_exp (use_p
, new_expr
);
1758 if (TREE_CODE (new_expr
) == INTEGER_CST
1759 && is_gimple_assign (copy
))
1761 tree rhs
= gimple_assign_rhs1 (copy
);
1763 if (TREE_CODE (rhs
) == ADDR_EXPR
)
1764 recompute_tree_invariant_for_addr_expr (rhs
);
1767 set_rename (old_name
, new_expr
);
1773 /* Returns a basic block that could correspond to where a constant was defined
1774 in the original code. In the original code OLD_BB had the definition, we
1775 need to find which basic block out of the copies of old_bb, in the new
1776 region, should a definition correspond to if it has to reach BB. */
1778 basic_block
translate_isl_ast_to_gimple::
1779 get_def_bb_for_const (basic_block bb
, basic_block old_bb
) const
1781 vec
<basic_block
> *bbs
= region
->copied_bb_map
->get (old_bb
);
1783 if (!bbs
|| bbs
->is_empty ())
1786 if (1 == bbs
->length ())
1790 basic_block b1
= NULL
, b2
;
1791 FOR_EACH_VEC_ELT (*bbs
, i
, b2
)
1796 /* BB and B2 are in two unrelated if-clauses. */
1797 if (!dominated_by_p (CDI_DOMINATORS
, bb
, b2
))
1800 /* Compute the nearest dominator. */
1801 if (!b1
|| dominated_by_p (CDI_DOMINATORS
, b2
, b1
))
1808 /* Get the new name of OP (from OLD_BB) to be used in NEW_BB. PHI_KIND
1809 determines the kind of phi node. */
1811 tree
translate_isl_ast_to_gimple::
1812 get_new_name (basic_block new_bb
, tree op
,
1813 basic_block old_bb
, phi_node_kind phi_kind
) const
1815 /* For constants the names are the same. */
1816 if (TREE_CODE (op
) != SSA_NAME
)
1819 return get_rename (new_bb
, op
, old_bb
, phi_kind
);
1822 /* Return a debug location for OP. */
1827 location_t loc
= UNKNOWN_LOCATION
;
1829 if (TREE_CODE (op
) == SSA_NAME
)
1830 loc
= gimple_location (SSA_NAME_DEF_STMT (op
));
1834 /* Returns the incoming edges of basic_block BB in the pair. The first edge is
1835 the init edge (from outside the loop) and the second one is the back edge
1836 from the same loop. */
1838 std::pair
<edge
, edge
>
1839 get_edges (basic_block bb
)
1841 std::pair
<edge
, edge
> edges
;
1844 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1845 if (bb
->loop_father
!= e
->src
->loop_father
)
1852 /* Copy the PHI arguments from OLD_PHI to the NEW_PHI. The arguments to NEW_PHI
1853 must be found unless they can be POSTPONEd for later. */
1855 bool translate_isl_ast_to_gimple::
1856 copy_loop_phi_args (gphi
*old_phi
, init_back_edge_pair_t
&ibp_old_bb
,
1857 gphi
*new_phi
, init_back_edge_pair_t
&ibp_new_bb
,
1860 gcc_assert (gimple_phi_num_args (old_phi
) == gimple_phi_num_args (new_phi
));
1862 basic_block new_bb
= gimple_bb (new_phi
);
1863 for (unsigned i
= 0; i
< gimple_phi_num_args (old_phi
); i
++)
1866 if (gimple_phi_arg_edge (old_phi
, i
) == ibp_old_bb
.first
)
1867 e
= ibp_new_bb
.first
;
1869 e
= ibp_new_bb
.second
;
1871 tree old_name
= gimple_phi_arg_def (old_phi
, i
);
1872 tree new_name
= get_new_name (new_bb
, old_name
,
1873 gimple_bb (old_phi
), loop_phi
);
1876 add_phi_arg (new_phi
, new_name
, e
, get_loc (old_name
));
1880 gimple
*old_def_stmt
= SSA_NAME_DEF_STMT (old_name
);
1881 if (!old_def_stmt
|| gimple_code (old_def_stmt
) == GIMPLE_NOP
)
1882 /* If the phi arg was a function arg, or wasn't defined, just use the
1884 add_phi_arg (new_phi
, old_name
, e
, get_loc (old_name
));
1887 /* Postpone code gen for later for those back-edges we don't have the
1889 region
->incomplete_phis
.safe_push (std::make_pair (old_phi
, new_phi
));
1891 fprintf (dump_file
, "[codegen] postpone loop phi nodes.\n");
1894 /* Either we should add the arg to phi or, we should postpone. */
1900 /* Copy loop phi nodes from BB to NEW_BB. */
1902 bool translate_isl_ast_to_gimple::
1903 copy_loop_phi_nodes (basic_block bb
, basic_block new_bb
)
1906 fprintf (dump_file
, "[codegen] copying loop phi nodes in bb_%d.\n",
1909 /* Loop phi nodes should have only two arguments. */
1910 gcc_assert (2 == EDGE_COUNT (bb
->preds
));
1912 /* First edge is the init edge and second is the back edge. */
1913 init_back_edge_pair_t ibp_old_bb
= get_edges (bb
);
1915 /* First edge is the init edge and second is the back edge. */
1916 init_back_edge_pair_t ibp_new_bb
= get_edges (new_bb
);
1918 for (gphi_iterator psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);
1921 gphi
*phi
= psi
.phi ();
1922 tree res
= gimple_phi_result (phi
);
1923 if (virtual_operand_p (res
))
1925 if (is_gimple_reg (res
) && scev_analyzable_p (res
, region
->region
))
1928 gphi
*new_phi
= create_phi_node (SSA_NAME_VAR (res
), new_bb
);
1929 tree new_res
= create_new_def_for (res
, new_phi
,
1930 gimple_phi_result_ptr (new_phi
));
1931 set_rename (res
, new_res
);
1932 codegen_error
= !copy_loop_phi_args (phi
, ibp_old_bb
, new_phi
,
1934 update_stmt (new_phi
);
1938 fprintf (dump_file
, "[codegen] creating loop-phi node: ");
1939 print_gimple_stmt (dump_file
, new_phi
, 0, 0);
1946 /* Return the init value of PHI, the value coming from outside the loop. */
1949 get_loop_init_value (gphi
*phi
)
1952 loop_p loop
= gimple_bb (phi
)->loop_father
;
1956 FOR_EACH_EDGE (e
, ei
, gimple_bb (phi
)->preds
)
1957 if (e
->src
->loop_father
!= loop
)
1958 return gimple_phi_arg_def (phi
, e
->dest_idx
);
1963 /* Find the init value (the value which comes from outside the loop), of one of
1964 the operands of DEF which is defined by a loop phi. */
1967 find_init_value (gimple
*def
)
1969 if (gimple_code (def
) == GIMPLE_PHI
)
1970 return get_loop_init_value (as_a
<gphi
*> (def
));
1972 if (gimple_vuse (def
))
1976 use_operand_p use_p
;
1977 FOR_EACH_SSA_USE_OPERAND (use_p
, def
, iter
, SSA_OP_USE
)
1979 tree use
= USE_FROM_PTR (use_p
);
1980 if (TREE_CODE (use
) == SSA_NAME
)
1982 if (tree res
= find_init_value (SSA_NAME_DEF_STMT (use
)))
1990 /* Return the init value, the value coming from outside the loop. */
1993 find_init_value_close_phi (gphi
*phi
)
1995 gcc_assert (gimple_phi_num_args (phi
) == 1);
1996 tree use_arg
= gimple_phi_arg_def (phi
, 0);
1997 gimple
*def
= SSA_NAME_DEF_STMT (use_arg
);
1998 return find_init_value (def
);
2002 tree
translate_isl_ast_to_gimple::
2003 add_close_phis_to_outer_loops (tree last_merge_name
, edge last_e
,
2004 gimple
*old_close_phi
)
2006 sese_l
&codegen_region
= region
->if_region
->true_region
->region
;
2007 gimple
*stmt
= SSA_NAME_DEF_STMT (last_merge_name
);
2008 basic_block bb
= gimple_bb (stmt
);
2009 if (!bb_in_sese_p (bb
, codegen_region
))
2010 return last_merge_name
;
2012 loop_p loop
= bb
->loop_father
;
2013 if (!loop_in_sese_p (loop
, codegen_region
))
2014 return last_merge_name
;
2016 edge e
= single_exit (loop
);
2018 if (dominated_by_p (CDI_DOMINATORS
, e
->dest
, last_e
->src
))
2019 return last_merge_name
;
2021 tree old_name
= gimple_phi_arg_def (old_close_phi
, 0);
2022 tree old_close_phi_name
= gimple_phi_result (old_close_phi
);
2025 if (!bb_contains_loop_close_phi_nodes (bb
) || !single_succ_p (bb
))
2026 bb
= split_edge (e
);
2028 gphi
*close_phi
= create_phi_node (SSA_NAME_VAR (last_merge_name
), bb
);
2029 tree res
= create_new_def_for (last_merge_name
, close_phi
,
2030 gimple_phi_result_ptr (close_phi
));
2031 set_rename (old_close_phi_name
, res
);
2032 add_phi_arg (close_phi
, last_merge_name
, e
, get_loc (old_name
));
2033 last_merge_name
= res
;
2035 return add_close_phis_to_outer_loops (last_merge_name
, last_e
, old_close_phi
);
2038 /* Add phi nodes to all merge points of all the diamonds enclosing the loop of
2039 the close phi node PHI. */
2041 bool translate_isl_ast_to_gimple::
2042 add_close_phis_to_merge_points (gphi
*old_close_phi
, gphi
*new_close_phi
,
2045 sese_l
&codegen_region
= region
->if_region
->true_region
->region
;
2046 basic_block default_value_bb
= get_entry_bb (codegen_region
);
2047 if (SSA_NAME
== TREE_CODE (default_value
))
2049 gimple
*stmt
= SSA_NAME_DEF_STMT (default_value
);
2050 if (!stmt
|| gimple_code (stmt
) == GIMPLE_NOP
)
2052 default_value_bb
= gimple_bb (stmt
);
2055 basic_block new_close_phi_bb
= gimple_bb (new_close_phi
);
2057 tree old_close_phi_name
= gimple_phi_result (old_close_phi
);
2058 tree new_close_phi_name
= gimple_phi_result (new_close_phi
);
2059 tree last_merge_name
= new_close_phi_name
;
2060 tree old_name
= gimple_phi_arg_def (old_close_phi
, 0);
2064 FOR_EACH_VEC_ELT_REVERSE (merge_points
, i
, merge_e
)
2066 basic_block new_merge_bb
= merge_e
->src
;
2067 if (!dominated_by_p (CDI_DOMINATORS
, new_merge_bb
, default_value_bb
))
2070 last_merge_name
= add_close_phis_to_outer_loops (last_merge_name
, merge_e
,
2073 gphi
*merge_phi
= create_phi_node (SSA_NAME_VAR (old_close_phi_name
), new_merge_bb
);
2074 tree merge_res
= create_new_def_for (old_close_phi_name
, merge_phi
,
2075 gimple_phi_result_ptr (merge_phi
));
2076 set_rename (old_close_phi_name
, merge_res
);
2078 edge from_loop
= NULL
, from_default_value
= NULL
;
2081 FOR_EACH_EDGE (e
, ei
, new_merge_bb
->preds
)
2082 if (dominated_by_p (CDI_DOMINATORS
, e
->src
, new_close_phi_bb
))
2085 from_default_value
= e
;
2087 /* Because CDI_POST_DOMINATORS are not updated, we only rely on
2088 CDI_DOMINATORS, which may not handle all cases where new_close_phi_bb
2089 is contained in another condition. */
2090 if (!from_default_value
|| !from_loop
)
2093 add_phi_arg (merge_phi
, last_merge_name
, from_loop
, get_loc (old_name
));
2094 add_phi_arg (merge_phi
, default_value
, from_default_value
, get_loc (old_name
));
2098 fprintf (dump_file
, "[codegen] Adding guard-phi: ");
2099 print_gimple_stmt (dump_file
, merge_phi
, 0, 0);
2102 update_stmt (merge_phi
);
2103 last_merge_name
= merge_res
;
2109 /* Copy all the loop-close phi args from BB to NEW_BB. */
2111 bool translate_isl_ast_to_gimple::
2112 copy_loop_close_phi_args (basic_block old_bb
, basic_block new_bb
, bool postpone
)
2114 for (gphi_iterator psi
= gsi_start_phis (old_bb
); !gsi_end_p (psi
);
2117 gphi
*old_close_phi
= psi
.phi ();
2118 tree res
= gimple_phi_result (old_close_phi
);
2119 if (virtual_operand_p (res
))
2122 if (is_gimple_reg (res
) && scev_analyzable_p (res
, region
->region
))
2123 /* Loop close phi nodes should not be scev_analyzable_p. */
2126 gphi
*new_close_phi
= create_phi_node (SSA_NAME_VAR (res
), new_bb
);
2127 tree new_res
= create_new_def_for (res
, new_close_phi
,
2128 gimple_phi_result_ptr (new_close_phi
));
2129 set_rename (res
, new_res
);
2131 tree old_name
= gimple_phi_arg_def (old_close_phi
, 0);
2132 tree new_name
= get_new_name (new_bb
, old_name
, old_bb
, close_phi
);
2134 /* Predecessor basic blocks of a loop close phi should have been code
2135 generated before. FIXME: This is fixable by merging PHIs from inner
2136 loops as well. See: gfortran.dg/graphite/interchange-3.f90. */
2140 add_phi_arg (new_close_phi
, new_name
, single_pred_edge (new_bb
),
2141 get_loc (old_name
));
2144 fprintf (dump_file
, "[codegen] Adding loop close phi: ");
2145 print_gimple_stmt (dump_file
, new_close_phi
, 0, 0);
2148 update_stmt (new_close_phi
);
2150 /* When there is no loop guard around this codegenerated loop, there is no
2151 need to collect the close-phi arg. */
2152 if (merge_points
.is_empty ())
2155 /* Add a PHI in the succ_new_bb for each close phi of the loop. */
2156 tree default_value
= find_init_value_close_phi (new_close_phi
);
2158 /* A close phi must come from a loop-phi having a default value. */
2164 region
->incomplete_phis
.safe_push (std::make_pair (old_close_phi
,
2168 fprintf (dump_file
, "[codegen] postpone close phi nodes: ");
2169 print_gimple_stmt (dump_file
, new_close_phi
, 0, 0);
2174 if (!add_close_phis_to_merge_points (old_close_phi
, new_close_phi
,
2182 /* Copy loop close phi nodes from BB to NEW_BB. */
2184 bool translate_isl_ast_to_gimple::
2185 copy_loop_close_phi_nodes (basic_block old_bb
, basic_block new_bb
)
2188 fprintf (dump_file
, "[codegen] copying loop close phi nodes in bb_%d.\n",
2190 /* Loop close phi nodes should have only one argument. */
2191 gcc_assert (1 == EDGE_COUNT (old_bb
->preds
));
2193 return copy_loop_close_phi_args (old_bb
, new_bb
, true);
2197 /* Add NEW_NAME as the ARGNUM-th arg of NEW_PHI which is in NEW_BB.
2198 DOMINATING_PRED is the predecessor basic block of OLD_BB which dominates the
2199 other pred of OLD_BB as well. If no such basic block exists then it is NULL.
2200 NON_DOMINATING_PRED is a pred which does not dominate OLD_BB, it cannot be
2203 Case1: OLD_BB->preds {BB1, BB2} and BB1 does not dominate BB2 and vice versa.
2204 In this case DOMINATING_PRED = NULL.
2206 Case2: OLD_BB->preds {BB1, BB2} and BB1 dominates BB2.
2208 Returns true on successful copy of the args, false otherwise. */
2210 bool translate_isl_ast_to_gimple::
2211 add_phi_arg_for_new_expr (tree old_phi_args
[2], tree new_phi_args
[2],
2212 edge old_bb_dominating_edge
,
2213 edge old_bb_non_dominating_edge
,
2214 gphi
*phi
, gphi
*new_phi
,
2217 basic_block def_pred
[2] = { NULL
, NULL
};
2218 int not_found_bb_index
= -1;
2219 for (int i
= 0; i
< 2; i
++)
2221 /* If the corresponding def_bb could not be found the entry will be
2223 if (TREE_CODE (old_phi_args
[i
]) == INTEGER_CST
)
2224 def_pred
[i
] = get_def_bb_for_const (new_bb
,
2225 gimple_phi_arg_edge (phi
, i
)->src
);
2226 else if (new_phi_args
[i
] && (TREE_CODE (new_phi_args
[i
]) == SSA_NAME
))
2227 def_pred
[i
] = gimple_bb (SSA_NAME_DEF_STMT (new_phi_args
[i
]));
2231 /* When non are available bail out. */
2232 if (not_found_bb_index
!= -1)
2234 not_found_bb_index
= i
;
2238 /* Here we are pattern matching on the structure of CFG w.r.t. old one. */
2239 if (old_bb_dominating_edge
)
2241 if (not_found_bb_index
!= -1)
2244 basic_block new_pred1
= (*new_bb
->preds
)[0]->src
;
2245 basic_block new_pred2
= (*new_bb
->preds
)[1]->src
;
2246 vec
<basic_block
> *bbs
2247 = region
->copied_bb_map
->get (old_bb_non_dominating_edge
->src
);
2249 /* Could not find a mapping. */
2253 basic_block new_pred
= NULL
;
2256 FOR_EACH_VEC_ELT (*bbs
, i
, b
)
2258 if (dominated_by_p (CDI_DOMINATORS
, new_pred1
, b
))
2260 /* FIXME: If we have already found new_pred then we have to
2261 disambiguate, bail out for now. */
2264 new_pred
= new_pred1
;
2266 if (dominated_by_p (CDI_DOMINATORS
, new_pred2
, b
))
2268 /* FIXME: If we have already found new_pred then we have to either
2269 it dominates both or we have to disambiguate, bail out. */
2272 new_pred
= new_pred2
;
2279 edge new_non_dominating_edge
= find_edge (new_pred
, new_bb
);
2280 gcc_assert (new_non_dominating_edge
);
2281 /* FIXME: Validate each args just like in loop-phis. */
2282 /* By the process of elimination we first insert insert phi-edge for
2283 non-dominating pred which is computed above and then we insert the
2285 int inserted_edge
= 0;
2286 for (; inserted_edge
< 2; inserted_edge
++)
2288 edge new_bb_pred_edge
= gimple_phi_arg_edge (new_phi
, inserted_edge
);
2289 if (new_non_dominating_edge
== new_bb_pred_edge
)
2291 add_phi_arg (new_phi
, new_phi_args
[inserted_edge
],
2292 new_non_dominating_edge
,
2293 get_loc (old_phi_args
[inserted_edge
]));
2297 if (inserted_edge
== 2)
2300 int edge_dominating
= inserted_edge
== 0 ? 1 : 0;
2302 edge new_dominating_edge
= NULL
;
2303 for (inserted_edge
= 0; inserted_edge
< 2; inserted_edge
++)
2305 edge e
= gimple_phi_arg_edge (new_phi
, inserted_edge
);
2306 if (e
!= new_non_dominating_edge
)
2308 new_dominating_edge
= e
;
2309 add_phi_arg (new_phi
, new_phi_args
[edge_dominating
],
2310 new_dominating_edge
,
2311 get_loc (old_phi_args
[inserted_edge
]));
2315 gcc_assert (new_dominating_edge
);
2319 /* Classic diamond structure: both edges are non-dominating. We need to
2320 find one unique edge then the other can be found be elimination. If
2321 any definition (def_pred) dominates both the preds of new_bb then we
2322 bail out. Entries of def_pred maybe NULL, in that case we must
2323 uniquely find pred with help of only one entry. */
2324 edge new_e
[2] = { NULL
, NULL
};
2325 for (int i
= 0; i
< 2; i
++)
2329 FOR_EACH_EDGE (e
, ei
, new_bb
->preds
)
2331 && dominated_by_p (CDI_DOMINATORS
, e
->src
, def_pred
[i
]))
2334 /* We do not know how to handle the case when def_pred
2335 dominates more than a predecessor. */
2341 gcc_assert (new_e
[0] || new_e
[1]);
2343 /* Find the other edge by process of elimination. */
2344 if (not_found_bb_index
!= -1)
2346 gcc_assert (!new_e
[not_found_bb_index
]);
2347 int found_bb_index
= not_found_bb_index
== 1 ? 0 : 1;
2350 FOR_EACH_EDGE (e
, ei
, new_bb
->preds
)
2352 if (new_e
[found_bb_index
] == e
)
2354 new_e
[not_found_bb_index
] = e
;
2358 /* Add edges to phi args. */
2359 for (int i
= 0; i
< 2; i
++)
2360 add_phi_arg (new_phi
, new_phi_args
[i
], new_e
[i
],
2361 get_loc (old_phi_args
[i
]));
2367 /* Copy the arguments of cond-phi node PHI, to NEW_PHI in the codegenerated
2368 region. If postpone is true and it isn't possible to copy any arg of PHI,
2369 the PHI is added to the REGION->INCOMPLETE_PHIS to be codegenerated later.
2370 Returns false if the copying was unsuccessful. */
2372 bool translate_isl_ast_to_gimple::
2373 copy_cond_phi_args (gphi
*phi
, gphi
*new_phi
, vec
<tree
> iv_map
, bool postpone
)
2376 fprintf (dump_file
, "[codegen] copying cond phi args.\n");
2377 gcc_assert (2 == gimple_phi_num_args (phi
));
2379 basic_block new_bb
= gimple_bb (new_phi
);
2380 loop_p loop
= gimple_bb (phi
)->loop_father
;
2382 basic_block old_bb
= gimple_bb (phi
);
2383 edge old_bb_non_dominating_edge
= NULL
, old_bb_dominating_edge
= NULL
;
2387 FOR_EACH_EDGE (e
, ei
, old_bb
->preds
)
2388 if (!dominated_by_p (CDI_DOMINATORS
, old_bb
, e
->src
))
2389 old_bb_non_dominating_edge
= e
;
2391 old_bb_dominating_edge
= e
;
2393 gcc_assert (!dominated_by_p (CDI_DOMINATORS
, old_bb
,
2394 old_bb_non_dominating_edge
->src
));
2396 tree new_phi_args
[2];
2397 tree old_phi_args
[2];
2399 for (unsigned i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2401 tree old_name
= gimple_phi_arg_def (phi
, i
);
2402 tree new_name
= get_new_name (new_bb
, old_name
, old_bb
, cond_phi
);
2403 old_phi_args
[i
] = old_name
;
2406 new_phi_args
[i
] = new_name
;
2410 /* If the phi-arg was a parameter. */
2411 if (vec_find (region
->params
, old_name
) != -1)
2413 new_phi_args
[i
] = old_name
;
2417 "[codegen] parameter argument to phi, new_expr: ");
2418 print_generic_expr (dump_file
, new_phi_args
[i
], 0);
2419 fprintf (dump_file
, "\n");
2424 gimple
*old_def_stmt
= SSA_NAME_DEF_STMT (old_name
);
2425 if (!old_def_stmt
|| gimple_code (old_def_stmt
) == GIMPLE_NOP
)
2426 /* FIXME: If the phi arg was a function arg, or wasn't defined, just use
2432 /* If the phi-arg is scev-analyzeable but only in the first stage. */
2433 if (is_gimple_reg (old_name
)
2434 && scev_analyzable_p (old_name
, region
->region
))
2437 tree new_expr
= get_rename_from_scev (old_name
, &stmts
, loop
,
2438 new_bb
, old_bb
, iv_map
);
2439 if (codegen_error_p ())
2442 gcc_assert (new_expr
);
2446 "[codegen] scev analyzeable, new_expr: ");
2447 print_generic_expr (dump_file
, new_expr
, 0);
2448 fprintf (dump_file
, "\n");
2450 gsi_insert_earliest (stmts
);
2451 new_phi_args
[i
] = new_expr
;
2455 /* Postpone code gen for later for back-edges. */
2456 region
->incomplete_phis
.safe_push (std::make_pair (phi
, new_phi
));
2460 fprintf (dump_file
, "[codegen] postpone cond phi nodes: ");
2461 print_gimple_stmt (dump_file
, new_phi
, 0, 0);
2464 new_phi_args
[i
] = NULL_TREE
;
2468 /* Either we should add the arg to phi or, we should postpone. */
2472 /* If none of the args have been determined in the first stage then wait until
2474 if (postpone
&& !new_phi_args
[0] && !new_phi_args
[1])
2477 return add_phi_arg_for_new_expr (old_phi_args
, new_phi_args
,
2478 old_bb_dominating_edge
,
2479 old_bb_non_dominating_edge
,
2480 phi
, new_phi
, new_bb
);
2483 /* Copy cond phi nodes from BB to NEW_BB. A cond-phi node is a basic block
2484 containing phi nodes coming from two predecessors, and none of them are back
2487 bool translate_isl_ast_to_gimple::
2488 copy_cond_phi_nodes (basic_block bb
, basic_block new_bb
, vec
<tree
> iv_map
)
2491 gcc_assert (!bb_contains_loop_close_phi_nodes (bb
));
2493 /* TODO: Handle cond phi nodes with more than 2 predecessors. */
2494 if (EDGE_COUNT (bb
->preds
) != 2)
2498 fprintf (dump_file
, "[codegen] copying cond phi nodes in bb_%d.\n",
2501 for (gphi_iterator psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);
2504 gphi
*phi
= psi
.phi ();
2505 tree res
= gimple_phi_result (phi
);
2506 if (virtual_operand_p (res
))
2509 gphi
*new_phi
= create_phi_node (SSA_NAME_VAR (res
), new_bb
);
2510 tree new_res
= create_new_def_for (res
, new_phi
,
2511 gimple_phi_result_ptr (new_phi
));
2512 set_rename (res
, new_res
);
2514 if (!copy_cond_phi_args (phi
, new_phi
, iv_map
, true))
2517 update_stmt (new_phi
);
2523 /* Return true if STMT should be copied from region to the new code-generated
2524 region. LABELs, CONDITIONS, induction-variables and region parameters need
2528 should_copy_to_new_region (gimple
*stmt
, sese_info_p region
)
2530 /* Do not copy labels or conditions. */
2531 if (gimple_code (stmt
) == GIMPLE_LABEL
2532 || gimple_code (stmt
) == GIMPLE_COND
)
2536 /* Do not copy induction variables. */
2537 if (is_gimple_assign (stmt
)
2538 && (lhs
= gimple_assign_lhs (stmt
))
2539 && TREE_CODE (lhs
) == SSA_NAME
2540 && is_gimple_reg (lhs
)
2541 && scev_analyzable_p (lhs
, region
->region
))
2544 /* Do not copy parameters that have been generated in the header of the
2546 if (is_gimple_assign (stmt
)
2547 && (lhs
= gimple_assign_lhs (stmt
))
2548 && TREE_CODE (lhs
) == SSA_NAME
2549 && region
->parameter_rename_map
->get(lhs
))
2555 /* Create new names for all the definitions created by COPY and add replacement
2556 mappings for each new name. */
2558 void translate_isl_ast_to_gimple::
2559 set_rename_for_each_def (gimple
*stmt
)
2561 def_operand_p def_p
;
2562 ssa_op_iter op_iter
;
2563 FOR_EACH_SSA_DEF_OPERAND (def_p
, stmt
, op_iter
, SSA_OP_ALL_DEFS
)
2565 tree old_name
= DEF_FROM_PTR (def_p
);
2566 tree new_name
= create_new_def_for (old_name
, stmt
, def_p
);
2567 set_rename (old_name
, new_name
);
2571 /* Duplicates the statements of basic block BB into basic block NEW_BB
2572 and compute the new induction variables according to the IV_MAP. */
2574 bool translate_isl_ast_to_gimple::
2575 graphite_copy_stmts_from_block (basic_block bb
, basic_block new_bb
,
2578 /* Iterator poining to the place where new statement (s) will be inserted. */
2579 gimple_stmt_iterator gsi_tgt
= gsi_last_bb (new_bb
);
2581 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);
2584 gimple
*stmt
= gsi_stmt (gsi
);
2585 if (!should_copy_to_new_region (stmt
, region
))
2588 /* Create a new copy of STMT and duplicate STMT's virtual
2590 gimple
*copy
= gimple_copy (stmt
);
2591 gsi_insert_after (&gsi_tgt
, copy
, GSI_NEW_STMT
);
2595 fprintf (dump_file
, "[codegen] inserting statement: ");
2596 print_gimple_stmt (dump_file
, copy
, 0, 0);
2599 maybe_duplicate_eh_stmt (copy
, stmt
);
2600 gimple_duplicate_stmt_histograms (cfun
, copy
, cfun
, stmt
);
2602 /* Crete new names for each def in the copied stmt. */
2603 set_rename_for_each_def (copy
);
2605 loop_p loop
= bb
->loop_father
;
2606 if (rename_uses (copy
, &gsi_tgt
, bb
, loop
, iv_map
))
2608 fold_stmt_inplace (&gsi_tgt
);
2609 gcc_assert (gsi_stmt (gsi_tgt
) == copy
);
2612 if (codegen_error_p ())
2615 /* For each SSA_NAME in the parameter_rename_map rename their usage. */
2617 use_operand_p use_p
;
2618 if (!is_gimple_debug (copy
))
2619 FOR_EACH_SSA_USE_OPERAND (use_p
, copy
, iter
, SSA_OP_USE
)
2621 tree old_name
= USE_FROM_PTR (use_p
);
2623 if (TREE_CODE (old_name
) != SSA_NAME
2624 || SSA_NAME_IS_DEFAULT_DEF (old_name
))
2627 tree
*new_expr
= region
->parameter_rename_map
->get (old_name
);
2631 replace_exp (use_p
, *new_expr
);
2641 /* Given a basic block containing close-phi it returns the new basic block where
2642 to insert a copy of the close-phi nodes. All the uses in close phis should
2643 come from a single loop otherwise it returns NULL. */
2645 edge
translate_isl_ast_to_gimple::
2646 edge_for_new_close_phis (basic_block bb
)
2648 /* Make sure that NEW_BB is the new_loop->exit->dest. We find the definition
2649 of close phi in the original code and then find the mapping of basic block
2650 defining that variable. If there are multiple close-phis and they are
2651 defined in different loops (in the original or in the new code) because of
2652 loop splitting, then we bail out. */
2653 loop_p new_loop
= NULL
;
2654 for (gphi_iterator psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);
2657 gphi
*phi
= psi
.phi ();
2658 tree name
= gimple_phi_arg_def (phi
, 0);
2659 basic_block old_loop_bb
= gimple_bb (SSA_NAME_DEF_STMT (name
));
2661 vec
<basic_block
> *bbs
= region
->copied_bb_map
->get (old_loop_bb
);
2662 if (!bbs
|| bbs
->length () != 1)
2663 /* This is one of the places which shows preserving original structure
2664 is not always possible, as we may need to insert close PHI for a loop
2665 where the latch does not have any mapping, or the mapping is
2670 new_loop
= (*bbs
)[0]->loop_father
;
2671 else if (new_loop
!= (*bbs
)[0]->loop_father
)
2678 return single_exit (new_loop
);
2681 /* Copies BB and includes in the copied BB all the statements that can
2682 be reached following the use-def chains from the memory accesses,
2683 and returns the next edge following this new block. */
2685 edge
translate_isl_ast_to_gimple::
2686 copy_bb_and_scalar_dependences (basic_block bb
, edge next_e
, vec
<tree
> iv_map
)
2688 int num_phis
= number_of_phi_nodes (bb
);
2690 if (region
->copied_bb_map
->get (bb
))
2692 /* FIXME: we should be able to handle phi nodes with args coming from
2693 outside the region. */
2696 codegen_error
= true;
2701 basic_block new_bb
= NULL
;
2702 if (bb_contains_loop_close_phi_nodes (bb
))
2705 fprintf (dump_file
, "[codegen] bb_%d contains close phi nodes.\n",
2708 edge e
= edge_for_new_close_phis (bb
);
2711 codegen_error
= true;
2715 basic_block phi_bb
= e
->dest
;
2717 if (!bb_contains_loop_close_phi_nodes (phi_bb
) || !single_succ_p (phi_bb
))
2718 phi_bb
= split_edge (e
);
2720 gcc_assert (single_pred_edge (phi_bb
)->src
->loop_father
2721 != single_pred_edge (phi_bb
)->dest
->loop_father
);
2723 if (!copy_loop_close_phi_nodes (bb
, phi_bb
))
2725 codegen_error
= true;
2732 new_bb
= split_edge (next_e
);
2736 new_bb
= split_edge (next_e
);
2737 if (num_phis
> 0 && bb_contains_loop_phi_nodes (bb
))
2739 basic_block phi_bb
= next_e
->dest
->loop_father
->header
;
2741 /* At this point we are unable to codegenerate by still preserving the SSA
2742 structure because maybe the loop is completely unrolled and the PHIs
2743 and cross-bb scalar dependencies are untrackable w.r.t. the original
2744 code. See gfortran.dg/graphite/pr29832.f90. */
2745 if (EDGE_COUNT (bb
->preds
) != EDGE_COUNT (phi_bb
->preds
))
2747 codegen_error
= true;
2751 /* In case isl did some loop peeling, like this:
2754 for (int c1 = 1; c1 <= 5; c1 += 1) {
2759 there should be no loop-phi nodes in S_8(0).
2761 FIXME: We need to reason about dynamic instances of S_8, i.e., the
2762 values of all scalar variables: for the moment we instantiate only
2763 SCEV analyzable expressions on the iteration domain, and we need to
2764 extend that to reductions that cannot be analyzed by SCEV. */
2765 if (!bb_in_sese_p (phi_bb
, region
->if_region
->true_region
->region
))
2767 codegen_error
= true;
2772 fprintf (dump_file
, "[codegen] bb_%d contains loop phi nodes.\n",
2774 if (!copy_loop_phi_nodes (bb
, phi_bb
))
2776 codegen_error
= true;
2780 else if (num_phis
> 0)
2783 fprintf (dump_file
, "[codegen] bb_%d contains cond phi nodes.\n",
2786 basic_block phi_bb
= single_pred (new_bb
);
2787 loop_p loop_father
= new_bb
->loop_father
;
2789 /* Move back until we find the block with two predecessors. */
2790 while (single_pred_p (phi_bb
))
2791 phi_bb
= single_pred_edge (phi_bb
)->src
;
2793 /* If a corresponding merge-point was not found, then abort codegen. */
2794 if (phi_bb
->loop_father
!= loop_father
2795 || !bb_in_sese_p (phi_bb
, region
->if_region
->true_region
->region
)
2796 || !copy_cond_phi_nodes (bb
, phi_bb
, iv_map
))
2798 codegen_error
= true;
2805 fprintf (dump_file
, "[codegen] copying from bb_%d to bb_%d.\n",
2806 bb
->index
, new_bb
->index
);
2808 vec
<basic_block
> *copied_bbs
= region
->copied_bb_map
->get (bb
);
2810 copied_bbs
->safe_push (new_bb
);
2813 vec
<basic_block
> bbs
;
2815 bbs
.safe_push (new_bb
);
2816 region
->copied_bb_map
->put (bb
, bbs
);
2819 if (!graphite_copy_stmts_from_block (bb
, new_bb
, iv_map
))
2821 codegen_error
= true;
2825 return single_succ_edge (new_bb
);
2828 /* Patch the missing arguments of the phi nodes. */
2830 void translate_isl_ast_to_gimple::
2831 translate_pending_phi_nodes ()
2835 FOR_EACH_VEC_ELT (region
->incomplete_phis
, i
, rename
)
2837 gphi
*old_phi
= rename
->first
;
2838 gphi
*new_phi
= rename
->second
;
2839 basic_block old_bb
= gimple_bb (old_phi
);
2840 basic_block new_bb
= gimple_bb (new_phi
);
2842 /* First edge is the init edge and second is the back edge. */
2843 init_back_edge_pair_t ibp_old_bb
= get_edges (old_bb
);
2844 init_back_edge_pair_t ibp_new_bb
= get_edges (new_bb
);
2848 fprintf (dump_file
, "[codegen] translating pending old-phi: ");
2849 print_gimple_stmt (dump_file
, old_phi
, 0, 0);
2852 auto_vec
<tree
, 1> iv_map
;
2853 if (bb_contains_loop_phi_nodes (new_bb
))
2854 codegen_error
= !copy_loop_phi_args (old_phi
, ibp_old_bb
, new_phi
,
2856 else if (bb_contains_loop_close_phi_nodes (new_bb
))
2857 codegen_error
= !copy_loop_close_phi_args (old_bb
, new_bb
, false);
2859 codegen_error
= !copy_cond_phi_args (old_phi
, new_phi
, iv_map
, false);
2863 fprintf (dump_file
, "[codegen] to new-phi: ");
2864 print_gimple_stmt (dump_file
, new_phi
, 0, 0);
2866 if (codegen_error_p ())
2871 /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
2873 void translate_isl_ast_to_gimple::
2874 add_parameters_to_ivs_params (scop_p scop
, ivs_params
&ip
)
2876 sese_info_p region
= scop
->scop_info
;
2877 unsigned nb_parameters
= isl_set_dim (scop
->param_context
, isl_dim_param
);
2878 gcc_assert (nb_parameters
== region
->params
.length ());
2880 for (i
= 0; i
< nb_parameters
; i
++)
2882 isl_id
*tmp_id
= isl_set_get_dim_id (scop
->param_context
,
2884 ip
[tmp_id
] = region
->params
[i
];
2889 /* Generates a build, which specifies the constraints on the parameters. */
2891 __isl_give isl_ast_build
*translate_isl_ast_to_gimple::
2892 generate_isl_context (scop_p scop
)
2894 isl_set
*context_isl
= isl_set_params (isl_set_copy (scop
->param_context
));
2895 return isl_ast_build_from_context (context_isl
);
2898 /* This method is executed before the construction of a for node. */
2900 ast_build_before_for (__isl_keep isl_ast_build
*build
, void *user
)
2902 isl_union_map
*dependences
= (isl_union_map
*) user
;
2903 ast_build_info
*for_info
= XNEW (struct ast_build_info
);
2904 isl_union_map
*schedule
= isl_ast_build_get_schedule (build
);
2905 isl_space
*schedule_space
= isl_ast_build_get_schedule_space (build
);
2906 int dimension
= isl_space_dim (schedule_space
, isl_dim_out
);
2907 for_info
->is_parallelizable
=
2908 !carries_deps (schedule
, dependences
, dimension
);
2909 isl_union_map_free (schedule
);
2910 isl_space_free (schedule_space
);
2911 isl_id
*id
= isl_id_alloc (isl_ast_build_get_ctx (build
), "", for_info
);
2915 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
2917 /* Generate isl AST from schedule of SCOP. */
2919 __isl_give isl_ast_node
*translate_isl_ast_to_gimple::
2920 scop_to_isl_ast (scop_p scop
)
2922 gcc_assert (scop
->transformed_schedule
);
2924 /* Set the separate option to reduce control flow overhead. */
2925 isl_schedule
*schedule
= isl_schedule_map_schedule_node_bottom_up
2926 (isl_schedule_copy (scop
->transformed_schedule
), set_separate_option
, NULL
);
2927 isl_ast_build
*context_isl
= generate_isl_context (scop
);
2929 if (flag_loop_parallelize_all
)
2931 scop_get_dependences (scop
);
2933 isl_ast_build_set_before_each_for (context_isl
, ast_build_before_for
,
2937 isl_ast_node
*ast_isl
= isl_ast_build_node_from_schedule
2938 (context_isl
, schedule
);
2939 isl_ast_build_free (context_isl
);
2944 /* Get the maximal number of schedule dimensions in the scop SCOP. */
2946 int translate_isl_ast_to_gimple::
2947 get_max_schedule_dimensions (scop_p scop
)
2951 int schedule_dims
= 0;
2953 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
2955 int pbb_schedule_dims
= isl_map_dim (pbb
->transformed
, isl_dim_out
);
2956 if (pbb_schedule_dims
> schedule_dims
)
2957 schedule_dims
= pbb_schedule_dims
;
2960 return schedule_dims
;
2963 /* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
2965 For schedules with different dimensionality, the isl AST generator can not
2966 define an order and will just randomly choose an order. The solution to this
2967 problem is to extend all schedules to the maximal number of schedule
2968 dimensions (using '0's for the remaining values). */
2970 __isl_give isl_map
*translate_isl_ast_to_gimple::
2971 extend_schedule (__isl_take isl_map
*schedule
, int nb_schedule_dims
)
2973 int tmp_dims
= isl_map_dim (schedule
, isl_dim_out
);
2975 isl_map_add_dims (schedule
, isl_dim_out
, nb_schedule_dims
- tmp_dims
);
2977 isl_val_int_from_si (isl_map_get_ctx (schedule
), 0);
2979 for (i
= tmp_dims
; i
< nb_schedule_dims
; i
++)
2982 = isl_map_fix_val (schedule
, isl_dim_out
, i
, isl_val_copy (zero
));
2984 isl_val_free (zero
);
2988 /* Generates a schedule, which specifies an order used to
2989 visit elements in a domain. */
2991 __isl_give isl_union_map
*translate_isl_ast_to_gimple::
2992 generate_isl_schedule (scop_p scop
)
2994 int nb_schedule_dims
= get_max_schedule_dimensions (scop
);
2997 isl_union_map
*schedule_isl
=
2998 isl_union_map_empty (isl_set_get_space (scop
->param_context
));
3000 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
3002 /* Dead code elimination: when the domain of a PBB is empty,
3003 don't generate code for the PBB. */
3004 if (isl_set_is_empty (pbb
->domain
))
3007 isl_map
*bb_schedule
= isl_map_copy (pbb
->transformed
);
3008 bb_schedule
= isl_map_intersect_domain (bb_schedule
,
3009 isl_set_copy (pbb
->domain
));
3010 bb_schedule
= extend_schedule (bb_schedule
, nb_schedule_dims
);
3011 bb_schedule
= isl_map_coalesce (bb_schedule
);
3013 = isl_union_map_union (schedule_isl
,
3014 isl_union_map_from_map (bb_schedule
));
3015 schedule_isl
= isl_union_map_coalesce (schedule_isl
);
3017 return schedule_isl
;
3020 /* Set the separate option for all dimensions.
3021 This helps to reduce control overhead. */
3023 __isl_give isl_ast_build
*translate_isl_ast_to_gimple::
3024 set_options (__isl_take isl_ast_build
*control
,
3025 __isl_keep isl_union_map
*schedule
)
3027 isl_ctx
*ctx
= isl_union_map_get_ctx (schedule
);
3028 isl_space
*range_space
= isl_space_set_alloc (ctx
, 0, 1);
3030 isl_space_set_tuple_name (range_space
, isl_dim_set
, "separate");
3031 isl_union_set
*range
=
3032 isl_union_set_from_set (isl_set_universe (range_space
));
3033 isl_union_set
*domain
= isl_union_map_range (isl_union_map_copy (schedule
));
3034 domain
= isl_union_set_universe (domain
);
3035 isl_union_map
*options
= isl_union_map_from_domain_and_range (domain
, range
);
3036 return isl_ast_build_set_options (control
, options
);
3039 /* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in IP. */
3041 __isl_give isl_ast_node
*translate_isl_ast_to_gimple::
3042 scop_to_isl_ast (scop_p scop
, ivs_params
&ip
)
3044 /* Generate loop upper bounds that consist of the current loop iterator, an
3045 operator (< or <=) and an expression not involving the iterator. If this
3046 option is not set, then the current loop iterator may appear several times
3047 in the upper bound. See the isl manual for more details. */
3048 isl_options_set_ast_build_atomic_upper_bound (scop
->isl_context
, true);
3050 add_parameters_to_ivs_params (scop
, ip
);
3051 isl_union_map
*schedule_isl
= generate_isl_schedule (scop
);
3052 isl_ast_build
*context_isl
= generate_isl_context (scop
);
3053 context_isl
= set_options (context_isl
, schedule_isl
);
3054 if (flag_loop_parallelize_all
)
3056 isl_union_map
*dependence
= scop_get_dependences (scop
);
3058 isl_ast_build_set_before_each_for (context_isl
, ast_build_before_for
,
3062 isl_ast_node
*ast_isl
= isl_ast_build_ast_from_schedule (context_isl
,
3066 isl_schedule_free (scop
->schedule
);
3067 scop
->schedule
= NULL
;
3070 isl_ast_build_free (context_isl
);
3075 /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
3076 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
3079 copy_def (tree tr
, gimple
*def_stmt
, sese_info_p region
, sese_info_p to_region
,
3080 gimple_stmt_iterator
*gsi
)
3082 if (!defined_in_sese_p (tr
, region
->region
))
3086 use_operand_p use_p
;
3087 FOR_EACH_SSA_USE_OPERAND (use_p
, def_stmt
, iter
, SSA_OP_USE
)
3089 tree use_tr
= USE_FROM_PTR (use_p
);
3091 /* Do not copy parameters that have been generated in the header of the
3093 if (region
->parameter_rename_map
->get(use_tr
))
3096 gimple
*def_of_use
= SSA_NAME_DEF_STMT (use_tr
);
3100 copy_def (use_tr
, def_of_use
, region
, to_region
, gsi
);
3103 gimple
*copy
= gimple_copy (def_stmt
);
3104 gsi_insert_after (gsi
, copy
, GSI_NEW_STMT
);
3106 /* Create new names for all the definitions created by COPY and
3107 add replacement mappings for each new name. */
3108 def_operand_p def_p
;
3109 ssa_op_iter op_iter
;
3110 FOR_EACH_SSA_DEF_OPERAND (def_p
, copy
, op_iter
, SSA_OP_ALL_DEFS
)
3112 tree old_name
= DEF_FROM_PTR (def_p
);
3113 tree new_name
= create_new_def_for (old_name
, copy
, def_p
);
3114 region
->parameter_rename_map
->put(old_name
, new_name
);
3121 copy_internal_parameters (sese_info_p region
, sese_info_p to_region
)
3123 /* For all the parameters which definitino is in the if_region->false_region,
3124 insert code on true_region (if_region->true_region->entry). */
3128 gimple_stmt_iterator gsi
= gsi_start_bb(to_region
->region
.entry
->dest
);
3130 FOR_EACH_VEC_ELT (region
->params
, i
, tr
)
3132 // If def is not in region.
3133 gimple
*def_stmt
= SSA_NAME_DEF_STMT (tr
);
3135 copy_def (tr
, def_stmt
, region
, to_region
, &gsi
);
3139 /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
3140 Return true if code generation succeeded. */
3143 graphite_regenerate_ast_isl (scop_p scop
)
3145 sese_info_p region
= scop
->scop_info
;
3146 translate_isl_ast_to_gimple
t (region
);
3148 ifsese if_region
= NULL
;
3149 isl_ast_node
*root_node
;
3152 timevar_push (TV_GRAPHITE_CODE_GEN
);
3153 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
3154 t
.add_parameters_to_ivs_params (scop
, ip
);
3155 root_node
= t
.scop_to_isl_ast (scop
);
3157 root_node
= t
.scop_to_isl_ast (scop
, ip
);
3160 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3162 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
3163 fprintf (dump_file
, "[scheduler] original schedule:\n");
3164 print_isl_schedule (dump_file
, scop
->original_schedule
);
3165 fprintf (dump_file
, "[scheduler] isl transformed schedule:\n");
3166 print_isl_schedule (dump_file
, scop
->transformed_schedule
);
3168 fprintf (dump_file
, "[scheduler] original ast:\n");
3169 print_schedule_ast (dump_file
, scop
->original_schedule
, scop
);
3171 fprintf (dump_file
, "[scheduler] AST generated by isl:\n");
3172 print_isl_ast (dump_file
, root_node
);
3175 recompute_all_dominators ();
3178 if_region
= move_sese_in_condition (region
);
3179 region
->if_region
= if_region
;
3180 recompute_all_dominators ();
3182 loop_p context_loop
= region
->region
.entry
->src
->loop_father
;
3184 /* Copy all the parameters which are defined in the region. */
3185 copy_internal_parameters(if_region
->false_region
, if_region
->true_region
);
3187 edge e
= single_succ_edge (if_region
->true_region
->region
.entry
->dest
);
3188 basic_block bb
= split_edge (e
);
3190 /* Update the true_region exit edge. */
3191 region
->if_region
->true_region
->region
.exit
= single_succ_edge (bb
);
3193 t
.translate_isl_ast (context_loop
, root_node
, e
, ip
);
3194 if (t
.codegen_error_p ())
3197 fprintf (dump_file
, "codegen error: "
3198 "reverting back to the original code.\n");
3199 set_ifsese_condition (if_region
, integer_zero_node
);
3203 t
.translate_pending_phi_nodes ();
3204 if (!t
.codegen_error_p ())
3206 sese_insert_phis_for_liveouts (region
,
3207 if_region
->region
->region
.exit
->src
,
3208 if_region
->false_region
->region
.exit
,
3209 if_region
->true_region
->region
.exit
);
3210 mark_virtual_operands_for_renaming (cfun
);
3211 update_ssa (TODO_update_ssa
);
3216 recompute_all_dominators ();
3220 fprintf (dump_file
, "[codegen] isl AST to Gimple succeeded.\n");
3225 fprintf (dump_file
, "[codegen] unsuccessful in translating"
3226 " pending phis, reverting back to the original code.\n");
3227 set_ifsese_condition (if_region
, integer_zero_node
);
3231 free (if_region
->true_region
);
3232 free (if_region
->region
);
3235 ivs_params_clear (ip
);
3236 isl_ast_node_free (root_node
);
3237 timevar_pop (TV_GRAPHITE_CODE_GEN
);
3239 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3242 int num_no_dependency
= 0;
3244 FOR_EACH_LOOP (loop
, 0)
3245 if (loop
->can_be_parallel
)
3246 num_no_dependency
++;
3248 fprintf (dump_file
, "%d loops carried no dependency.\n",
3252 return !t
.codegen_error_p ();
3255 #endif /* HAVE_isl */