graphite-isl-ast-to-gimple.cc revision 1.1 1 1.1 mrg /* Translation of isl AST to Gimple.
2 1.1 mrg Copyright (C) 2014-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Roman Gareev <gareevroman (at) gmail.com>.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify
8 1.1 mrg it under the terms of the GNU General Public License as published by
9 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
10 1.1 mrg any later version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful,
13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 mrg GNU General Public License for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg #define INCLUDE_ISL
22 1.1 mrg
23 1.1 mrg #include "config.h"
24 1.1 mrg
25 1.1 mrg #ifdef HAVE_isl
26 1.1 mrg
27 1.1 mrg #include "system.h"
28 1.1 mrg #include "coretypes.h"
29 1.1 mrg #include "backend.h"
30 1.1 mrg #include "cfghooks.h"
31 1.1 mrg #include "tree.h"
32 1.1 mrg #include "gimple.h"
33 1.1 mrg #include "ssa.h"
34 1.1 mrg #include "fold-const.h"
35 1.1 mrg #include "gimple-fold.h"
36 1.1 mrg #include "gimple-iterator.h"
37 1.1 mrg #include "gimplify.h"
38 1.1 mrg #include "gimplify-me.h"
39 1.1 mrg #include "tree-eh.h"
40 1.1 mrg #include "tree-ssa-loop.h"
41 1.1 mrg #include "tree-ssa-operands.h"
42 1.1 mrg #include "tree-ssa-propagate.h"
43 1.1 mrg #include "tree-pass.h"
44 1.1 mrg #include "cfgloop.h"
45 1.1 mrg #include "tree-data-ref.h"
46 1.1 mrg #include "tree-ssa-loop-manip.h"
47 1.1 mrg #include "tree-scalar-evolution.h"
48 1.1 mrg #include "gimple-ssa.h"
49 1.1 mrg #include "tree-phinodes.h"
50 1.1 mrg #include "tree-into-ssa.h"
51 1.1 mrg #include "ssa-iterators.h"
52 1.1 mrg #include "tree-cfg.h"
53 1.1 mrg #include "gimple-pretty-print.h"
54 1.1 mrg #include "cfganal.h"
55 1.1 mrg #include "value-prof.h"
56 1.1 mrg #include "tree-ssa.h"
57 1.1 mrg #include "tree-vectorizer.h"
58 1.1 mrg #include "graphite.h"
59 1.1 mrg
60 1.1 mrg struct ast_build_info
61 1.1 mrg {
62 1.1 mrg ast_build_info()
63 1.1 mrg : is_parallelizable(false)
64 1.1 mrg { }
65 1.1 mrg bool is_parallelizable;
66 1.1 mrg };
67 1.1 mrg
68 1.1 mrg /* IVS_PARAMS maps isl's scattering and parameter identifiers
69 1.1 mrg to corresponding trees. */
70 1.1 mrg
71 1.1 mrg typedef hash_map<isl_id *, tree> ivs_params;
72 1.1 mrg
73 1.1 mrg /* Free all memory allocated for isl's identifiers. */
74 1.1 mrg
75 1.1 mrg static void ivs_params_clear (ivs_params &ip)
76 1.1 mrg {
77 1.1 mrg for (auto it = ip.begin (); it != ip.end (); ++it)
78 1.1 mrg isl_id_free ((*it).first);
79 1.1 mrg }
80 1.1 mrg
81 1.1 mrg /* Set the "separate" option for the schedule node. */
82 1.1 mrg
83 1.1 mrg static isl_schedule_node *
84 1.1 mrg set_separate_option (__isl_take isl_schedule_node *node, void *user)
85 1.1 mrg {
86 1.1 mrg if (user)
87 1.1 mrg return node;
88 1.1 mrg
89 1.1 mrg if (isl_schedule_node_get_type (node) != isl_schedule_node_band)
90 1.1 mrg return node;
91 1.1 mrg
92 1.1 mrg /* Set the "separate" option unless it is set earlier to another option. */
93 1.1 mrg if (isl_schedule_node_band_member_get_ast_loop_type (node, 0)
94 1.1 mrg == isl_ast_loop_default)
95 1.1 mrg return isl_schedule_node_band_member_set_ast_loop_type
96 1.1 mrg (node, 0, isl_ast_loop_separate);
97 1.1 mrg
98 1.1 mrg return node;
99 1.1 mrg }
100 1.1 mrg
101 1.1 mrg /* Print SCHEDULE under an AST form on file F. */
102 1.1 mrg
103 1.1 mrg void
104 1.1 mrg print_schedule_ast (FILE *f, __isl_keep isl_schedule *schedule, scop_p scop)
105 1.1 mrg {
106 1.1 mrg isl_set *set = isl_set_params (isl_set_copy (scop->param_context));
107 1.1 mrg isl_ast_build *context = isl_ast_build_from_context (set);
108 1.1 mrg isl_ast_node *ast
109 1.1 mrg = isl_ast_build_node_from_schedule (context, isl_schedule_copy (schedule));
110 1.1 mrg isl_ast_build_free (context);
111 1.1 mrg print_isl_ast (f, ast);
112 1.1 mrg isl_ast_node_free (ast);
113 1.1 mrg }
114 1.1 mrg
115 1.1 mrg DEBUG_FUNCTION void
116 1.1 mrg debug_schedule_ast (__isl_keep isl_schedule *s, scop_p scop)
117 1.1 mrg {
118 1.1 mrg print_schedule_ast (stderr, s, scop);
119 1.1 mrg }
120 1.1 mrg
121 1.1 mrg enum phi_node_kind
122 1.1 mrg {
123 1.1 mrg unknown_phi,
124 1.1 mrg loop_phi,
125 1.1 mrg close_phi,
126 1.1 mrg cond_phi
127 1.1 mrg };
128 1.1 mrg
129 1.1 mrg class translate_isl_ast_to_gimple
130 1.1 mrg {
131 1.1 mrg public:
132 1.1 mrg translate_isl_ast_to_gimple (sese_info_p r);
133 1.1 mrg edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
134 1.1 mrg edge next_e, ivs_params &ip);
135 1.1 mrg edge translate_isl_ast_node_for (loop_p context_loop,
136 1.1 mrg __isl_keep isl_ast_node *node,
137 1.1 mrg edge next_e, ivs_params &ip);
138 1.1 mrg edge translate_isl_ast_for_loop (loop_p context_loop,
139 1.1 mrg __isl_keep isl_ast_node *node_for,
140 1.1 mrg edge next_e,
141 1.1 mrg tree type, tree lb, tree ub,
142 1.1 mrg ivs_params &ip);
143 1.1 mrg edge translate_isl_ast_node_if (loop_p context_loop,
144 1.1 mrg __isl_keep isl_ast_node *node,
145 1.1 mrg edge next_e, ivs_params &ip);
146 1.1 mrg edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
147 1.1 mrg edge next_e, ivs_params &ip);
148 1.1 mrg edge translate_isl_ast_node_block (loop_p context_loop,
149 1.1 mrg __isl_keep isl_ast_node *node,
150 1.1 mrg edge next_e, ivs_params &ip);
151 1.1 mrg tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
152 1.1 mrg ivs_params &ip);
153 1.1 mrg tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
154 1.1 mrg ivs_params &ip);
155 1.1 mrg tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
156 1.1 mrg ivs_params &ip);
157 1.1 mrg tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
158 1.1 mrg ivs_params &ip);
159 1.1 mrg tree gcc_expression_from_isl_expression (tree type,
160 1.1 mrg __isl_take isl_ast_expr *,
161 1.1 mrg ivs_params &ip);
162 1.1 mrg tree gcc_expression_from_isl_ast_expr_id (tree type,
163 1.1 mrg __isl_keep isl_ast_expr *expr_id,
164 1.1 mrg ivs_params &ip);
165 1.1 mrg widest_int widest_int_from_isl_expr_int (__isl_keep isl_ast_expr *expr);
166 1.1 mrg tree gcc_expression_from_isl_expr_int (tree type,
167 1.1 mrg __isl_take isl_ast_expr *expr);
168 1.1 mrg tree gcc_expression_from_isl_expr_op (tree type,
169 1.1 mrg __isl_take isl_ast_expr *expr,
170 1.1 mrg ivs_params &ip);
171 1.1 mrg struct loop *graphite_create_new_loop (edge entry_edge,
172 1.1 mrg __isl_keep isl_ast_node *node_for,
173 1.1 mrg loop_p outer, tree type,
174 1.1 mrg tree lb, tree ub, ivs_params &ip);
175 1.1 mrg edge graphite_create_new_guard (edge entry_edge,
176 1.1 mrg __isl_take isl_ast_expr *if_cond,
177 1.1 mrg ivs_params &ip);
178 1.1 mrg void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
179 1.1 mrg __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
180 1.1 mrg sese_l ®ion);
181 1.1 mrg void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
182 1.1 mrg __isl_give isl_ast_build *generate_isl_context (scop_p scop);
183 1.1 mrg
184 1.1 mrg __isl_give isl_ast_node * scop_to_isl_ast (scop_p scop);
185 1.1 mrg
186 1.1 mrg tree get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
187 1.1 mrg vec<tree> iv_map);
188 1.1 mrg void graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
189 1.1 mrg vec<tree> iv_map);
190 1.1 mrg edge copy_bb_and_scalar_dependences (basic_block bb, edge next_e,
191 1.1 mrg vec<tree> iv_map);
192 1.1 mrg void set_rename (tree old_name, tree expr);
193 1.1 mrg void gsi_insert_earliest (gimple_seq seq);
194 1.1 mrg bool codegen_error_p () const { return codegen_error; }
195 1.1 mrg
196 1.1 mrg void set_codegen_error ()
197 1.1 mrg {
198 1.1 mrg codegen_error = true;
199 1.1 mrg gcc_assert (! flag_checking
200 1.1 mrg || param_graphite_allow_codegen_errors);
201 1.1 mrg }
202 1.1 mrg
203 1.1 mrg bool is_constant (tree op) const
204 1.1 mrg {
205 1.1 mrg return TREE_CODE (op) == INTEGER_CST
206 1.1 mrg || TREE_CODE (op) == REAL_CST
207 1.1 mrg || TREE_CODE (op) == COMPLEX_CST
208 1.1 mrg || TREE_CODE (op) == VECTOR_CST;
209 1.1 mrg }
210 1.1 mrg
211 1.1 mrg private:
212 1.1 mrg /* The region to be translated. */
213 1.1 mrg sese_info_p region;
214 1.1 mrg
215 1.1 mrg /* This flag is set when an error occurred during the translation of isl AST
216 1.1 mrg to Gimple. */
217 1.1 mrg bool codegen_error;
218 1.1 mrg
219 1.1 mrg /* A vector of all the edges at if_condition merge points. */
220 1.1 mrg auto_vec<edge, 2> merge_points;
221 1.1 mrg
222 1.1 mrg tree graphite_expr_type;
223 1.1 mrg };
224 1.1 mrg
225 1.1 mrg translate_isl_ast_to_gimple::translate_isl_ast_to_gimple (sese_info_p r)
226 1.1 mrg : region (r), codegen_error (false)
227 1.1 mrg {
228 1.1 mrg /* We always try to use signed 128 bit types, but fall back to smaller types
229 1.1 mrg in case a platform does not provide types of these sizes. In the future we
230 1.1 mrg should use isl to derive the optimal type for each subexpression. */
231 1.1 mrg int max_mode_int_precision
232 1.1 mrg = GET_MODE_PRECISION (int_mode_for_size (MAX_FIXED_MODE_SIZE, 0).require ());
233 1.1 mrg int graphite_expr_type_precision
234 1.1 mrg = 128 <= max_mode_int_precision ? 128 : max_mode_int_precision;
235 1.1 mrg graphite_expr_type
236 1.1 mrg = build_nonstandard_integer_type (graphite_expr_type_precision, 0);
237 1.1 mrg }
238 1.1 mrg
239 1.1 mrg /* Return the tree variable that corresponds to the given isl ast identifier
240 1.1 mrg expression (an isl_ast_expr of type isl_ast_expr_id).
241 1.1 mrg
242 1.1 mrg FIXME: We should replace blind conversion of id's type with derivation
243 1.1 mrg of the optimal type when we get the corresponding isl support. Blindly
244 1.1 mrg converting type sizes may be problematic when we switch to smaller
245 1.1 mrg types. */
246 1.1 mrg
247 1.1 mrg tree translate_isl_ast_to_gimple::
248 1.1 mrg gcc_expression_from_isl_ast_expr_id (tree type,
249 1.1 mrg __isl_take isl_ast_expr *expr_id,
250 1.1 mrg ivs_params &ip)
251 1.1 mrg {
252 1.1 mrg gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
253 1.1 mrg isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
254 1.1 mrg tree *tp = ip.get (tmp_isl_id);
255 1.1 mrg isl_id_free (tmp_isl_id);
256 1.1 mrg gcc_assert (tp && "Could not map isl_id to tree expression");
257 1.1 mrg isl_ast_expr_free (expr_id);
258 1.1 mrg tree t = *tp;
259 1.1 mrg if (useless_type_conversion_p (type, TREE_TYPE (t)))
260 1.1 mrg return t;
261 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (t))
262 1.1 mrg && !POINTER_TYPE_P (type) && !ptrofftype_p (type))
263 1.1 mrg t = fold_convert (sizetype, t);
264 1.1 mrg return fold_convert (type, t);
265 1.1 mrg }
266 1.1 mrg
267 1.1 mrg /* Converts an isl_ast_expr_int expression E to a widest_int.
268 1.1 mrg Raises a code generation error when the constant doesn't fit. */
269 1.1 mrg
270 1.1 mrg widest_int translate_isl_ast_to_gimple::
271 1.1 mrg widest_int_from_isl_expr_int (__isl_keep isl_ast_expr *expr)
272 1.1 mrg {
273 1.1 mrg gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
274 1.1 mrg isl_val *val = isl_ast_expr_get_val (expr);
275 1.1 mrg size_t n = isl_val_n_abs_num_chunks (val, sizeof (HOST_WIDE_INT));
276 1.1 mrg HOST_WIDE_INT *chunks = XALLOCAVEC (HOST_WIDE_INT, n);
277 1.1 mrg if (n > WIDE_INT_MAX_ELTS
278 1.1 mrg || isl_val_get_abs_num_chunks (val, sizeof (HOST_WIDE_INT), chunks) == -1)
279 1.1 mrg {
280 1.1 mrg isl_val_free (val);
281 1.1 mrg set_codegen_error ();
282 1.1 mrg return 0;
283 1.1 mrg }
284 1.1 mrg widest_int wi = widest_int::from_array (chunks, n, true);
285 1.1 mrg if (isl_val_is_neg (val))
286 1.1 mrg wi = -wi;
287 1.1 mrg isl_val_free (val);
288 1.1 mrg return wi;
289 1.1 mrg }
290 1.1 mrg
291 1.1 mrg /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
292 1.1 mrg type TYPE. Raises a code generation error when the constant doesn't fit. */
293 1.1 mrg
294 1.1 mrg tree translate_isl_ast_to_gimple::
295 1.1 mrg gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
296 1.1 mrg {
297 1.1 mrg widest_int wi = widest_int_from_isl_expr_int (expr);
298 1.1 mrg isl_ast_expr_free (expr);
299 1.1 mrg if (codegen_error_p ())
300 1.1 mrg return NULL_TREE;
301 1.1 mrg if (wi::min_precision (wi, TYPE_SIGN (type)) > TYPE_PRECISION (type))
302 1.1 mrg {
303 1.1 mrg set_codegen_error ();
304 1.1 mrg return NULL_TREE;
305 1.1 mrg }
306 1.1 mrg return wide_int_to_tree (type, wi);
307 1.1 mrg }
308 1.1 mrg
309 1.1 mrg /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
310 1.1 mrg type TYPE. */
311 1.1 mrg
312 1.1 mrg tree translate_isl_ast_to_gimple::
313 1.1 mrg binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
314 1.1 mrg {
315 1.1 mrg enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
316 1.1 mrg isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
317 1.1 mrg tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
318 1.1 mrg arg_expr = isl_ast_expr_get_op_arg (expr, 1);
319 1.1 mrg isl_ast_expr_free (expr);
320 1.1 mrg
321 1.1 mrg /* From our constraint generation we may get modulo operations that
322 1.1 mrg we cannot represent explicitely but that are no-ops for TYPE.
323 1.1 mrg Elide those. */
324 1.1 mrg if ((expr_type == isl_ast_op_pdiv_r
325 1.1 mrg || expr_type == isl_ast_op_zdiv_r
326 1.1 mrg || expr_type == isl_ast_op_add)
327 1.1 mrg && isl_ast_expr_get_type (arg_expr) == isl_ast_expr_int
328 1.1 mrg && (wi::exact_log2 (widest_int_from_isl_expr_int (arg_expr))
329 1.1 mrg >= TYPE_PRECISION (type)))
330 1.1 mrg {
331 1.1 mrg isl_ast_expr_free (arg_expr);
332 1.1 mrg return tree_lhs_expr;
333 1.1 mrg }
334 1.1 mrg
335 1.1 mrg tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
336 1.1 mrg if (codegen_error_p ())
337 1.1 mrg return NULL_TREE;
338 1.1 mrg
339 1.1 mrg switch (expr_type)
340 1.1 mrg {
341 1.1 mrg case isl_ast_op_add:
342 1.1 mrg return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
343 1.1 mrg
344 1.1 mrg case isl_ast_op_sub:
345 1.1 mrg return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
346 1.1 mrg
347 1.1 mrg case isl_ast_op_mul:
348 1.1 mrg return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
349 1.1 mrg
350 1.1 mrg case isl_ast_op_div:
351 1.1 mrg return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
352 1.1 mrg
353 1.1 mrg case isl_ast_op_pdiv_q:
354 1.1 mrg return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
355 1.1 mrg
356 1.1 mrg case isl_ast_op_zdiv_r:
357 1.1 mrg case isl_ast_op_pdiv_r:
358 1.1 mrg return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
359 1.1 mrg
360 1.1 mrg case isl_ast_op_fdiv_q:
361 1.1 mrg return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
362 1.1 mrg
363 1.1 mrg case isl_ast_op_and:
364 1.1 mrg return fold_build2 (TRUTH_ANDIF_EXPR, type,
365 1.1 mrg tree_lhs_expr, tree_rhs_expr);
366 1.1 mrg
367 1.1 mrg case isl_ast_op_or:
368 1.1 mrg return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);
369 1.1 mrg
370 1.1 mrg case isl_ast_op_eq:
371 1.1 mrg return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);
372 1.1 mrg
373 1.1 mrg case isl_ast_op_le:
374 1.1 mrg return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
375 1.1 mrg
376 1.1 mrg case isl_ast_op_lt:
377 1.1 mrg return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
378 1.1 mrg
379 1.1 mrg case isl_ast_op_ge:
380 1.1 mrg return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
381 1.1 mrg
382 1.1 mrg case isl_ast_op_gt:
383 1.1 mrg return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
384 1.1 mrg
385 1.1 mrg default:
386 1.1 mrg gcc_unreachable ();
387 1.1 mrg }
388 1.1 mrg }
389 1.1 mrg
390 1.1 mrg /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
391 1.1 mrg type TYPE. */
392 1.1 mrg
393 1.1 mrg tree translate_isl_ast_to_gimple::
394 1.1 mrg ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
395 1.1 mrg {
396 1.1 mrg enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr);
397 1.1 mrg gcc_assert (t == isl_ast_op_cond || t == isl_ast_op_select);
398 1.1 mrg isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
399 1.1 mrg tree a = gcc_expression_from_isl_expression (type, arg_expr, ip);
400 1.1 mrg arg_expr = isl_ast_expr_get_op_arg (expr, 1);
401 1.1 mrg tree b = gcc_expression_from_isl_expression (type, arg_expr, ip);
402 1.1 mrg arg_expr = isl_ast_expr_get_op_arg (expr, 2);
403 1.1 mrg tree c = gcc_expression_from_isl_expression (type, arg_expr, ip);
404 1.1 mrg isl_ast_expr_free (expr);
405 1.1 mrg
406 1.1 mrg if (codegen_error_p ())
407 1.1 mrg return NULL_TREE;
408 1.1 mrg
409 1.1 mrg return fold_build3 (COND_EXPR, type, a,
410 1.1 mrg rewrite_to_non_trapping_overflow (b),
411 1.1 mrg rewrite_to_non_trapping_overflow (c));
412 1.1 mrg }
413 1.1 mrg
414 1.1 mrg /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
415 1.1 mrg type TYPE. */
416 1.1 mrg
417 1.1 mrg tree translate_isl_ast_to_gimple::
418 1.1 mrg unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
419 1.1 mrg {
420 1.1 mrg gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
421 1.1 mrg isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
422 1.1 mrg tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
423 1.1 mrg isl_ast_expr_free (expr);
424 1.1 mrg return codegen_error_p () ? NULL_TREE
425 1.1 mrg : fold_build1 (NEGATE_EXPR, type, tree_expr);
426 1.1 mrg }
427 1.1 mrg
428 1.1 mrg /* Converts an isl_ast_expr_op expression E with unknown number of arguments
429 1.1 mrg to a GCC expression tree of type TYPE. */
430 1.1 mrg
431 1.1 mrg tree translate_isl_ast_to_gimple::
432 1.1 mrg nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
433 1.1 mrg {
434 1.1 mrg enum tree_code op_code;
435 1.1 mrg switch (isl_ast_expr_get_op_type (expr))
436 1.1 mrg {
437 1.1 mrg case isl_ast_op_max:
438 1.1 mrg op_code = MAX_EXPR;
439 1.1 mrg break;
440 1.1 mrg
441 1.1 mrg case isl_ast_op_min:
442 1.1 mrg op_code = MIN_EXPR;
443 1.1 mrg break;
444 1.1 mrg
445 1.1 mrg default:
446 1.1 mrg gcc_unreachable ();
447 1.1 mrg }
448 1.1 mrg isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
449 1.1 mrg tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);
450 1.1 mrg
451 1.1 mrg if (codegen_error_p ())
452 1.1 mrg {
453 1.1 mrg isl_ast_expr_free (expr);
454 1.1 mrg return NULL_TREE;
455 1.1 mrg }
456 1.1 mrg
457 1.1 mrg int i;
458 1.1 mrg for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
459 1.1 mrg {
460 1.1 mrg arg_expr = isl_ast_expr_get_op_arg (expr, i);
461 1.1 mrg tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
462 1.1 mrg
463 1.1 mrg if (codegen_error_p ())
464 1.1 mrg {
465 1.1 mrg isl_ast_expr_free (expr);
466 1.1 mrg return NULL_TREE;
467 1.1 mrg }
468 1.1 mrg
469 1.1 mrg res = fold_build2 (op_code, type, res, t);
470 1.1 mrg }
471 1.1 mrg isl_ast_expr_free (expr);
472 1.1 mrg return res;
473 1.1 mrg }
474 1.1 mrg
475 1.1 mrg /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
476 1.1 mrg type TYPE. */
477 1.1 mrg
478 1.1 mrg tree translate_isl_ast_to_gimple::
479 1.1 mrg gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
480 1.1 mrg ivs_params &ip)
481 1.1 mrg {
482 1.1 mrg if (codegen_error_p ())
483 1.1 mrg {
484 1.1 mrg isl_ast_expr_free (expr);
485 1.1 mrg return NULL_TREE;
486 1.1 mrg }
487 1.1 mrg
488 1.1 mrg gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
489 1.1 mrg switch (isl_ast_expr_get_op_type (expr))
490 1.1 mrg {
491 1.1 mrg /* These isl ast expressions are not supported yet. */
492 1.1 mrg case isl_ast_op_error:
493 1.1 mrg case isl_ast_op_call:
494 1.1 mrg case isl_ast_op_and_then:
495 1.1 mrg case isl_ast_op_or_else:
496 1.1 mrg gcc_unreachable ();
497 1.1 mrg
498 1.1 mrg case isl_ast_op_max:
499 1.1 mrg case isl_ast_op_min:
500 1.1 mrg return nary_op_to_tree (type, expr, ip);
501 1.1 mrg
502 1.1 mrg case isl_ast_op_add:
503 1.1 mrg case isl_ast_op_sub:
504 1.1 mrg case isl_ast_op_mul:
505 1.1 mrg case isl_ast_op_div:
506 1.1 mrg case isl_ast_op_pdiv_q:
507 1.1 mrg case isl_ast_op_pdiv_r:
508 1.1 mrg case isl_ast_op_fdiv_q:
509 1.1 mrg case isl_ast_op_zdiv_r:
510 1.1 mrg case isl_ast_op_and:
511 1.1 mrg case isl_ast_op_or:
512 1.1 mrg case isl_ast_op_eq:
513 1.1 mrg case isl_ast_op_le:
514 1.1 mrg case isl_ast_op_lt:
515 1.1 mrg case isl_ast_op_ge:
516 1.1 mrg case isl_ast_op_gt:
517 1.1 mrg return binary_op_to_tree (type, expr, ip);
518 1.1 mrg
519 1.1 mrg case isl_ast_op_minus:
520 1.1 mrg return unary_op_to_tree (type, expr, ip);
521 1.1 mrg
522 1.1 mrg case isl_ast_op_cond:
523 1.1 mrg case isl_ast_op_select:
524 1.1 mrg return ternary_op_to_tree (type, expr, ip);
525 1.1 mrg
526 1.1 mrg default:
527 1.1 mrg gcc_unreachable ();
528 1.1 mrg }
529 1.1 mrg }
530 1.1 mrg
531 1.1 mrg /* Converts an isl AST expression E back to a GCC expression tree of
532 1.1 mrg type TYPE. */
533 1.1 mrg
534 1.1 mrg tree translate_isl_ast_to_gimple::
535 1.1 mrg gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
536 1.1 mrg ivs_params &ip)
537 1.1 mrg {
538 1.1 mrg if (codegen_error_p ())
539 1.1 mrg {
540 1.1 mrg isl_ast_expr_free (expr);
541 1.1 mrg return NULL_TREE;
542 1.1 mrg }
543 1.1 mrg
544 1.1 mrg switch (isl_ast_expr_get_type (expr))
545 1.1 mrg {
546 1.1 mrg case isl_ast_expr_id:
547 1.1 mrg return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
548 1.1 mrg
549 1.1 mrg case isl_ast_expr_int:
550 1.1 mrg return gcc_expression_from_isl_expr_int (type, expr);
551 1.1 mrg
552 1.1 mrg case isl_ast_expr_op:
553 1.1 mrg return gcc_expression_from_isl_expr_op (type, expr, ip);
554 1.1 mrg
555 1.1 mrg default:
556 1.1 mrg gcc_unreachable ();
557 1.1 mrg }
558 1.1 mrg }
559 1.1 mrg
560 1.1 mrg /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
561 1.1 mrg induction variable for the new LOOP. New LOOP is attached to CFG
562 1.1 mrg starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
563 1.1 mrg becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
564 1.1 mrg isl's scattering name to the induction variable created for the
565 1.1 mrg loop of STMT. The new induction variable is inserted in the NEWIVS
566 1.1 mrg vector and is of type TYPE. */
567 1.1 mrg
568 1.1 mrg struct loop *translate_isl_ast_to_gimple::
569 1.1 mrg graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
570 1.1 mrg loop_p outer, tree type, tree lb, tree ub,
571 1.1 mrg ivs_params &ip)
572 1.1 mrg {
573 1.1 mrg isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
574 1.1 mrg tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
575 1.1 mrg
576 1.1 mrg /* To fail code generation, we generate wrong code until we discard it. */
577 1.1 mrg if (codegen_error_p ())
578 1.1 mrg stride = integer_zero_node;
579 1.1 mrg
580 1.1 mrg tree ivvar = create_tmp_var (type, "graphite_IV");
581 1.1 mrg tree iv, iv_after_increment;
582 1.1 mrg loop_p loop = create_empty_loop_on_edge
583 1.1 mrg (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
584 1.1 mrg outer ? outer : entry_edge->src->loop_father);
585 1.1 mrg
586 1.1 mrg isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
587 1.1 mrg isl_id *id = isl_ast_expr_get_id (for_iterator);
588 1.1 mrg bool existed_p = ip.put (id, iv);
589 1.1 mrg if (existed_p)
590 1.1 mrg isl_id_free (id);
591 1.1 mrg isl_ast_expr_free (for_iterator);
592 1.1 mrg return loop;
593 1.1 mrg }
594 1.1 mrg
595 1.1 mrg /* Create the loop for a isl_ast_node_for.
596 1.1 mrg
597 1.1 mrg - NEXT_E is the edge where new generated code should be attached. */
598 1.1 mrg
599 1.1 mrg edge translate_isl_ast_to_gimple::
600 1.1 mrg translate_isl_ast_for_loop (loop_p context_loop,
601 1.1 mrg __isl_keep isl_ast_node *node_for, edge next_e,
602 1.1 mrg tree type, tree lb, tree ub,
603 1.1 mrg ivs_params &ip)
604 1.1 mrg {
605 1.1 mrg gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
606 1.1 mrg struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
607 1.1 mrg type, lb, ub, ip);
608 1.1 mrg edge last_e = single_exit (loop);
609 1.1 mrg edge to_body = single_succ_edge (loop->header);
610 1.1 mrg basic_block after = to_body->dest;
611 1.1 mrg
612 1.1 mrg /* Translate the body of the loop. */
613 1.1 mrg isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
614 1.1 mrg next_e = translate_isl_ast (loop, for_body, to_body, ip);
615 1.1 mrg isl_ast_node_free (for_body);
616 1.1 mrg
617 1.1 mrg /* Early return if we failed to translate loop body. */
618 1.1 mrg if (!next_e || codegen_error_p ())
619 1.1 mrg return NULL;
620 1.1 mrg
621 1.1 mrg if (next_e->dest != after)
622 1.1 mrg redirect_edge_succ_nodup (next_e, after);
623 1.1 mrg set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
624 1.1 mrg
625 1.1 mrg if (flag_loop_parallelize_all)
626 1.1 mrg {
627 1.1 mrg isl_id *id = isl_ast_node_get_annotation (node_for);
628 1.1 mrg gcc_assert (id);
629 1.1 mrg ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
630 1.1 mrg loop->can_be_parallel = for_info->is_parallelizable;
631 1.1 mrg free (for_info);
632 1.1 mrg isl_id_free (id);
633 1.1 mrg }
634 1.1 mrg
635 1.1 mrg return last_e;
636 1.1 mrg }
637 1.1 mrg
638 1.1 mrg /* We use this function to get the upper bound because of the form,
639 1.1 mrg which is used by isl to represent loops:
640 1.1 mrg
641 1.1 mrg for (iterator = init; cond; iterator += inc)
642 1.1 mrg
643 1.1 mrg {
644 1.1 mrg
645 1.1 mrg ...
646 1.1 mrg
647 1.1 mrg }
648 1.1 mrg
649 1.1 mrg The loop condition is an arbitrary expression, which contains the
650 1.1 mrg current loop iterator.
651 1.1 mrg
652 1.1 mrg (e.g. iterator + 3 < B && C > iterator + A)
653 1.1 mrg
654 1.1 mrg We have to know the upper bound of the iterator to generate a loop
655 1.1 mrg in Gimple form. It can be obtained from the special representation
656 1.1 mrg of the loop condition, which is generated by isl,
657 1.1 mrg if the ast_build_atomic_upper_bound option is set. In this case,
658 1.1 mrg isl generates a loop condition that consists of the current loop
659 1.1 mrg iterator, + an operator (< or <=) and an expression not involving
660 1.1 mrg the iterator, which is processed and returned by this function.
661 1.1 mrg
662 1.1 mrg (e.g iterator <= upper-bound-expression-without-iterator) */
663 1.1 mrg
664 1.1 mrg static __isl_give isl_ast_expr *
665 1.1 mrg get_upper_bound (__isl_keep isl_ast_node *node_for)
666 1.1 mrg {
667 1.1 mrg gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
668 1.1 mrg isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
669 1.1 mrg gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
670 1.1 mrg isl_ast_expr *res;
671 1.1 mrg switch (isl_ast_expr_get_op_type (for_cond))
672 1.1 mrg {
673 1.1 mrg case isl_ast_op_le:
674 1.1 mrg res = isl_ast_expr_get_op_arg (for_cond, 1);
675 1.1 mrg break;
676 1.1 mrg
677 1.1 mrg case isl_ast_op_lt:
678 1.1 mrg {
679 1.1 mrg /* (iterator < ub) => (iterator <= ub - 1). */
680 1.1 mrg isl_val *one =
681 1.1 mrg isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
682 1.1 mrg isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
683 1.1 mrg res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
684 1.1 mrg break;
685 1.1 mrg }
686 1.1 mrg
687 1.1 mrg default:
688 1.1 mrg gcc_unreachable ();
689 1.1 mrg }
690 1.1 mrg isl_ast_expr_free (for_cond);
691 1.1 mrg return res;
692 1.1 mrg }
693 1.1 mrg
694 1.1 mrg /* Translates an isl_ast_node_for to Gimple. */
695 1.1 mrg
696 1.1 mrg edge translate_isl_ast_to_gimple::
697 1.1 mrg translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
698 1.1 mrg edge next_e, ivs_params &ip)
699 1.1 mrg {
700 1.1 mrg gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
701 1.1 mrg tree type = graphite_expr_type;
702 1.1 mrg
703 1.1 mrg isl_ast_expr *for_init = isl_ast_node_for_get_init (node);
704 1.1 mrg tree lb = gcc_expression_from_isl_expression (type, for_init, ip);
705 1.1 mrg /* To fail code generation, we generate wrong code until we discard it. */
706 1.1 mrg if (codegen_error_p ())
707 1.1 mrg lb = integer_zero_node;
708 1.1 mrg
709 1.1 mrg isl_ast_expr *upper_bound = get_upper_bound (node);
710 1.1 mrg tree ub = gcc_expression_from_isl_expression (type, upper_bound, ip);
711 1.1 mrg /* To fail code generation, we generate wrong code until we discard it. */
712 1.1 mrg if (codegen_error_p ())
713 1.1 mrg ub = integer_zero_node;
714 1.1 mrg
715 1.1 mrg edge last_e = single_succ_edge (split_edge (next_e));
716 1.1 mrg
717 1.1 mrg /* Compensate for the fact that we emit a do { } while loop from
718 1.1 mrg a for ISL AST.
719 1.1 mrg ??? We often miss constraints on niter because the SESE region
720 1.1 mrg doesn't cover loop header copies. Ideally we'd add constraints
721 1.1 mrg for all relevant dominating conditions. */
722 1.1 mrg if (TREE_CODE (lb) == INTEGER_CST && TREE_CODE (ub) == INTEGER_CST
723 1.1 mrg && tree_int_cst_compare (lb, ub) <= 0)
724 1.1 mrg ;
725 1.1 mrg else
726 1.1 mrg {
727 1.1 mrg tree one = build_one_cst (POINTER_TYPE_P (type) ? sizetype : type);
728 1.1 mrg /* Adding +1 and using LT_EXPR helps with loop latches that have a
729 1.1 mrg loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this
730 1.1 mrg becomes 2^k-1 due to integer overflow, and the condition lb <= ub
731 1.1 mrg is true, even if we do not want this. However lb < ub + 1 is false,
732 1.1 mrg as expected. */
733 1.1 mrg tree ub_one = fold_build2 (POINTER_TYPE_P (type)
734 1.1 mrg ? POINTER_PLUS_EXPR : PLUS_EXPR,
735 1.1 mrg type, unshare_expr (ub), one);
736 1.1 mrg create_empty_if_region_on_edge (next_e,
737 1.1 mrg fold_build2 (LT_EXPR, boolean_type_node,
738 1.1 mrg unshare_expr (lb), ub_one));
739 1.1 mrg next_e = get_true_edge_from_guard_bb (next_e->dest);
740 1.1 mrg }
741 1.1 mrg
742 1.1 mrg translate_isl_ast_for_loop (context_loop, node, next_e,
743 1.1 mrg type, lb, ub, ip);
744 1.1 mrg return last_e;
745 1.1 mrg }
746 1.1 mrg
747 1.1 mrg /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
748 1.1 mrg variables of the loops around GBB in SESE.
749 1.1 mrg
750 1.1 mrg FIXME: Instead of using a vec<tree> that maps each loop id to a possible
751 1.1 mrg chrec, we could consider using a map<int, tree> that maps loop ids to the
752 1.1 mrg corresponding tree expressions. */
753 1.1 mrg
754 1.1 mrg void translate_isl_ast_to_gimple::
755 1.1 mrg build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
756 1.1 mrg __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
757 1.1 mrg sese_l ®ion)
758 1.1 mrg {
759 1.1 mrg gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
760 1.1 mrg isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
761 1.1 mrg int i;
762 1.1 mrg isl_ast_expr *arg_expr;
763 1.1 mrg for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
764 1.1 mrg {
765 1.1 mrg arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
766 1.1 mrg tree type = graphite_expr_type;
767 1.1 mrg tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
768 1.1 mrg
769 1.1 mrg /* To fail code generation, we generate wrong code until we discard it. */
770 1.1 mrg if (codegen_error_p ())
771 1.1 mrg t = integer_zero_node;
772 1.1 mrg
773 1.1 mrg loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
774 1.1 mrg iv_map[old_loop->num] = t;
775 1.1 mrg }
776 1.1 mrg }
777 1.1 mrg
778 1.1 mrg /* Translates an isl_ast_node_user to Gimple.
779 1.1 mrg
780 1.1 mrg FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
781 1.1 mrg
782 1.1 mrg edge translate_isl_ast_to_gimple::
783 1.1 mrg translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
784 1.1 mrg edge next_e, ivs_params &ip)
785 1.1 mrg {
786 1.1 mrg gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
787 1.1 mrg
788 1.1 mrg isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
789 1.1 mrg isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
790 1.1 mrg gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
791 1.1 mrg
792 1.1 mrg isl_id *name_id = isl_ast_expr_get_id (name_expr);
793 1.1 mrg poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
794 1.1 mrg gcc_assert (pbb);
795 1.1 mrg
796 1.1 mrg gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
797 1.1 mrg
798 1.1 mrg isl_ast_expr_free (name_expr);
799 1.1 mrg isl_id_free (name_id);
800 1.1 mrg
801 1.1 mrg gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
802 1.1 mrg "The entry block should not even appear within a scop");
803 1.1 mrg
804 1.1 mrg const int nb_loops = number_of_loops (cfun);
805 1.1 mrg vec<tree> iv_map;
806 1.1 mrg iv_map.create (nb_loops);
807 1.1 mrg iv_map.safe_grow_cleared (nb_loops, true);
808 1.1 mrg
809 1.1 mrg build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
810 1.1 mrg isl_ast_expr_free (user_expr);
811 1.1 mrg
812 1.1 mrg basic_block old_bb = GBB_BB (gbb);
813 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
814 1.1 mrg {
815 1.1 mrg fprintf (dump_file,
816 1.1 mrg "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
817 1.1 mrg old_bb->index, next_e->src->index, next_e->dest->index);
818 1.1 mrg print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
819 1.1 mrg }
820 1.1 mrg
821 1.1 mrg next_e = copy_bb_and_scalar_dependences (old_bb, next_e, iv_map);
822 1.1 mrg
823 1.1 mrg iv_map.release ();
824 1.1 mrg
825 1.1 mrg if (codegen_error_p ())
826 1.1 mrg return NULL;
827 1.1 mrg
828 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
829 1.1 mrg {
830 1.1 mrg fprintf (dump_file, "[codegen] (after copy) new basic block\n");
831 1.1 mrg print_loops_bb (dump_file, next_e->src, 0, 3);
832 1.1 mrg }
833 1.1 mrg
834 1.1 mrg return next_e;
835 1.1 mrg }
836 1.1 mrg
837 1.1 mrg /* Translates an isl_ast_node_block to Gimple. */
838 1.1 mrg
839 1.1 mrg edge translate_isl_ast_to_gimple::
840 1.1 mrg translate_isl_ast_node_block (loop_p context_loop,
841 1.1 mrg __isl_keep isl_ast_node *node,
842 1.1 mrg edge next_e, ivs_params &ip)
843 1.1 mrg {
844 1.1 mrg gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
845 1.1 mrg isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
846 1.1 mrg int i;
847 1.1 mrg for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
848 1.1 mrg {
849 1.1 mrg isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
850 1.1 mrg next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
851 1.1 mrg isl_ast_node_free (tmp_node);
852 1.1 mrg }
853 1.1 mrg isl_ast_node_list_free (node_list);
854 1.1 mrg return next_e;
855 1.1 mrg }
856 1.1 mrg
857 1.1 mrg /* Creates a new if region corresponding to isl's cond. */
858 1.1 mrg
859 1.1 mrg edge translate_isl_ast_to_gimple::
860 1.1 mrg graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
861 1.1 mrg ivs_params &ip)
862 1.1 mrg {
863 1.1 mrg tree type = graphite_expr_type;
864 1.1 mrg tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
865 1.1 mrg
866 1.1 mrg /* To fail code generation, we generate wrong code until we discard it. */
867 1.1 mrg if (codegen_error_p ())
868 1.1 mrg cond_expr = integer_zero_node;
869 1.1 mrg
870 1.1 mrg edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
871 1.1 mrg return exit_edge;
872 1.1 mrg }
873 1.1 mrg
874 1.1 mrg /* Translates an isl_ast_node_if to Gimple. */
875 1.1 mrg
876 1.1 mrg edge translate_isl_ast_to_gimple::
877 1.1 mrg translate_isl_ast_node_if (loop_p context_loop,
878 1.1 mrg __isl_keep isl_ast_node *node,
879 1.1 mrg edge next_e, ivs_params &ip)
880 1.1 mrg {
881 1.1 mrg gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
882 1.1 mrg isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
883 1.1 mrg edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
884 1.1 mrg edge true_e = get_true_edge_from_guard_bb (next_e->dest);
885 1.1 mrg merge_points.safe_push (last_e);
886 1.1 mrg
887 1.1 mrg isl_ast_node *then_node = isl_ast_node_if_get_then (node);
888 1.1 mrg translate_isl_ast (context_loop, then_node, true_e, ip);
889 1.1 mrg isl_ast_node_free (then_node);
890 1.1 mrg
891 1.1 mrg edge false_e = get_false_edge_from_guard_bb (next_e->dest);
892 1.1 mrg isl_ast_node *else_node = isl_ast_node_if_get_else (node);
893 1.1 mrg if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
894 1.1 mrg translate_isl_ast (context_loop, else_node, false_e, ip);
895 1.1 mrg
896 1.1 mrg isl_ast_node_free (else_node);
897 1.1 mrg return last_e;
898 1.1 mrg }
899 1.1 mrg
900 1.1 mrg /* Translates an isl AST node NODE to GCC representation in the
901 1.1 mrg context of a SESE. */
902 1.1 mrg
903 1.1 mrg edge translate_isl_ast_to_gimple::
904 1.1 mrg translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
905 1.1 mrg edge next_e, ivs_params &ip)
906 1.1 mrg {
907 1.1 mrg if (codegen_error_p ())
908 1.1 mrg return NULL;
909 1.1 mrg
910 1.1 mrg switch (isl_ast_node_get_type (node))
911 1.1 mrg {
912 1.1 mrg case isl_ast_node_error:
913 1.1 mrg gcc_unreachable ();
914 1.1 mrg
915 1.1 mrg case isl_ast_node_for:
916 1.1 mrg return translate_isl_ast_node_for (context_loop, node,
917 1.1 mrg next_e, ip);
918 1.1 mrg
919 1.1 mrg case isl_ast_node_if:
920 1.1 mrg return translate_isl_ast_node_if (context_loop, node,
921 1.1 mrg next_e, ip);
922 1.1 mrg
923 1.1 mrg case isl_ast_node_user:
924 1.1 mrg return translate_isl_ast_node_user (node, next_e, ip);
925 1.1 mrg
926 1.1 mrg case isl_ast_node_block:
927 1.1 mrg return translate_isl_ast_node_block (context_loop, node,
928 1.1 mrg next_e, ip);
929 1.1 mrg
930 1.1 mrg case isl_ast_node_mark:
931 1.1 mrg {
932 1.1 mrg isl_ast_node *n = isl_ast_node_mark_get_node (node);
933 1.1 mrg edge e = translate_isl_ast (context_loop, n, next_e, ip);
934 1.1 mrg isl_ast_node_free (n);
935 1.1 mrg return e;
936 1.1 mrg }
937 1.1 mrg
938 1.1 mrg default:
939 1.1 mrg gcc_unreachable ();
940 1.1 mrg }
941 1.1 mrg }
942 1.1 mrg
943 1.1 mrg /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
944 1.1 mrg When OLD_NAME and EXPR are the same we assert. */
945 1.1 mrg
946 1.1 mrg void translate_isl_ast_to_gimple::
947 1.1 mrg set_rename (tree old_name, tree expr)
948 1.1 mrg {
949 1.1 mrg if (dump_file)
950 1.1 mrg {
951 1.1 mrg fprintf (dump_file, "[codegen] setting rename: old_name = ");
952 1.1 mrg print_generic_expr (dump_file, old_name);
953 1.1 mrg fprintf (dump_file, ", new decl = ");
954 1.1 mrg print_generic_expr (dump_file, expr);
955 1.1 mrg fprintf (dump_file, "\n");
956 1.1 mrg }
957 1.1 mrg bool res = region->rename_map->put (old_name, expr);
958 1.1 mrg gcc_assert (! res);
959 1.1 mrg }
960 1.1 mrg
961 1.1 mrg /* Return an iterator to the instructions comes last in the execution order.
962 1.1 mrg Either GSI1 and GSI2 should belong to the same basic block or one of their
963 1.1 mrg respective basic blocks should dominate the other. */
964 1.1 mrg
965 1.1 mrg gimple_stmt_iterator
966 1.1 mrg later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
967 1.1 mrg {
968 1.1 mrg basic_block bb1 = gsi_bb (gsi1);
969 1.1 mrg basic_block bb2 = gsi_bb (gsi2);
970 1.1 mrg
971 1.1 mrg /* Find the iterator which is the latest. */
972 1.1 mrg if (bb1 == bb2)
973 1.1 mrg {
974 1.1 mrg gimple *stmt1 = gsi_stmt (gsi1);
975 1.1 mrg gimple *stmt2 = gsi_stmt (gsi2);
976 1.1 mrg
977 1.1 mrg if (stmt1 != NULL && stmt2 != NULL)
978 1.1 mrg {
979 1.1 mrg bool is_phi1 = gimple_code (stmt1) == GIMPLE_PHI;
980 1.1 mrg bool is_phi2 = gimple_code (stmt2) == GIMPLE_PHI;
981 1.1 mrg
982 1.1 mrg if (is_phi1 != is_phi2)
983 1.1 mrg return is_phi1 ? gsi2 : gsi1;
984 1.1 mrg }
985 1.1 mrg
986 1.1 mrg /* For empty basic blocks gsis point to the end of the sequence. Since
987 1.1 mrg there is no operator== defined for gimple_stmt_iterator and for gsis
988 1.1 mrg not pointing to a valid statement gsi_next would assert. */
989 1.1 mrg gimple_stmt_iterator gsi = gsi1;
990 1.1 mrg do {
991 1.1 mrg if (gsi_stmt (gsi) == gsi_stmt (gsi2))
992 1.1 mrg return gsi2;
993 1.1 mrg gsi_next (&gsi);
994 1.1 mrg } while (!gsi_end_p (gsi));
995 1.1 mrg
996 1.1 mrg return gsi1;
997 1.1 mrg }
998 1.1 mrg
999 1.1 mrg /* Find the basic block closest to the basic block which defines stmt. */
1000 1.1 mrg if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
1001 1.1 mrg return gsi1;
1002 1.1 mrg
1003 1.1 mrg gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
1004 1.1 mrg return gsi2;
1005 1.1 mrg }
1006 1.1 mrg
1007 1.1 mrg /* Insert each statement from SEQ at its earliest insertion p. */
1008 1.1 mrg
1009 1.1 mrg void translate_isl_ast_to_gimple::
1010 1.1 mrg gsi_insert_earliest (gimple_seq seq)
1011 1.1 mrg {
1012 1.1 mrg update_modified_stmts (seq);
1013 1.1 mrg sese_l &codegen_region = region->if_region->true_region->region;
1014 1.1 mrg basic_block begin_bb = get_entry_bb (codegen_region);
1015 1.1 mrg
1016 1.1 mrg /* Inserting the gimple statements in a vector because gimple_seq behave
1017 1.1 mrg in strage ways when inserting the stmts from it into different basic
1018 1.1 mrg blocks one at a time. */
1019 1.1 mrg auto_vec<gimple *, 3> stmts;
1020 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
1021 1.1 mrg gsi_next (&gsi))
1022 1.1 mrg stmts.safe_push (gsi_stmt (gsi));
1023 1.1 mrg
1024 1.1 mrg int i;
1025 1.1 mrg gimple *use_stmt;
1026 1.1 mrg FOR_EACH_VEC_ELT (stmts, i, use_stmt)
1027 1.1 mrg {
1028 1.1 mrg gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1029 1.1 mrg gimple_stmt_iterator gsi_def_stmt = gsi_start_nondebug_bb (begin_bb);
1030 1.1 mrg
1031 1.1 mrg use_operand_p use_p;
1032 1.1 mrg ssa_op_iter op_iter;
1033 1.1 mrg FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
1034 1.1 mrg {
1035 1.1 mrg /* Iterator to the current def of use_p. For function parameters or
1036 1.1 mrg anything where def is not found, insert at the beginning of the
1037 1.1 mrg generated region. */
1038 1.1 mrg gimple_stmt_iterator gsi_stmt = gsi_def_stmt;
1039 1.1 mrg
1040 1.1 mrg tree op = USE_FROM_PTR (use_p);
1041 1.1 mrg gimple *stmt = SSA_NAME_DEF_STMT (op);
1042 1.1 mrg if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
1043 1.1 mrg gsi_stmt = gsi_for_stmt (stmt);
1044 1.1 mrg
1045 1.1 mrg /* For region parameters, insert at the beginning of the generated
1046 1.1 mrg region. */
1047 1.1 mrg if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
1048 1.1 mrg gsi_stmt = gsi_def_stmt;
1049 1.1 mrg
1050 1.1 mrg gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
1051 1.1 mrg }
1052 1.1 mrg
1053 1.1 mrg if (!gsi_stmt (gsi_def_stmt))
1054 1.1 mrg {
1055 1.1 mrg gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
1056 1.1 mrg gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
1057 1.1 mrg }
1058 1.1 mrg else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
1059 1.1 mrg {
1060 1.1 mrg gimple_stmt_iterator bsi
1061 1.1 mrg = gsi_start_nondebug_bb (gsi_bb (gsi_def_stmt));
1062 1.1 mrg /* Insert right after the PHI statements. */
1063 1.1 mrg gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
1064 1.1 mrg }
1065 1.1 mrg else
1066 1.1 mrg gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);
1067 1.1 mrg
1068 1.1 mrg if (dump_file)
1069 1.1 mrg {
1070 1.1 mrg fprintf (dump_file, "[codegen] inserting statement in BB %d: ",
1071 1.1 mrg gimple_bb (use_stmt)->index);
1072 1.1 mrg print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
1073 1.1 mrg }
1074 1.1 mrg }
1075 1.1 mrg }
1076 1.1 mrg
1077 1.1 mrg /* For ops which are scev_analyzeable, we can regenerate a new name from its
1078 1.1 mrg scalar evolution around LOOP. */
1079 1.1 mrg
1080 1.1 mrg tree translate_isl_ast_to_gimple::
1081 1.1 mrg get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
1082 1.1 mrg vec<tree> iv_map)
1083 1.1 mrg {
1084 1.1 mrg tree scev = cached_scalar_evolution_in_region (region->region,
1085 1.1 mrg loop, old_name);
1086 1.1 mrg
1087 1.1 mrg /* At this point we should know the exact scev for each
1088 1.1 mrg scalar SSA_NAME used in the scop: all the other scalar
1089 1.1 mrg SSA_NAMEs should have been translated out of SSA using
1090 1.1 mrg arrays with one element. */
1091 1.1 mrg tree new_expr;
1092 1.1 mrg if (chrec_contains_undetermined (scev))
1093 1.1 mrg {
1094 1.1 mrg set_codegen_error ();
1095 1.1 mrg return build_zero_cst (TREE_TYPE (old_name));
1096 1.1 mrg }
1097 1.1 mrg
1098 1.1 mrg new_expr = chrec_apply_map (scev, iv_map);
1099 1.1 mrg
1100 1.1 mrg /* The apply should produce an expression tree containing
1101 1.1 mrg the uses of the new induction variables. We should be
1102 1.1 mrg able to use new_expr instead of the old_name in the newly
1103 1.1 mrg generated loop nest. */
1104 1.1 mrg if (chrec_contains_undetermined (new_expr)
1105 1.1 mrg || tree_contains_chrecs (new_expr, NULL))
1106 1.1 mrg {
1107 1.1 mrg set_codegen_error ();
1108 1.1 mrg return build_zero_cst (TREE_TYPE (old_name));
1109 1.1 mrg }
1110 1.1 mrg
1111 1.1 mrg /* Replace the old_name with the new_expr. */
1112 1.1 mrg return force_gimple_operand (unshare_expr (new_expr), stmts,
1113 1.1 mrg true, NULL_TREE);
1114 1.1 mrg }
1115 1.1 mrg
1116 1.1 mrg
1117 1.1 mrg /* Return true if STMT should be copied from region to the new code-generated
1118 1.1 mrg region. LABELs, CONDITIONS, induction-variables and region parameters need
1119 1.1 mrg not be copied. */
1120 1.1 mrg
1121 1.1 mrg static bool
1122 1.1 mrg should_copy_to_new_region (gimple *stmt, sese_info_p region)
1123 1.1 mrg {
1124 1.1 mrg /* Do not copy labels or conditions. */
1125 1.1 mrg if (gimple_code (stmt) == GIMPLE_LABEL
1126 1.1 mrg || gimple_code (stmt) == GIMPLE_COND)
1127 1.1 mrg return false;
1128 1.1 mrg
1129 1.1 mrg tree lhs;
1130 1.1 mrg /* Do not copy induction variables. */
1131 1.1 mrg if (is_gimple_assign (stmt)
1132 1.1 mrg && (lhs = gimple_assign_lhs (stmt))
1133 1.1 mrg && TREE_CODE (lhs) == SSA_NAME
1134 1.1 mrg && scev_analyzable_p (lhs, region->region)
1135 1.1 mrg /* But to code-generate liveouts - liveout PHI generation is
1136 1.1 mrg in generic sese.cc code that cannot do code generation. */
1137 1.1 mrg && ! bitmap_bit_p (region->liveout, SSA_NAME_VERSION (lhs)))
1138 1.1 mrg return false;
1139 1.1 mrg
1140 1.1 mrg return true;
1141 1.1 mrg }
1142 1.1 mrg
1143 1.1 mrg /* Duplicates the statements of basic block BB into basic block NEW_BB
1144 1.1 mrg and compute the new induction variables according to the IV_MAP. */
1145 1.1 mrg
1146 1.1 mrg void translate_isl_ast_to_gimple::
1147 1.1 mrg graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
1148 1.1 mrg vec<tree> iv_map)
1149 1.1 mrg {
1150 1.1 mrg /* Iterator poining to the place where new statement (s) will be inserted. */
1151 1.1 mrg gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
1152 1.1 mrg
1153 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1154 1.1 mrg gsi_next (&gsi))
1155 1.1 mrg {
1156 1.1 mrg gimple *stmt = gsi_stmt (gsi);
1157 1.1 mrg if (!should_copy_to_new_region (stmt, region))
1158 1.1 mrg continue;
1159 1.1 mrg
1160 1.1 mrg /* Create a new copy of STMT and duplicate STMT's virtual
1161 1.1 mrg operands. */
1162 1.1 mrg gimple *copy = gimple_copy (stmt);
1163 1.1 mrg
1164 1.1 mrg /* Rather than not copying debug stmts we reset them.
1165 1.1 mrg ??? Where we can rewrite uses without inserting new
1166 1.1 mrg stmts we could simply do that. */
1167 1.1 mrg if (is_gimple_debug (copy))
1168 1.1 mrg {
1169 1.1 mrg if (gimple_debug_bind_p (copy))
1170 1.1 mrg gimple_debug_bind_reset_value (copy);
1171 1.1 mrg else if (gimple_debug_source_bind_p (copy)
1172 1.1 mrg || gimple_debug_nonbind_marker_p (copy))
1173 1.1 mrg ;
1174 1.1 mrg else
1175 1.1 mrg gcc_unreachable ();
1176 1.1 mrg }
1177 1.1 mrg
1178 1.1 mrg maybe_duplicate_eh_stmt (copy, stmt);
1179 1.1 mrg gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
1180 1.1 mrg
1181 1.1 mrg /* Crete new names for each def in the copied stmt. */
1182 1.1 mrg def_operand_p def_p;
1183 1.1 mrg ssa_op_iter op_iter;
1184 1.1 mrg FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
1185 1.1 mrg {
1186 1.1 mrg tree old_name = DEF_FROM_PTR (def_p);
1187 1.1 mrg create_new_def_for (old_name, copy, def_p);
1188 1.1 mrg }
1189 1.1 mrg
1190 1.1 mrg gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
1191 1.1 mrg if (dump_file)
1192 1.1 mrg {
1193 1.1 mrg fprintf (dump_file, "[codegen] inserting statement: ");
1194 1.1 mrg print_gimple_stmt (dump_file, copy, 0);
1195 1.1 mrg }
1196 1.1 mrg
1197 1.1 mrg /* For each SCEV analyzable SSA_NAME, rename their usage. */
1198 1.1 mrg ssa_op_iter iter;
1199 1.1 mrg use_operand_p use_p;
1200 1.1 mrg if (!is_gimple_debug (copy))
1201 1.1 mrg {
1202 1.1 mrg bool changed = false;
1203 1.1 mrg FOR_EACH_SSA_USE_OPERAND (use_p, copy, iter, SSA_OP_USE)
1204 1.1 mrg {
1205 1.1 mrg tree old_name = USE_FROM_PTR (use_p);
1206 1.1 mrg
1207 1.1 mrg if (TREE_CODE (old_name) != SSA_NAME
1208 1.1 mrg || SSA_NAME_IS_DEFAULT_DEF (old_name)
1209 1.1 mrg || ! scev_analyzable_p (old_name, region->region))
1210 1.1 mrg continue;
1211 1.1 mrg
1212 1.1 mrg gimple_seq stmts = NULL;
1213 1.1 mrg tree new_name = get_rename_from_scev (old_name, &stmts,
1214 1.1 mrg bb->loop_father, iv_map);
1215 1.1 mrg if (! codegen_error_p ())
1216 1.1 mrg gsi_insert_earliest (stmts);
1217 1.1 mrg replace_exp (use_p, new_name);
1218 1.1 mrg changed = true;
1219 1.1 mrg }
1220 1.1 mrg if (changed)
1221 1.1 mrg fold_stmt_inplace (&gsi_tgt);
1222 1.1 mrg }
1223 1.1 mrg
1224 1.1 mrg update_stmt (copy);
1225 1.1 mrg }
1226 1.1 mrg }
1227 1.1 mrg
1228 1.1 mrg
1229 1.1 mrg /* Copies BB and includes in the copied BB all the statements that can
1230 1.1 mrg be reached following the use-def chains from the memory accesses,
1231 1.1 mrg and returns the next edge following this new block. */
1232 1.1 mrg
1233 1.1 mrg edge translate_isl_ast_to_gimple::
1234 1.1 mrg copy_bb_and_scalar_dependences (basic_block bb, edge next_e, vec<tree> iv_map)
1235 1.1 mrg {
1236 1.1 mrg basic_block new_bb = split_edge (next_e);
1237 1.1 mrg gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
1238 1.1 mrg for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1239 1.1 mrg gsi_next (&psi))
1240 1.1 mrg {
1241 1.1 mrg gphi *phi = psi.phi ();
1242 1.1 mrg tree res = gimple_phi_result (phi);
1243 1.1 mrg if (virtual_operand_p (res)
1244 1.1 mrg || scev_analyzable_p (res, region->region))
1245 1.1 mrg continue;
1246 1.1 mrg
1247 1.1 mrg tree new_phi_def;
1248 1.1 mrg tree *rename = region->rename_map->get (res);
1249 1.1 mrg if (! rename)
1250 1.1 mrg {
1251 1.1 mrg new_phi_def = create_tmp_reg (TREE_TYPE (res));
1252 1.1 mrg set_rename (res, new_phi_def);
1253 1.1 mrg }
1254 1.1 mrg else
1255 1.1 mrg new_phi_def = *rename;
1256 1.1 mrg
1257 1.1 mrg gassign *ass = gimple_build_assign (NULL_TREE, new_phi_def);
1258 1.1 mrg create_new_def_for (res, ass, NULL);
1259 1.1 mrg gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
1260 1.1 mrg }
1261 1.1 mrg
1262 1.1 mrg graphite_copy_stmts_from_block (bb, new_bb, iv_map);
1263 1.1 mrg
1264 1.1 mrg /* Insert out-of SSA copies on the original BB outgoing edges. */
1265 1.1 mrg gsi_tgt = gsi_last_bb (new_bb);
1266 1.1 mrg basic_block bb_for_succs = bb;
1267 1.1 mrg if (bb_for_succs == bb_for_succs->loop_father->latch
1268 1.1 mrg && bb_in_sese_p (bb_for_succs, region->region)
1269 1.1 mrg && sese_trivially_empty_bb_p (bb_for_succs))
1270 1.1 mrg bb_for_succs = NULL;
1271 1.1 mrg while (bb_for_succs)
1272 1.1 mrg {
1273 1.1 mrg basic_block latch = NULL;
1274 1.1 mrg edge_iterator ei;
1275 1.1 mrg edge e;
1276 1.1 mrg FOR_EACH_EDGE (e, ei, bb_for_succs->succs)
1277 1.1 mrg {
1278 1.1 mrg for (gphi_iterator psi = gsi_start_phis (e->dest); !gsi_end_p (psi);
1279 1.1 mrg gsi_next (&psi))
1280 1.1 mrg {
1281 1.1 mrg gphi *phi = psi.phi ();
1282 1.1 mrg tree res = gimple_phi_result (phi);
1283 1.1 mrg if (virtual_operand_p (res)
1284 1.1 mrg || scev_analyzable_p (res, region->region))
1285 1.1 mrg continue;
1286 1.1 mrg
1287 1.1 mrg tree new_phi_def;
1288 1.1 mrg tree *rename = region->rename_map->get (res);
1289 1.1 mrg if (! rename)
1290 1.1 mrg {
1291 1.1 mrg new_phi_def = create_tmp_reg (TREE_TYPE (res));
1292 1.1 mrg set_rename (res, new_phi_def);
1293 1.1 mrg }
1294 1.1 mrg else
1295 1.1 mrg new_phi_def = *rename;
1296 1.1 mrg
1297 1.1 mrg tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
1298 1.1 mrg if (TREE_CODE (arg) == SSA_NAME
1299 1.1 mrg && scev_analyzable_p (arg, region->region))
1300 1.1 mrg {
1301 1.1 mrg gimple_seq stmts = NULL;
1302 1.1 mrg tree new_name = get_rename_from_scev (arg, &stmts,
1303 1.1 mrg bb->loop_father,
1304 1.1 mrg iv_map);
1305 1.1 mrg if (! codegen_error_p ())
1306 1.1 mrg gsi_insert_earliest (stmts);
1307 1.1 mrg arg = new_name;
1308 1.1 mrg }
1309 1.1 mrg gassign *ass = gimple_build_assign (new_phi_def, arg);
1310 1.1 mrg gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
1311 1.1 mrg }
1312 1.1 mrg if (e->dest == bb_for_succs->loop_father->latch
1313 1.1 mrg && bb_in_sese_p (e->dest, region->region)
1314 1.1 mrg && sese_trivially_empty_bb_p (e->dest))
1315 1.1 mrg latch = e->dest;
1316 1.1 mrg }
1317 1.1 mrg bb_for_succs = latch;
1318 1.1 mrg }
1319 1.1 mrg
1320 1.1 mrg return single_succ_edge (new_bb);
1321 1.1 mrg }
1322 1.1 mrg
1323 1.1 mrg /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
1324 1.1 mrg
1325 1.1 mrg void translate_isl_ast_to_gimple::
1326 1.1 mrg add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
1327 1.1 mrg {
1328 1.1 mrg sese_info_p region = scop->scop_info;
1329 1.1 mrg unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
1330 1.1 mrg gcc_assert (nb_parameters == sese_nb_params (region));
1331 1.1 mrg unsigned i;
1332 1.1 mrg tree param;
1333 1.1 mrg FOR_EACH_VEC_ELT (region->params, i, param)
1334 1.1 mrg {
1335 1.1 mrg isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
1336 1.1 mrg isl_dim_param, i);
1337 1.1 mrg bool existed_p = ip.put (tmp_id, param);
1338 1.1 mrg gcc_assert (!existed_p);
1339 1.1 mrg }
1340 1.1 mrg }
1341 1.1 mrg
1342 1.1 mrg
1343 1.1 mrg /* Generates a build, which specifies the constraints on the parameters. */
1344 1.1 mrg
1345 1.1 mrg __isl_give isl_ast_build *translate_isl_ast_to_gimple::
1346 1.1 mrg generate_isl_context (scop_p scop)
1347 1.1 mrg {
1348 1.1 mrg isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
1349 1.1 mrg return isl_ast_build_from_context (context_isl);
1350 1.1 mrg }
1351 1.1 mrg
1352 1.1 mrg /* This method is executed before the construction of a for node. */
1353 1.1 mrg __isl_give isl_id *
1354 1.1 mrg ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
1355 1.1 mrg {
1356 1.1 mrg isl_union_map *dependences = (isl_union_map *) user;
1357 1.1 mrg ast_build_info *for_info = XNEW (struct ast_build_info);
1358 1.1 mrg isl_union_map *schedule = isl_ast_build_get_schedule (build);
1359 1.1 mrg isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
1360 1.1 mrg int dimension = isl_space_dim (schedule_space, isl_dim_out);
1361 1.1 mrg for_info->is_parallelizable =
1362 1.1 mrg !carries_deps (schedule, dependences, dimension);
1363 1.1 mrg isl_union_map_free (schedule);
1364 1.1 mrg isl_space_free (schedule_space);
1365 1.1 mrg isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
1366 1.1 mrg return id;
1367 1.1 mrg }
1368 1.1 mrg
1369 1.1 mrg /* Generate isl AST from schedule of SCOP. */
1370 1.1 mrg
1371 1.1 mrg __isl_give isl_ast_node *translate_isl_ast_to_gimple::
1372 1.1 mrg scop_to_isl_ast (scop_p scop)
1373 1.1 mrg {
1374 1.1 mrg int old_err = isl_options_get_on_error (scop->isl_context);
1375 1.1 mrg int old_max_operations = isl_ctx_get_max_operations (scop->isl_context);
1376 1.1 mrg int max_operations = param_max_isl_operations;
1377 1.1 mrg if (max_operations)
1378 1.1 mrg isl_ctx_set_max_operations (scop->isl_context, max_operations);
1379 1.1 mrg isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_CONTINUE);
1380 1.1 mrg
1381 1.1 mrg gcc_assert (scop->transformed_schedule);
1382 1.1 mrg
1383 1.1 mrg /* Set the separate option to reduce control flow overhead. */
1384 1.1 mrg isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
1385 1.1 mrg (isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
1386 1.1 mrg isl_ast_build *context_isl = generate_isl_context (scop);
1387 1.1 mrg
1388 1.1 mrg if (flag_loop_parallelize_all)
1389 1.1 mrg {
1390 1.1 mrg scop_get_dependences (scop);
1391 1.1 mrg context_isl =
1392 1.1 mrg isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
1393 1.1 mrg scop->dependence);
1394 1.1 mrg }
1395 1.1 mrg
1396 1.1 mrg isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
1397 1.1 mrg (context_isl, schedule);
1398 1.1 mrg isl_ast_build_free (context_isl);
1399 1.1 mrg
1400 1.1 mrg isl_options_set_on_error (scop->isl_context, old_err);
1401 1.1 mrg isl_ctx_reset_operations (scop->isl_context);
1402 1.1 mrg isl_ctx_set_max_operations (scop->isl_context, old_max_operations);
1403 1.1 mrg if (isl_ctx_last_error (scop->isl_context) != isl_error_none)
1404 1.1 mrg {
1405 1.1 mrg if (dump_enabled_p ())
1406 1.1 mrg {
1407 1.1 mrg dump_user_location_t loc = find_loop_location
1408 1.1 mrg (scop->scop_info->region.entry->dest->loop_father);
1409 1.1 mrg if (isl_ctx_last_error (scop->isl_context) == isl_error_quota)
1410 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1411 1.1 mrg "loop nest not optimized, AST generation timed out "
1412 1.1 mrg "after %d operations [--param max-isl-operations]\n",
1413 1.1 mrg max_operations);
1414 1.1 mrg else
1415 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1416 1.1 mrg "loop nest not optimized, ISL AST generation "
1417 1.1 mrg "signalled an error\n");
1418 1.1 mrg }
1419 1.1 mrg isl_ast_node_free (ast_isl);
1420 1.1 mrg return NULL;
1421 1.1 mrg }
1422 1.1 mrg
1423 1.1 mrg return ast_isl;
1424 1.1 mrg }
1425 1.1 mrg
1426 1.1 mrg /* Generate out-of-SSA copies for the entry edge FALSE_ENTRY/TRUE_ENTRY
1427 1.1 mrg in REGION. */
1428 1.1 mrg
1429 1.1 mrg static void
1430 1.1 mrg generate_entry_out_of_ssa_copies (edge false_entry,
1431 1.1 mrg edge true_entry,
1432 1.1 mrg sese_info_p region)
1433 1.1 mrg {
1434 1.1 mrg gimple_stmt_iterator gsi_tgt = gsi_start_bb (true_entry->dest);
1435 1.1 mrg for (gphi_iterator psi = gsi_start_phis (false_entry->dest);
1436 1.1 mrg !gsi_end_p (psi); gsi_next (&psi))
1437 1.1 mrg {
1438 1.1 mrg gphi *phi = psi.phi ();
1439 1.1 mrg tree res = gimple_phi_result (phi);
1440 1.1 mrg if (virtual_operand_p (res))
1441 1.1 mrg continue;
1442 1.1 mrg /* When there's no out-of-SSA var registered do not bother
1443 1.1 mrg to create one. */
1444 1.1 mrg tree *rename = region->rename_map->get (res);
1445 1.1 mrg if (! rename)
1446 1.1 mrg continue;
1447 1.1 mrg tree new_phi_def = *rename;
1448 1.1 mrg gassign *ass = gimple_build_assign (new_phi_def,
1449 1.1 mrg PHI_ARG_DEF_FROM_EDGE (phi,
1450 1.1 mrg false_entry));
1451 1.1 mrg gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
1452 1.1 mrg }
1453 1.1 mrg }
1454 1.1 mrg
1455 1.1 mrg /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
1456 1.1 mrg Return true if code generation succeeded. */
1457 1.1 mrg
1458 1.1 mrg bool
1459 1.1 mrg graphite_regenerate_ast_isl (scop_p scop)
1460 1.1 mrg {
1461 1.1 mrg sese_info_p region = scop->scop_info;
1462 1.1 mrg translate_isl_ast_to_gimple t (region);
1463 1.1 mrg
1464 1.1 mrg ifsese if_region = NULL;
1465 1.1 mrg isl_ast_node *root_node;
1466 1.1 mrg ivs_params ip;
1467 1.1 mrg
1468 1.1 mrg timevar_push (TV_GRAPHITE_CODE_GEN);
1469 1.1 mrg t.add_parameters_to_ivs_params (scop, ip);
1470 1.1 mrg root_node = t.scop_to_isl_ast (scop);
1471 1.1 mrg if (! root_node)
1472 1.1 mrg {
1473 1.1 mrg ivs_params_clear (ip);
1474 1.1 mrg timevar_pop (TV_GRAPHITE_CODE_GEN);
1475 1.1 mrg return false;
1476 1.1 mrg }
1477 1.1 mrg
1478 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1479 1.1 mrg {
1480 1.1 mrg fprintf (dump_file, "[scheduler] original schedule:\n");
1481 1.1 mrg print_isl_schedule (dump_file, scop->original_schedule);
1482 1.1 mrg fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
1483 1.1 mrg print_isl_schedule (dump_file, scop->transformed_schedule);
1484 1.1 mrg
1485 1.1 mrg fprintf (dump_file, "[scheduler] original ast:\n");
1486 1.1 mrg print_schedule_ast (dump_file, scop->original_schedule, scop);
1487 1.1 mrg fprintf (dump_file, "[scheduler] AST generated by isl:\n");
1488 1.1 mrg print_isl_ast (dump_file, root_node);
1489 1.1 mrg }
1490 1.1 mrg
1491 1.1 mrg if_region = move_sese_in_condition (region);
1492 1.1 mrg region->if_region = if_region;
1493 1.1 mrg
1494 1.1 mrg loop_p context_loop = region->region.entry->src->loop_father;
1495 1.1 mrg edge e = single_succ_edge (if_region->true_region->region.entry->dest);
1496 1.1 mrg basic_block bb = split_edge (e);
1497 1.1 mrg
1498 1.1 mrg /* Update the true_region exit edge. */
1499 1.1 mrg region->if_region->true_region->region.exit = single_succ_edge (bb);
1500 1.1 mrg
1501 1.1 mrg t.translate_isl_ast (context_loop, root_node, e, ip);
1502 1.1 mrg if (! t.codegen_error_p ())
1503 1.1 mrg {
1504 1.1 mrg generate_entry_out_of_ssa_copies (if_region->false_region->region.entry,
1505 1.1 mrg if_region->true_region->region.entry,
1506 1.1 mrg region);
1507 1.1 mrg sese_insert_phis_for_liveouts (region,
1508 1.1 mrg if_region->region->region.exit->src,
1509 1.1 mrg if_region->false_region->region.exit,
1510 1.1 mrg if_region->true_region->region.exit);
1511 1.1 mrg if (dump_file)
1512 1.1 mrg fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
1513 1.1 mrg }
1514 1.1 mrg
1515 1.1 mrg if (t.codegen_error_p ())
1516 1.1 mrg {
1517 1.1 mrg if (dump_enabled_p ())
1518 1.1 mrg {
1519 1.1 mrg dump_user_location_t loc = find_loop_location
1520 1.1 mrg (scop->scop_info->region.entry->dest->loop_father);
1521 1.1 mrg dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
1522 1.1 mrg "loop nest not optimized, code generation error\n");
1523 1.1 mrg }
1524 1.1 mrg
1525 1.1 mrg /* Remove the unreachable region. */
1526 1.1 mrg remove_edge_and_dominated_blocks (if_region->true_region->region.entry);
1527 1.1 mrg basic_block ifb = if_region->false_region->region.entry->src;
1528 1.1 mrg gimple_stmt_iterator gsi = gsi_last_bb (ifb);
1529 1.1 mrg gsi_remove (&gsi, true);
1530 1.1 mrg if_region->false_region->region.entry->flags &= ~EDGE_FALSE_VALUE;
1531 1.1 mrg if_region->false_region->region.entry->flags |= EDGE_FALLTHRU;
1532 1.1 mrg /* remove_edge_and_dominated_blocks marks loops for removal but
1533 1.1 mrg doesn't actually remove them (fix that...). */
1534 1.1 mrg for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
1535 1.1 mrg if (!loop->header)
1536 1.1 mrg delete_loop (loop);
1537 1.1 mrg }
1538 1.1 mrg
1539 1.1 mrg /* We are delaying SSA update to after code-generating all SCOPs.
1540 1.1 mrg This is because we analyzed DRs and parameters on the unmodified
1541 1.1 mrg IL and thus rely on SSA update to pick up new dominating definitions
1542 1.1 mrg from for example SESE liveout PHIs. This is also for efficiency
1543 1.1 mrg as SSA update does work depending on the size of the function. */
1544 1.1 mrg
1545 1.1 mrg free (if_region->true_region);
1546 1.1 mrg free (if_region->region);
1547 1.1 mrg free (if_region);
1548 1.1 mrg
1549 1.1 mrg ivs_params_clear (ip);
1550 1.1 mrg isl_ast_node_free (root_node);
1551 1.1 mrg timevar_pop (TV_GRAPHITE_CODE_GEN);
1552 1.1 mrg
1553 1.1 mrg return !t.codegen_error_p ();
1554 1.1 mrg }
1555 1.1 mrg
1556 1.1 mrg #endif /* HAVE_isl */
1557