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"
36 #include "fold-const.h"
37 #include "gimple-fold.h"
38 #include "gimple-iterator.h"
40 #include "gimplify-me.h"
42 #include "tree-ssa-loop.h"
43 #include "tree-ssa-operands.h"
44 #include "tree-ssa-propagate.h"
45 #include "tree-pass.h"
47 #include "tree-data-ref.h"
48 #include "tree-ssa-loop-manip.h"
49 #include "tree-scalar-evolution.h"
50 #include "gimple-ssa.h"
51 #include "tree-phinodes.h"
52 #include "tree-into-ssa.h"
53 #include "ssa-iterators.h"
55 #include "gimple-pretty-print.h"
57 #include "value-prof.h"
64 : is_parallelizable(false)
66 bool is_parallelizable
;
69 /* IVS_PARAMS maps isl's scattering and parameter identifiers
70 to corresponding trees. */
72 typedef std::map
<isl_id
*, tree
> ivs_params
;
74 /* Free all memory allocated for isl's identifiers. */
76 static void ivs_params_clear (ivs_params
&ip
)
78 std::map
<isl_id
*, tree
>::iterator it
;
79 for (it
= ip
.begin ();
80 it
!= ip
.end (); it
++)
82 isl_id_free (it
->first
);
86 /* Set the "separate" option for the schedule node. */
88 static isl_schedule_node
*
89 set_separate_option (__isl_take isl_schedule_node
*node
, void *user
)
94 if (isl_schedule_node_get_type (node
) != isl_schedule_node_band
)
97 /* Set the "separate" option unless it is set earlier to another option. */
98 if (isl_schedule_node_band_member_get_ast_loop_type (node
, 0)
99 == isl_ast_loop_default
)
100 return isl_schedule_node_band_member_set_ast_loop_type
101 (node
, 0, isl_ast_loop_separate
);
106 /* Print SCHEDULE under an AST form on file F. */
109 print_schedule_ast (FILE *f
, __isl_keep isl_schedule
*schedule
, scop_p scop
)
111 isl_set
*set
= isl_set_params (isl_set_copy (scop
->param_context
));
112 isl_ast_build
*context
= isl_ast_build_from_context (set
);
114 = isl_ast_build_node_from_schedule (context
, isl_schedule_copy (schedule
));
115 isl_ast_build_free (context
);
116 print_isl_ast (f
, ast
);
117 isl_ast_node_free (ast
);
121 debug_schedule_ast (__isl_keep isl_schedule
*s
, scop_p scop
)
123 print_schedule_ast (stderr
, s
, scop
);
134 class translate_isl_ast_to_gimple
137 translate_isl_ast_to_gimple (sese_info_p r
);
138 edge
translate_isl_ast (loop_p context_loop
, __isl_keep isl_ast_node
*node
,
139 edge next_e
, ivs_params
&ip
);
140 edge
translate_isl_ast_node_for (loop_p context_loop
,
141 __isl_keep isl_ast_node
*node
,
142 edge next_e
, ivs_params
&ip
);
143 edge
translate_isl_ast_for_loop (loop_p context_loop
,
144 __isl_keep isl_ast_node
*node_for
,
146 tree type
, tree lb
, tree ub
,
148 edge
translate_isl_ast_node_if (loop_p context_loop
,
149 __isl_keep isl_ast_node
*node
,
150 edge next_e
, ivs_params
&ip
);
151 edge
translate_isl_ast_node_user (__isl_keep isl_ast_node
*node
,
152 edge next_e
, ivs_params
&ip
);
153 edge
translate_isl_ast_node_block (loop_p context_loop
,
154 __isl_keep isl_ast_node
*node
,
155 edge next_e
, ivs_params
&ip
);
156 tree
unary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
158 tree
binary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
160 tree
ternary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
162 tree
nary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
,
164 tree
gcc_expression_from_isl_expression (tree type
,
165 __isl_take isl_ast_expr
*,
167 tree
gcc_expression_from_isl_ast_expr_id (tree type
,
168 __isl_keep isl_ast_expr
*expr_id
,
170 widest_int
widest_int_from_isl_expr_int (__isl_keep isl_ast_expr
*expr
);
171 tree
gcc_expression_from_isl_expr_int (tree type
,
172 __isl_take isl_ast_expr
*expr
);
173 tree
gcc_expression_from_isl_expr_op (tree type
,
174 __isl_take isl_ast_expr
*expr
,
176 struct loop
*graphite_create_new_loop (edge entry_edge
,
177 __isl_keep isl_ast_node
*node_for
,
178 loop_p outer
, tree type
,
179 tree lb
, tree ub
, ivs_params
&ip
);
180 edge
graphite_create_new_guard (edge entry_edge
,
181 __isl_take isl_ast_expr
*if_cond
,
183 void build_iv_mapping (vec
<tree
> iv_map
, gimple_poly_bb_p gbb
,
184 __isl_keep isl_ast_expr
*user_expr
, ivs_params
&ip
,
186 void add_parameters_to_ivs_params (scop_p scop
, ivs_params
&ip
);
187 __isl_give isl_ast_build
*generate_isl_context (scop_p scop
);
189 __isl_give isl_ast_node
* scop_to_isl_ast (scop_p scop
);
191 tree
get_rename_from_scev (tree old_name
, gimple_seq
*stmts
, loop_p loop
,
193 bool graphite_copy_stmts_from_block (basic_block bb
, basic_block new_bb
,
195 edge
copy_bb_and_scalar_dependences (basic_block bb
, edge next_e
,
197 void set_rename (tree old_name
, tree expr
);
198 void gsi_insert_earliest (gimple_seq seq
);
199 bool codegen_error_p () const { return codegen_error
; }
201 void set_codegen_error ()
203 codegen_error
= true;
204 gcc_assert (! flag_checking
205 || PARAM_VALUE (PARAM_GRAPHITE_ALLOW_CODEGEN_ERRORS
));
208 bool is_constant (tree op
) const
210 return TREE_CODE (op
) == INTEGER_CST
211 || TREE_CODE (op
) == REAL_CST
212 || TREE_CODE (op
) == COMPLEX_CST
213 || TREE_CODE (op
) == VECTOR_CST
;
217 /* The region to be translated. */
220 /* This flag is set when an error occurred during the translation of isl AST
224 /* A vector of all the edges at if_condition merge points. */
225 auto_vec
<edge
, 2> merge_points
;
227 tree graphite_expr_type
;
230 translate_isl_ast_to_gimple::translate_isl_ast_to_gimple (sese_info_p r
)
231 : region (r
), codegen_error (false)
233 /* We always try to use signed 128 bit types, but fall back to smaller types
234 in case a platform does not provide types of these sizes. In the future we
235 should use isl to derive the optimal type for each subexpression. */
236 int max_mode_int_precision
237 = GET_MODE_PRECISION (int_mode_for_size (MAX_FIXED_MODE_SIZE
, 0).require ());
238 int graphite_expr_type_precision
239 = 128 <= max_mode_int_precision
? 128 : max_mode_int_precision
;
241 = build_nonstandard_integer_type (graphite_expr_type_precision
, 0);
244 /* Return the tree variable that corresponds to the given isl ast identifier
245 expression (an isl_ast_expr of type isl_ast_expr_id).
247 FIXME: We should replace blind conversion of id's type with derivation
248 of the optimal type when we get the corresponding isl support. Blindly
249 converting type sizes may be problematic when we switch to smaller
252 tree
translate_isl_ast_to_gimple::
253 gcc_expression_from_isl_ast_expr_id (tree type
,
254 __isl_take isl_ast_expr
*expr_id
,
257 gcc_assert (isl_ast_expr_get_type (expr_id
) == isl_ast_expr_id
);
258 isl_id
*tmp_isl_id
= isl_ast_expr_get_id (expr_id
);
259 std::map
<isl_id
*, tree
>::iterator res
;
260 res
= ip
.find (tmp_isl_id
);
261 isl_id_free (tmp_isl_id
);
262 gcc_assert (res
!= ip
.end () &&
263 "Could not map isl_id to tree expression");
264 isl_ast_expr_free (expr_id
);
265 tree t
= res
->second
;
266 if (useless_type_conversion_p (type
, TREE_TYPE (t
)))
268 return fold_convert (type
, t
);
271 /* Converts an isl_ast_expr_int expression E to a widest_int.
272 Raises a code generation error when the constant doesn't fit. */
274 widest_int
translate_isl_ast_to_gimple::
275 widest_int_from_isl_expr_int (__isl_keep isl_ast_expr
*expr
)
277 gcc_assert (isl_ast_expr_get_type (expr
) == isl_ast_expr_int
);
278 isl_val
*val
= isl_ast_expr_get_val (expr
);
279 size_t n
= isl_val_n_abs_num_chunks (val
, sizeof (HOST_WIDE_INT
));
280 HOST_WIDE_INT
*chunks
= XALLOCAVEC (HOST_WIDE_INT
, n
);
281 if (n
> WIDE_INT_MAX_ELTS
282 || isl_val_get_abs_num_chunks (val
, sizeof (HOST_WIDE_INT
), chunks
) == -1)
285 set_codegen_error ();
288 widest_int wi
= widest_int::from_array (chunks
, n
, true);
289 if (isl_val_is_neg (val
))
295 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
296 type TYPE. Raises a code generation error when the constant doesn't fit. */
298 tree
translate_isl_ast_to_gimple::
299 gcc_expression_from_isl_expr_int (tree type
, __isl_take isl_ast_expr
*expr
)
301 widest_int wi
= widest_int_from_isl_expr_int (expr
);
302 isl_ast_expr_free (expr
);
303 if (codegen_error_p ())
305 if (wi::min_precision (wi
, TYPE_SIGN (type
)) > TYPE_PRECISION (type
))
307 set_codegen_error ();
310 return wide_int_to_tree (type
, wi
);
313 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
316 tree
translate_isl_ast_to_gimple::
317 binary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
, ivs_params
&ip
)
319 enum isl_ast_op_type expr_type
= isl_ast_expr_get_op_type (expr
);
320 isl_ast_expr
*arg_expr
= isl_ast_expr_get_op_arg (expr
, 0);
321 tree tree_lhs_expr
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
322 arg_expr
= isl_ast_expr_get_op_arg (expr
, 1);
323 isl_ast_expr_free (expr
);
325 /* From our constraint generation we may get modulo operations that
326 we cannot represent explicitely but that are no-ops for TYPE.
328 if (expr_type
== isl_ast_op_pdiv_r
329 && isl_ast_expr_get_type (arg_expr
) == isl_ast_expr_int
330 && (wi::exact_log2 (widest_int_from_isl_expr_int (arg_expr
))
331 >= TYPE_PRECISION (type
)))
333 isl_ast_expr_free (arg_expr
);
334 return tree_lhs_expr
;
337 tree tree_rhs_expr
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
338 if (codegen_error_p ())
344 return fold_build2 (PLUS_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
347 return fold_build2 (MINUS_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
350 return fold_build2 (MULT_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
353 return fold_build2 (EXACT_DIV_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
355 case isl_ast_op_pdiv_q
:
356 return fold_build2 (TRUNC_DIV_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
358 case isl_ast_op_zdiv_r
:
359 case isl_ast_op_pdiv_r
:
360 return fold_build2 (TRUNC_MOD_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
362 case isl_ast_op_fdiv_q
:
363 return fold_build2 (FLOOR_DIV_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
366 return fold_build2 (TRUTH_ANDIF_EXPR
, type
,
367 tree_lhs_expr
, tree_rhs_expr
);
370 return fold_build2 (TRUTH_ORIF_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
373 return fold_build2 (EQ_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
376 return fold_build2 (LE_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
379 return fold_build2 (LT_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
382 return fold_build2 (GE_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
385 return fold_build2 (GT_EXPR
, type
, tree_lhs_expr
, tree_rhs_expr
);
392 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
395 tree
translate_isl_ast_to_gimple::
396 ternary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
, ivs_params
&ip
)
398 enum isl_ast_op_type t
= isl_ast_expr_get_op_type (expr
);
399 gcc_assert (t
== isl_ast_op_cond
|| t
== isl_ast_op_select
);
400 isl_ast_expr
*arg_expr
= isl_ast_expr_get_op_arg (expr
, 0);
401 tree a
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
402 arg_expr
= isl_ast_expr_get_op_arg (expr
, 1);
403 tree b
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
404 arg_expr
= isl_ast_expr_get_op_arg (expr
, 2);
405 tree c
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
406 isl_ast_expr_free (expr
);
408 if (codegen_error_p ())
411 return fold_build3 (COND_EXPR
, type
, a
, b
, c
);
414 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
417 tree
translate_isl_ast_to_gimple::
418 unary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
, ivs_params
&ip
)
420 gcc_assert (isl_ast_expr_get_op_type (expr
) == isl_ast_op_minus
);
421 isl_ast_expr
*arg_expr
= isl_ast_expr_get_op_arg (expr
, 0);
422 tree tree_expr
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
423 isl_ast_expr_free (expr
);
424 return codegen_error_p () ? NULL_TREE
425 : fold_build1 (NEGATE_EXPR
, type
, tree_expr
);
428 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
429 to a GCC expression tree of type TYPE. */
431 tree
translate_isl_ast_to_gimple::
432 nary_op_to_tree (tree type
, __isl_take isl_ast_expr
*expr
, ivs_params
&ip
)
434 enum tree_code op_code
;
435 switch (isl_ast_expr_get_op_type (expr
))
448 isl_ast_expr
*arg_expr
= isl_ast_expr_get_op_arg (expr
, 0);
449 tree res
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
451 if (codegen_error_p ())
453 isl_ast_expr_free (expr
);
458 for (i
= 1; i
< isl_ast_expr_get_op_n_arg (expr
); i
++)
460 arg_expr
= isl_ast_expr_get_op_arg (expr
, i
);
461 tree t
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
463 if (codegen_error_p ())
465 isl_ast_expr_free (expr
);
469 res
= fold_build2 (op_code
, type
, res
, t
);
471 isl_ast_expr_free (expr
);
475 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
478 tree
translate_isl_ast_to_gimple::
479 gcc_expression_from_isl_expr_op (tree type
, __isl_take isl_ast_expr
*expr
,
482 if (codegen_error_p ())
484 isl_ast_expr_free (expr
);
488 gcc_assert (isl_ast_expr_get_type (expr
) == isl_ast_expr_op
);
489 switch (isl_ast_expr_get_op_type (expr
))
491 /* These isl ast expressions are not supported yet. */
492 case isl_ast_op_error
:
493 case isl_ast_op_call
:
494 case isl_ast_op_and_then
:
495 case isl_ast_op_or_else
:
500 return nary_op_to_tree (type
, expr
, ip
);
506 case isl_ast_op_pdiv_q
:
507 case isl_ast_op_pdiv_r
:
508 case isl_ast_op_fdiv_q
:
509 case isl_ast_op_zdiv_r
:
517 return binary_op_to_tree (type
, expr
, ip
);
519 case isl_ast_op_minus
:
520 return unary_op_to_tree (type
, expr
, ip
);
522 case isl_ast_op_cond
:
523 case isl_ast_op_select
:
524 return ternary_op_to_tree (type
, expr
, ip
);
533 /* Converts an isl AST expression E back to a GCC expression tree of
536 tree
translate_isl_ast_to_gimple::
537 gcc_expression_from_isl_expression (tree type
, __isl_take isl_ast_expr
*expr
,
540 if (codegen_error_p ())
542 isl_ast_expr_free (expr
);
546 switch (isl_ast_expr_get_type (expr
))
548 case isl_ast_expr_id
:
549 return gcc_expression_from_isl_ast_expr_id (type
, expr
, ip
);
551 case isl_ast_expr_int
:
552 return gcc_expression_from_isl_expr_int (type
, expr
);
554 case isl_ast_expr_op
:
555 return gcc_expression_from_isl_expr_op (type
, expr
, ip
);
564 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
565 induction variable for the new LOOP. New LOOP is attached to CFG
566 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
567 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
568 isl's scattering name to the induction variable created for the
569 loop of STMT. The new induction variable is inserted in the NEWIVS
570 vector and is of type TYPE. */
572 struct loop
*translate_isl_ast_to_gimple::
573 graphite_create_new_loop (edge entry_edge
, __isl_keep isl_ast_node
*node_for
,
574 loop_p outer
, tree type
, tree lb
, tree ub
,
577 isl_ast_expr
*for_inc
= isl_ast_node_for_get_inc (node_for
);
578 tree stride
= gcc_expression_from_isl_expression (type
, for_inc
, ip
);
580 /* To fail code generation, we generate wrong code until we discard it. */
581 if (codegen_error_p ())
582 stride
= integer_zero_node
;
584 tree ivvar
= create_tmp_var (type
, "graphite_IV");
585 tree iv
, iv_after_increment
;
586 loop_p loop
= create_empty_loop_on_edge
587 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
588 outer
? outer
: entry_edge
->src
->loop_father
);
590 isl_ast_expr
*for_iterator
= isl_ast_node_for_get_iterator (node_for
);
591 isl_id
*id
= isl_ast_expr_get_id (for_iterator
);
592 std::map
<isl_id
*, tree
>::iterator res
;
595 isl_id_free (res
->first
);
597 isl_ast_expr_free (for_iterator
);
601 /* Create the loop for a isl_ast_node_for.
603 - NEXT_E is the edge where new generated code should be attached. */
605 edge
translate_isl_ast_to_gimple::
606 translate_isl_ast_for_loop (loop_p context_loop
,
607 __isl_keep isl_ast_node
*node_for
, edge next_e
,
608 tree type
, tree lb
, tree ub
,
611 gcc_assert (isl_ast_node_get_type (node_for
) == isl_ast_node_for
);
612 struct loop
*loop
= graphite_create_new_loop (next_e
, node_for
, context_loop
,
614 edge last_e
= single_exit (loop
);
615 edge to_body
= single_succ_edge (loop
->header
);
616 basic_block after
= to_body
->dest
;
618 /* Translate the body of the loop. */
619 isl_ast_node
*for_body
= isl_ast_node_for_get_body (node_for
);
620 next_e
= translate_isl_ast (loop
, for_body
, to_body
, ip
);
621 isl_ast_node_free (for_body
);
623 /* Early return if we failed to translate loop body. */
624 if (!next_e
|| codegen_error_p ())
627 if (next_e
->dest
!= after
)
628 redirect_edge_succ_nodup (next_e
, after
);
629 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
631 if (flag_loop_parallelize_all
)
633 isl_id
*id
= isl_ast_node_get_annotation (node_for
);
635 ast_build_info
*for_info
= (ast_build_info
*) isl_id_get_user (id
);
636 loop
->can_be_parallel
= for_info
->is_parallelizable
;
644 /* We use this function to get the upper bound because of the form,
645 which is used by isl to represent loops:
647 for (iterator = init; cond; iterator += inc)
655 The loop condition is an arbitrary expression, which contains the
656 current loop iterator.
658 (e.g. iterator + 3 < B && C > iterator + A)
660 We have to know the upper bound of the iterator to generate a loop
661 in Gimple form. It can be obtained from the special representation
662 of the loop condition, which is generated by isl,
663 if the ast_build_atomic_upper_bound option is set. In this case,
664 isl generates a loop condition that consists of the current loop
665 iterator, + an operator (< or <=) and an expression not involving
666 the iterator, which is processed and returned by this function.
668 (e.g iterator <= upper-bound-expression-without-iterator) */
670 static __isl_give isl_ast_expr
*
671 get_upper_bound (__isl_keep isl_ast_node
*node_for
)
673 gcc_assert (isl_ast_node_get_type (node_for
) == isl_ast_node_for
);
674 isl_ast_expr
*for_cond
= isl_ast_node_for_get_cond (node_for
);
675 gcc_assert (isl_ast_expr_get_type (for_cond
) == isl_ast_expr_op
);
677 switch (isl_ast_expr_get_op_type (for_cond
))
680 res
= isl_ast_expr_get_op_arg (for_cond
, 1);
685 /* (iterator < ub) => (iterator <= ub - 1). */
687 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond
), 1);
688 isl_ast_expr
*ub
= isl_ast_expr_get_op_arg (for_cond
, 1);
689 res
= isl_ast_expr_sub (ub
, isl_ast_expr_from_val (one
));
696 isl_ast_expr_free (for_cond
);
700 /* Translates an isl_ast_node_for to Gimple. */
702 edge
translate_isl_ast_to_gimple::
703 translate_isl_ast_node_for (loop_p context_loop
, __isl_keep isl_ast_node
*node
,
704 edge next_e
, ivs_params
&ip
)
706 gcc_assert (isl_ast_node_get_type (node
) == isl_ast_node_for
);
707 tree type
= graphite_expr_type
;
709 isl_ast_expr
*for_init
= isl_ast_node_for_get_init (node
);
710 tree lb
= gcc_expression_from_isl_expression (type
, for_init
, ip
);
711 /* To fail code generation, we generate wrong code until we discard it. */
712 if (codegen_error_p ())
713 lb
= integer_zero_node
;
715 isl_ast_expr
*upper_bound
= get_upper_bound (node
);
716 tree ub
= gcc_expression_from_isl_expression (type
, upper_bound
, ip
);
717 /* To fail code generation, we generate wrong code until we discard it. */
718 if (codegen_error_p ())
719 ub
= integer_zero_node
;
721 edge last_e
= single_succ_edge (split_edge (next_e
));
722 translate_isl_ast_for_loop (context_loop
, node
, next_e
,
727 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
728 variables of the loops around GBB in SESE.
730 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
731 chrec, we could consider using a map<int, tree> that maps loop ids to the
732 corresponding tree expressions. */
734 void translate_isl_ast_to_gimple::
735 build_iv_mapping (vec
<tree
> iv_map
, gimple_poly_bb_p gbb
,
736 __isl_keep isl_ast_expr
*user_expr
, ivs_params
&ip
,
739 gcc_assert (isl_ast_expr_get_type (user_expr
) == isl_ast_expr_op
&&
740 isl_ast_expr_get_op_type (user_expr
) == isl_ast_op_call
);
742 isl_ast_expr
*arg_expr
;
743 for (i
= 1; i
< isl_ast_expr_get_op_n_arg (user_expr
); i
++)
745 arg_expr
= isl_ast_expr_get_op_arg (user_expr
, i
);
746 tree type
= graphite_expr_type
;
747 tree t
= gcc_expression_from_isl_expression (type
, arg_expr
, ip
);
749 /* To fail code generation, we generate wrong code until we discard it. */
750 if (codegen_error_p ())
751 t
= integer_zero_node
;
753 loop_p old_loop
= gbb_loop_at_index (gbb
, region
, i
- 1);
754 iv_map
[old_loop
->num
] = t
;
758 /* Translates an isl_ast_node_user to Gimple.
760 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
762 edge
translate_isl_ast_to_gimple::
763 translate_isl_ast_node_user (__isl_keep isl_ast_node
*node
,
764 edge next_e
, ivs_params
&ip
)
766 gcc_assert (isl_ast_node_get_type (node
) == isl_ast_node_user
);
768 isl_ast_expr
*user_expr
= isl_ast_node_user_get_expr (node
);
769 isl_ast_expr
*name_expr
= isl_ast_expr_get_op_arg (user_expr
, 0);
770 gcc_assert (isl_ast_expr_get_type (name_expr
) == isl_ast_expr_id
);
772 isl_id
*name_id
= isl_ast_expr_get_id (name_expr
);
773 poly_bb_p pbb
= (poly_bb_p
) isl_id_get_user (name_id
);
776 gimple_poly_bb_p gbb
= PBB_BLACK_BOX (pbb
);
778 isl_ast_expr_free (name_expr
);
779 isl_id_free (name_id
);
781 gcc_assert (GBB_BB (gbb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
) &&
782 "The entry block should not even appear within a scop");
784 const int nb_loops
= number_of_loops (cfun
);
786 iv_map
.create (nb_loops
);
787 iv_map
.safe_grow_cleared (nb_loops
);
789 build_iv_mapping (iv_map
, gbb
, user_expr
, ip
, pbb
->scop
->scop_info
->region
);
790 isl_ast_expr_free (user_expr
);
792 basic_block old_bb
= GBB_BB (gbb
);
796 "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
797 old_bb
->index
, next_e
->src
->index
, next_e
->dest
->index
);
798 print_loops_bb (dump_file
, GBB_BB (gbb
), 0, 3);
802 next_e
= copy_bb_and_scalar_dependences (old_bb
, next_e
, iv_map
);
806 if (codegen_error_p ())
811 fprintf (dump_file
, "[codegen] (after copy) new basic block\n");
812 print_loops_bb (dump_file
, next_e
->src
, 0, 3);
818 /* Translates an isl_ast_node_block to Gimple. */
820 edge
translate_isl_ast_to_gimple::
821 translate_isl_ast_node_block (loop_p context_loop
,
822 __isl_keep isl_ast_node
*node
,
823 edge next_e
, ivs_params
&ip
)
825 gcc_assert (isl_ast_node_get_type (node
) == isl_ast_node_block
);
826 isl_ast_node_list
*node_list
= isl_ast_node_block_get_children (node
);
828 for (i
= 0; i
< isl_ast_node_list_n_ast_node (node_list
); i
++)
830 isl_ast_node
*tmp_node
= isl_ast_node_list_get_ast_node (node_list
, i
);
831 next_e
= translate_isl_ast (context_loop
, tmp_node
, next_e
, ip
);
832 isl_ast_node_free (tmp_node
);
834 isl_ast_node_list_free (node_list
);
838 /* Creates a new if region corresponding to isl's cond. */
840 edge
translate_isl_ast_to_gimple::
841 graphite_create_new_guard (edge entry_edge
, __isl_take isl_ast_expr
*if_cond
,
844 tree type
= graphite_expr_type
;
845 tree cond_expr
= gcc_expression_from_isl_expression (type
, if_cond
, ip
);
847 /* To fail code generation, we generate wrong code until we discard it. */
848 if (codegen_error_p ())
849 cond_expr
= integer_zero_node
;
851 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
855 /* Translates an isl_ast_node_if to Gimple. */
857 edge
translate_isl_ast_to_gimple::
858 translate_isl_ast_node_if (loop_p context_loop
,
859 __isl_keep isl_ast_node
*node
,
860 edge next_e
, ivs_params
&ip
)
862 gcc_assert (isl_ast_node_get_type (node
) == isl_ast_node_if
);
863 isl_ast_expr
*if_cond
= isl_ast_node_if_get_cond (node
);
864 edge last_e
= graphite_create_new_guard (next_e
, if_cond
, ip
);
865 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
866 merge_points
.safe_push (last_e
);
868 isl_ast_node
*then_node
= isl_ast_node_if_get_then (node
);
869 translate_isl_ast (context_loop
, then_node
, true_e
, ip
);
870 isl_ast_node_free (then_node
);
872 edge false_e
= get_false_edge_from_guard_bb (next_e
->dest
);
873 isl_ast_node
*else_node
= isl_ast_node_if_get_else (node
);
874 if (isl_ast_node_get_type (else_node
) != isl_ast_node_error
)
875 translate_isl_ast (context_loop
, else_node
, false_e
, ip
);
877 isl_ast_node_free (else_node
);
881 /* Translates an isl AST node NODE to GCC representation in the
882 context of a SESE. */
884 edge
translate_isl_ast_to_gimple::
885 translate_isl_ast (loop_p context_loop
, __isl_keep isl_ast_node
*node
,
886 edge next_e
, ivs_params
&ip
)
888 if (codegen_error_p ())
891 switch (isl_ast_node_get_type (node
))
893 case isl_ast_node_error
:
896 case isl_ast_node_for
:
897 return translate_isl_ast_node_for (context_loop
, node
,
900 case isl_ast_node_if
:
901 return translate_isl_ast_node_if (context_loop
, node
,
904 case isl_ast_node_user
:
905 return translate_isl_ast_node_user (node
, next_e
, ip
);
907 case isl_ast_node_block
:
908 return translate_isl_ast_node_block (context_loop
, node
,
911 case isl_ast_node_mark
:
913 isl_ast_node
*n
= isl_ast_node_mark_get_node (node
);
914 edge e
= translate_isl_ast (context_loop
, n
, next_e
, ip
);
915 isl_ast_node_free (n
);
924 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
925 When OLD_NAME and EXPR are the same we assert. */
927 void translate_isl_ast_to_gimple::
928 set_rename (tree old_name
, tree expr
)
932 fprintf (dump_file
, "[codegen] setting rename: old_name = ");
933 print_generic_expr (dump_file
, old_name
);
934 fprintf (dump_file
, ", new decl = ");
935 print_generic_expr (dump_file
, expr
);
936 fprintf (dump_file
, "\n");
938 bool res
= region
->rename_map
->put (old_name
, expr
);
942 /* Return an iterator to the instructions comes last in the execution order.
943 Either GSI1 and GSI2 should belong to the same basic block or one of their
944 respective basic blocks should dominate the other. */
947 later_of_the_two (gimple_stmt_iterator gsi1
, gimple_stmt_iterator gsi2
)
949 basic_block bb1
= gsi_bb (gsi1
);
950 basic_block bb2
= gsi_bb (gsi2
);
952 /* Find the iterator which is the latest. */
955 gimple
*stmt1
= gsi_stmt (gsi1
);
956 gimple
*stmt2
= gsi_stmt (gsi2
);
958 if (stmt1
!= NULL
&& stmt2
!= NULL
)
960 bool is_phi1
= gimple_code (stmt1
) == GIMPLE_PHI
;
961 bool is_phi2
= gimple_code (stmt2
) == GIMPLE_PHI
;
963 if (is_phi1
!= is_phi2
)
964 return is_phi1
? gsi2
: gsi1
;
967 /* For empty basic blocks gsis point to the end of the sequence. Since
968 there is no operator== defined for gimple_stmt_iterator and for gsis
969 not pointing to a valid statement gsi_next would assert. */
970 gimple_stmt_iterator gsi
= gsi1
;
972 if (gsi_stmt (gsi
) == gsi_stmt (gsi2
))
975 } while (!gsi_end_p (gsi
));
980 /* Find the basic block closest to the basic block which defines stmt. */
981 if (dominated_by_p (CDI_DOMINATORS
, bb1
, bb2
))
984 gcc_assert (dominated_by_p (CDI_DOMINATORS
, bb2
, bb1
));
988 /* Insert each statement from SEQ at its earliest insertion p. */
990 void translate_isl_ast_to_gimple::
991 gsi_insert_earliest (gimple_seq seq
)
993 update_modified_stmts (seq
);
994 sese_l
&codegen_region
= region
->if_region
->true_region
->region
;
995 basic_block begin_bb
= get_entry_bb (codegen_region
);
997 /* Inserting the gimple statements in a vector because gimple_seq behave
998 in strage ways when inserting the stmts from it into different basic
999 blocks one at a time. */
1000 auto_vec
<gimple
*, 3> stmts
;
1001 for (gimple_stmt_iterator gsi
= gsi_start (seq
); !gsi_end_p (gsi
);
1003 stmts
.safe_push (gsi_stmt (gsi
));
1007 FOR_EACH_VEC_ELT (stmts
, i
, use_stmt
)
1009 gcc_assert (gimple_code (use_stmt
) != GIMPLE_PHI
);
1010 gimple_stmt_iterator gsi_def_stmt
= gsi_start_bb_nondebug (begin_bb
);
1012 use_operand_p use_p
;
1013 ssa_op_iter op_iter
;
1014 FOR_EACH_SSA_USE_OPERAND (use_p
, use_stmt
, op_iter
, SSA_OP_USE
)
1016 /* Iterator to the current def of use_p. For function parameters or
1017 anything where def is not found, insert at the beginning of the
1018 generated region. */
1019 gimple_stmt_iterator gsi_stmt
= gsi_def_stmt
;
1021 tree op
= USE_FROM_PTR (use_p
);
1022 gimple
*stmt
= SSA_NAME_DEF_STMT (op
);
1023 if (stmt
&& (gimple_code (stmt
) != GIMPLE_NOP
))
1024 gsi_stmt
= gsi_for_stmt (stmt
);
1026 /* For region parameters, insert at the beginning of the generated
1028 if (!bb_in_sese_p (gsi_bb (gsi_stmt
), codegen_region
))
1029 gsi_stmt
= gsi_def_stmt
;
1031 gsi_def_stmt
= later_of_the_two (gsi_stmt
, gsi_def_stmt
);
1034 if (!gsi_stmt (gsi_def_stmt
))
1036 gimple_stmt_iterator gsi
= gsi_after_labels (gsi_bb (gsi_def_stmt
));
1037 gsi_insert_before (&gsi
, use_stmt
, GSI_NEW_STMT
);
1039 else if (gimple_code (gsi_stmt (gsi_def_stmt
)) == GIMPLE_PHI
)
1041 gimple_stmt_iterator bsi
1042 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt
));
1043 /* Insert right after the PHI statements. */
1044 gsi_insert_before (&bsi
, use_stmt
, GSI_NEW_STMT
);
1047 gsi_insert_after (&gsi_def_stmt
, use_stmt
, GSI_NEW_STMT
);
1051 fprintf (dump_file
, "[codegen] inserting statement: ");
1052 print_gimple_stmt (dump_file
, use_stmt
, 0, TDF_VOPS
| TDF_MEMSYMS
);
1053 print_loops_bb (dump_file
, gimple_bb (use_stmt
), 0, 3);
1058 /* For ops which are scev_analyzeable, we can regenerate a new name from its
1059 scalar evolution around LOOP. */
1061 tree
translate_isl_ast_to_gimple::
1062 get_rename_from_scev (tree old_name
, gimple_seq
*stmts
, loop_p loop
,
1065 tree scev
= scalar_evolution_in_region (region
->region
, loop
, old_name
);
1067 /* At this point we should know the exact scev for each
1068 scalar SSA_NAME used in the scop: all the other scalar
1069 SSA_NAMEs should have been translated out of SSA using
1070 arrays with one element. */
1072 if (chrec_contains_undetermined (scev
))
1074 set_codegen_error ();
1075 return build_zero_cst (TREE_TYPE (old_name
));
1078 new_expr
= chrec_apply_map (scev
, iv_map
);
1080 /* The apply should produce an expression tree containing
1081 the uses of the new induction variables. We should be
1082 able to use new_expr instead of the old_name in the newly
1083 generated loop nest. */
1084 if (chrec_contains_undetermined (new_expr
)
1085 || tree_contains_chrecs (new_expr
, NULL
))
1087 set_codegen_error ();
1088 return build_zero_cst (TREE_TYPE (old_name
));
1091 /* Replace the old_name with the new_expr. */
1092 return force_gimple_operand (unshare_expr (new_expr
), stmts
,
1097 /* Return true if STMT should be copied from region to the new code-generated
1098 region. LABELs, CONDITIONS, induction-variables and region parameters need
1102 should_copy_to_new_region (gimple
*stmt
, sese_info_p region
)
1104 /* Do not copy labels or conditions. */
1105 if (gimple_code (stmt
) == GIMPLE_LABEL
1106 || gimple_code (stmt
) == GIMPLE_COND
)
1110 /* Do not copy induction variables. */
1111 if (is_gimple_assign (stmt
)
1112 && (lhs
= gimple_assign_lhs (stmt
))
1113 && TREE_CODE (lhs
) == SSA_NAME
1114 && is_gimple_reg (lhs
)
1115 && scev_analyzable_p (lhs
, region
->region
))
1121 /* Duplicates the statements of basic block BB into basic block NEW_BB
1122 and compute the new induction variables according to the IV_MAP. */
1124 bool translate_isl_ast_to_gimple::
1125 graphite_copy_stmts_from_block (basic_block bb
, basic_block new_bb
,
1128 /* Iterator poining to the place where new statement (s) will be inserted. */
1129 gimple_stmt_iterator gsi_tgt
= gsi_last_bb (new_bb
);
1131 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);
1134 gimple
*stmt
= gsi_stmt (gsi
);
1135 if (!should_copy_to_new_region (stmt
, region
))
1138 /* Create a new copy of STMT and duplicate STMT's virtual
1140 gimple
*copy
= gimple_copy (stmt
);
1141 gsi_insert_after (&gsi_tgt
, copy
, GSI_NEW_STMT
);
1143 /* Rather than not copying debug stmts we reset them.
1144 ??? Where we can rewrite uses without inserting new
1145 stmts we could simply do that. */
1146 if (is_gimple_debug (copy
))
1148 if (gimple_debug_bind_p (copy
))
1149 gimple_debug_bind_reset_value (copy
);
1150 else if (gimple_debug_source_bind_p (copy
))
1158 fprintf (dump_file
, "[codegen] inserting statement: ");
1159 print_gimple_stmt (dump_file
, copy
, 0);
1162 maybe_duplicate_eh_stmt (copy
, stmt
);
1163 gimple_duplicate_stmt_histograms (cfun
, copy
, cfun
, stmt
);
1165 /* Crete new names for each def in the copied stmt. */
1166 def_operand_p def_p
;
1167 ssa_op_iter op_iter
;
1168 FOR_EACH_SSA_DEF_OPERAND (def_p
, copy
, op_iter
, SSA_OP_ALL_DEFS
)
1170 tree old_name
= DEF_FROM_PTR (def_p
);
1171 create_new_def_for (old_name
, copy
, def_p
);
1174 if (codegen_error_p ())
1177 /* For each SCEV analyzable SSA_NAME, rename their usage. */
1179 use_operand_p use_p
;
1180 if (!is_gimple_debug (copy
))
1181 FOR_EACH_SSA_USE_OPERAND (use_p
, copy
, iter
, SSA_OP_USE
)
1183 tree old_name
= USE_FROM_PTR (use_p
);
1185 if (TREE_CODE (old_name
) != SSA_NAME
1186 || SSA_NAME_IS_DEFAULT_DEF (old_name
)
1187 || ! scev_analyzable_p (old_name
, region
->region
))
1190 gimple_seq stmts
= NULL
;
1191 tree new_name
= get_rename_from_scev (old_name
, &stmts
,
1192 bb
->loop_father
, iv_map
);
1193 if (! codegen_error_p ())
1194 gsi_insert_earliest (stmts
);
1195 replace_exp (use_p
, new_name
);
1205 /* Copies BB and includes in the copied BB all the statements that can
1206 be reached following the use-def chains from the memory accesses,
1207 and returns the next edge following this new block. */
1209 edge
translate_isl_ast_to_gimple::
1210 copy_bb_and_scalar_dependences (basic_block bb
, edge next_e
, vec
<tree
> iv_map
)
1212 basic_block new_bb
= split_edge (next_e
);
1213 gimple_stmt_iterator gsi_tgt
= gsi_last_bb (new_bb
);
1214 for (gphi_iterator psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);
1217 gphi
*phi
= psi
.phi ();
1218 tree res
= gimple_phi_result (phi
);
1219 if (virtual_operand_p (res
)
1220 || scev_analyzable_p (res
, region
->region
))
1224 tree
*rename
= region
->rename_map
->get (res
);
1227 new_phi_def
= create_tmp_reg (TREE_TYPE (res
));
1228 set_rename (res
, new_phi_def
);
1231 new_phi_def
= *rename
;
1233 gassign
*ass
= gimple_build_assign (NULL_TREE
, new_phi_def
);
1234 create_new_def_for (res
, ass
, NULL
);
1235 gsi_insert_after (&gsi_tgt
, ass
, GSI_NEW_STMT
);
1238 if (!graphite_copy_stmts_from_block (bb
, new_bb
, iv_map
))
1240 set_codegen_error ();
1244 /* Insert out-of SSA copies on the original BB outgoing edges. */
1245 gsi_tgt
= gsi_last_bb (new_bb
);
1246 basic_block bb_for_succs
= bb
;
1247 if (bb_for_succs
== bb_for_succs
->loop_father
->latch
1248 && bb_in_sese_p (bb_for_succs
, region
->region
)
1249 && sese_trivially_empty_bb_p (bb_for_succs
))
1250 bb_for_succs
= NULL
;
1251 while (bb_for_succs
)
1253 basic_block latch
= NULL
;
1256 FOR_EACH_EDGE (e
, ei
, bb_for_succs
->succs
)
1258 for (gphi_iterator psi
= gsi_start_phis (e
->dest
); !gsi_end_p (psi
);
1261 gphi
*phi
= psi
.phi ();
1262 tree res
= gimple_phi_result (phi
);
1263 if (virtual_operand_p (res
)
1264 || scev_analyzable_p (res
, region
->region
))
1268 tree
*rename
= region
->rename_map
->get (res
);
1271 new_phi_def
= create_tmp_reg (TREE_TYPE (res
));
1272 set_rename (res
, new_phi_def
);
1275 new_phi_def
= *rename
;
1277 tree arg
= PHI_ARG_DEF_FROM_EDGE (phi
, e
);
1278 if (TREE_CODE (arg
) == SSA_NAME
1279 && scev_analyzable_p (arg
, region
->region
))
1281 gimple_seq stmts
= NULL
;
1282 tree new_name
= get_rename_from_scev (arg
, &stmts
,
1285 if (! codegen_error_p ())
1286 gsi_insert_earliest (stmts
);
1289 gassign
*ass
= gimple_build_assign (new_phi_def
, arg
);
1290 gsi_insert_after (&gsi_tgt
, ass
, GSI_NEW_STMT
);
1292 if (e
->dest
== bb_for_succs
->loop_father
->latch
1293 && bb_in_sese_p (e
->dest
, region
->region
)
1294 && sese_trivially_empty_bb_p (e
->dest
))
1297 bb_for_succs
= latch
;
1300 return single_succ_edge (new_bb
);
1303 /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
1305 void translate_isl_ast_to_gimple::
1306 add_parameters_to_ivs_params (scop_p scop
, ivs_params
&ip
)
1308 sese_info_p region
= scop
->scop_info
;
1309 unsigned nb_parameters
= isl_set_dim (scop
->param_context
, isl_dim_param
);
1310 gcc_assert (nb_parameters
== sese_nb_params (region
));
1313 FOR_EACH_VEC_ELT (region
->params
, i
, param
)
1315 isl_id
*tmp_id
= isl_set_get_dim_id (scop
->param_context
,
1322 /* Generates a build, which specifies the constraints on the parameters. */
1324 __isl_give isl_ast_build
*translate_isl_ast_to_gimple::
1325 generate_isl_context (scop_p scop
)
1327 isl_set
*context_isl
= isl_set_params (isl_set_copy (scop
->param_context
));
1328 return isl_ast_build_from_context (context_isl
);
1331 /* This method is executed before the construction of a for node. */
1333 ast_build_before_for (__isl_keep isl_ast_build
*build
, void *user
)
1335 isl_union_map
*dependences
= (isl_union_map
*) user
;
1336 ast_build_info
*for_info
= XNEW (struct ast_build_info
);
1337 isl_union_map
*schedule
= isl_ast_build_get_schedule (build
);
1338 isl_space
*schedule_space
= isl_ast_build_get_schedule_space (build
);
1339 int dimension
= isl_space_dim (schedule_space
, isl_dim_out
);
1340 for_info
->is_parallelizable
=
1341 !carries_deps (schedule
, dependences
, dimension
);
1342 isl_union_map_free (schedule
);
1343 isl_space_free (schedule_space
);
1344 isl_id
*id
= isl_id_alloc (isl_ast_build_get_ctx (build
), "", for_info
);
1348 /* Generate isl AST from schedule of SCOP. */
1350 __isl_give isl_ast_node
*translate_isl_ast_to_gimple::
1351 scop_to_isl_ast (scop_p scop
)
1353 gcc_assert (scop
->transformed_schedule
);
1355 /* Set the separate option to reduce control flow overhead. */
1356 isl_schedule
*schedule
= isl_schedule_map_schedule_node_bottom_up
1357 (isl_schedule_copy (scop
->transformed_schedule
), set_separate_option
, NULL
);
1358 isl_ast_build
*context_isl
= generate_isl_context (scop
);
1360 if (flag_loop_parallelize_all
)
1362 scop_get_dependences (scop
);
1364 isl_ast_build_set_before_each_for (context_isl
, ast_build_before_for
,
1368 isl_ast_node
*ast_isl
= isl_ast_build_node_from_schedule
1369 (context_isl
, schedule
);
1370 isl_ast_build_free (context_isl
);
1374 /* Generate out-of-SSA copies for the entry edge FALSE_ENTRY/TRUE_ENTRY
1378 generate_entry_out_of_ssa_copies (edge false_entry
,
1382 gimple_stmt_iterator gsi_tgt
= gsi_start_bb (true_entry
->dest
);
1383 for (gphi_iterator psi
= gsi_start_phis (false_entry
->dest
);
1384 !gsi_end_p (psi
); gsi_next (&psi
))
1386 gphi
*phi
= psi
.phi ();
1387 tree res
= gimple_phi_result (phi
);
1388 if (virtual_operand_p (res
))
1390 /* When there's no out-of-SSA var registered do not bother
1392 tree
*rename
= region
->rename_map
->get (res
);
1395 tree new_phi_def
= *rename
;
1396 gassign
*ass
= gimple_build_assign (new_phi_def
,
1397 PHI_ARG_DEF_FROM_EDGE (phi
,
1399 gsi_insert_after (&gsi_tgt
, ass
, GSI_NEW_STMT
);
1403 /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
1404 Return true if code generation succeeded. */
1407 graphite_regenerate_ast_isl (scop_p scop
)
1409 sese_info_p region
= scop
->scop_info
;
1410 translate_isl_ast_to_gimple
t (region
);
1412 ifsese if_region
= NULL
;
1413 isl_ast_node
*root_node
;
1416 timevar_push (TV_GRAPHITE_CODE_GEN
);
1417 t
.add_parameters_to_ivs_params (scop
, ip
);
1418 root_node
= t
.scop_to_isl_ast (scop
);
1420 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1422 fprintf (dump_file
, "[scheduler] original schedule:\n");
1423 print_isl_schedule (dump_file
, scop
->original_schedule
);
1424 fprintf (dump_file
, "[scheduler] isl transformed schedule:\n");
1425 print_isl_schedule (dump_file
, scop
->transformed_schedule
);
1427 fprintf (dump_file
, "[scheduler] original ast:\n");
1428 print_schedule_ast (dump_file
, scop
->original_schedule
, scop
);
1429 fprintf (dump_file
, "[scheduler] AST generated by isl:\n");
1430 print_isl_ast (dump_file
, root_node
);
1433 if_region
= move_sese_in_condition (region
);
1434 region
->if_region
= if_region
;
1436 loop_p context_loop
= region
->region
.entry
->src
->loop_father
;
1437 edge e
= single_succ_edge (if_region
->true_region
->region
.entry
->dest
);
1438 basic_block bb
= split_edge (e
);
1440 /* Update the true_region exit edge. */
1441 region
->if_region
->true_region
->region
.exit
= single_succ_edge (bb
);
1443 t
.translate_isl_ast (context_loop
, root_node
, e
, ip
);
1444 if (! t
.codegen_error_p ())
1446 generate_entry_out_of_ssa_copies (if_region
->false_region
->region
.entry
,
1447 if_region
->true_region
->region
.entry
,
1449 sese_insert_phis_for_liveouts (region
,
1450 if_region
->region
->region
.exit
->src
,
1451 if_region
->false_region
->region
.exit
,
1452 if_region
->true_region
->region
.exit
);
1454 fprintf (dump_file
, "[codegen] isl AST to Gimple succeeded.\n");
1457 if (t
.codegen_error_p ())
1460 fprintf (dump_file
, "codegen error: "
1461 "reverting back to the original code.\n");
1462 set_ifsese_condition (if_region
, integer_zero_node
);
1464 /* Remove the unreachable region. */
1465 remove_edge_and_dominated_blocks (if_region
->true_region
->region
.entry
);
1466 basic_block ifb
= if_region
->false_region
->region
.entry
->src
;
1467 gimple_stmt_iterator gsi
= gsi_last_bb (ifb
);
1468 gsi_remove (&gsi
, true);
1469 if_region
->false_region
->region
.entry
->flags
&= ~EDGE_FALSE_VALUE
;
1470 if_region
->false_region
->region
.entry
->flags
|= EDGE_FALLTHRU
;
1471 /* remove_edge_and_dominated_blocks marks loops for removal but
1472 doesn't actually remove them (fix that...). */
1474 FOR_EACH_LOOP (loop
, LI_FROM_INNERMOST
)
1479 /* We are delaying SSA update to after code-generating all SCOPs.
1480 This is because we analyzed DRs and parameters on the unmodified
1481 IL and thus rely on SSA update to pick up new dominating definitions
1482 from for example SESE liveout PHIs. This is also for efficiency
1483 as SSA update does work depending on the size of the function. */
1485 free (if_region
->true_region
);
1486 free (if_region
->region
);
1489 ivs_params_clear (ip
);
1490 isl_ast_node_free (root_node
);
1491 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1493 return !t
.codegen_error_p ();
1496 #endif /* HAVE_isl */