* i386.c (has_dispatch): Disable for Ryzen.
[official-gcc.git] / gcc / graphite-isl-ast-to-gimple.c
blobdddc07b5b433adf6d290f55407f8e77aa4236bbf
1 /* Translation of isl AST to Gimple.
2 Copyright (C) 2014-2017 Free Software Foundation, Inc.
3 Contributed by Roman Gareev <gareevroman@gmail.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define USES_ISL
23 #include "config.h"
25 #ifdef HAVE_isl
27 #define INCLUDE_MAP
28 #include "system.h"
29 #include "coretypes.h"
30 #include "backend.h"
31 #include "cfghooks.h"
32 #include "tree.h"
33 #include "gimple.h"
34 #include "ssa.h"
35 #include "params.h"
36 #include "fold-const.h"
37 #include "gimple-fold.h"
38 #include "gimple-iterator.h"
39 #include "gimplify.h"
40 #include "gimplify-me.h"
41 #include "tree-eh.h"
42 #include "tree-ssa-loop.h"
43 #include "tree-ssa-operands.h"
44 #include "tree-ssa-propagate.h"
45 #include "tree-pass.h"
46 #include "cfgloop.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"
54 #include "tree-cfg.h"
55 #include "gimple-pretty-print.h"
56 #include "cfganal.h"
57 #include "value-prof.h"
58 #include "tree-ssa.h"
59 #include "graphite.h"
61 /* We always try to use signed 128 bit types, but fall back to smaller types
62 in case a platform does not provide types of these sizes. In the future we
63 should use isl to derive the optimal type for each subexpression. */
65 static int max_mode_int_precision =
66 GET_MODE_PRECISION (int_mode_for_size (MAX_FIXED_MODE_SIZE, 0).require ());
67 static int graphite_expression_type_precision = 128 <= max_mode_int_precision ?
68 128 : max_mode_int_precision;
70 struct ast_build_info
72 ast_build_info()
73 : is_parallelizable(false)
74 { }
75 bool is_parallelizable;
78 /* IVS_PARAMS maps isl's scattering and parameter identifiers
79 to corresponding trees. */
81 typedef std::map<isl_id *, tree> ivs_params;
83 /* Free all memory allocated for isl's identifiers. */
85 static void ivs_params_clear (ivs_params &ip)
87 std::map<isl_id *, tree>::iterator it;
88 for (it = ip.begin ();
89 it != ip.end (); it++)
91 isl_id_free (it->first);
95 /* Set the "separate" option for the schedule node. */
97 static isl_schedule_node *
98 set_separate_option (__isl_take isl_schedule_node *node, void *user)
100 if (user)
101 return node;
103 if (isl_schedule_node_get_type (node) != isl_schedule_node_band)
104 return node;
106 /* Set the "separate" option unless it is set earlier to another option. */
107 if (isl_schedule_node_band_member_get_ast_loop_type (node, 0)
108 == isl_ast_loop_default)
109 return isl_schedule_node_band_member_set_ast_loop_type
110 (node, 0, isl_ast_loop_separate);
112 return node;
115 /* Print SCHEDULE under an AST form on file F. */
117 void
118 print_schedule_ast (FILE *f, __isl_keep isl_schedule *schedule, scop_p scop)
120 isl_set *set = isl_set_params (isl_set_copy (scop->param_context));
121 isl_ast_build *context = isl_ast_build_from_context (set);
122 isl_ast_node *ast
123 = isl_ast_build_node_from_schedule (context, isl_schedule_copy (schedule));
124 isl_ast_build_free (context);
125 print_isl_ast (f, ast);
126 isl_ast_node_free (ast);
129 DEBUG_FUNCTION void
130 debug_schedule_ast (__isl_keep isl_schedule *s, scop_p scop)
132 print_schedule_ast (stderr, s, scop);
135 enum phi_node_kind
137 unknown_phi,
138 loop_phi,
139 close_phi,
140 cond_phi
143 class translate_isl_ast_to_gimple
145 public:
146 translate_isl_ast_to_gimple (sese_info_p r)
147 : region (r), codegen_error (false) { }
148 edge translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
149 edge next_e, ivs_params &ip);
150 edge translate_isl_ast_node_for (loop_p context_loop,
151 __isl_keep isl_ast_node *node,
152 edge next_e, ivs_params &ip);
153 edge translate_isl_ast_for_loop (loop_p context_loop,
154 __isl_keep isl_ast_node *node_for,
155 edge next_e,
156 tree type, tree lb, tree ub,
157 ivs_params &ip);
158 edge translate_isl_ast_node_if (loop_p context_loop,
159 __isl_keep isl_ast_node *node,
160 edge next_e, ivs_params &ip);
161 edge translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
162 edge next_e, ivs_params &ip);
163 edge translate_isl_ast_node_block (loop_p context_loop,
164 __isl_keep isl_ast_node *node,
165 edge next_e, ivs_params &ip);
166 tree unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
167 ivs_params &ip);
168 tree binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
169 ivs_params &ip);
170 tree ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
171 ivs_params &ip);
172 tree nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr,
173 ivs_params &ip);
174 tree gcc_expression_from_isl_expression (tree type,
175 __isl_take isl_ast_expr *,
176 ivs_params &ip);
177 tree gcc_expression_from_isl_ast_expr_id (tree type,
178 __isl_keep isl_ast_expr *expr_id,
179 ivs_params &ip);
180 tree gcc_expression_from_isl_expr_int (tree type,
181 __isl_take isl_ast_expr *expr);
182 tree gcc_expression_from_isl_expr_op (tree type,
183 __isl_take isl_ast_expr *expr,
184 ivs_params &ip);
185 struct loop *graphite_create_new_loop (edge entry_edge,
186 __isl_keep isl_ast_node *node_for,
187 loop_p outer, tree type,
188 tree lb, tree ub, ivs_params &ip);
189 edge graphite_create_new_guard (edge entry_edge,
190 __isl_take isl_ast_expr *if_cond,
191 ivs_params &ip);
192 void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
193 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
194 sese_l &region);
195 void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
196 __isl_give isl_ast_build *generate_isl_context (scop_p scop);
198 __isl_give isl_ast_node * scop_to_isl_ast (scop_p scop);
200 tree get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
201 basic_block new_bb, basic_block old_bb,
202 vec<tree> iv_map);
203 bool graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
204 vec<tree> iv_map);
205 edge copy_bb_and_scalar_dependences (basic_block bb, edge next_e,
206 vec<tree> iv_map);
207 void set_rename (tree old_name, tree expr);
208 void set_rename_for_each_def (gimple *stmt);
209 void gsi_insert_earliest (gimple_seq seq);
210 bool codegen_error_p () const { return codegen_error; }
212 void set_codegen_error ()
214 codegen_error = true;
215 gcc_assert (! flag_checking
216 || PARAM_VALUE (PARAM_GRAPHITE_ALLOW_CODEGEN_ERRORS));
219 bool is_constant (tree op) const
221 return TREE_CODE (op) == INTEGER_CST
222 || TREE_CODE (op) == REAL_CST
223 || TREE_CODE (op) == COMPLEX_CST
224 || TREE_CODE (op) == VECTOR_CST;
227 private:
228 /* The region to be translated. */
229 sese_info_p region;
231 /* This flag is set when an error occurred during the translation of isl AST
232 to Gimple. */
233 bool codegen_error;
235 /* A vector of all the edges at if_condition merge points. */
236 auto_vec<edge, 2> merge_points;
239 /* Return the tree variable that corresponds to the given isl ast identifier
240 expression (an isl_ast_expr of type isl_ast_expr_id).
242 FIXME: We should replace blind conversion of id's type with derivation
243 of the optimal type when we get the corresponding isl support. Blindly
244 converting type sizes may be problematic when we switch to smaller
245 types. */
247 tree translate_isl_ast_to_gimple::
248 gcc_expression_from_isl_ast_expr_id (tree type,
249 __isl_take isl_ast_expr *expr_id,
250 ivs_params &ip)
252 gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
253 isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
254 std::map<isl_id *, tree>::iterator res;
255 res = ip.find (tmp_isl_id);
256 isl_id_free (tmp_isl_id);
257 gcc_assert (res != ip.end () &&
258 "Could not map isl_id to tree expression");
259 isl_ast_expr_free (expr_id);
260 tree t = res->second;
261 tree *val = region->parameter_rename_map->get(t);
263 if (!val)
264 val = &t;
265 return fold_convert (type, *val);
268 /* Converts an isl_ast_expr_int expression E to a GCC expression tree of
269 type TYPE. */
271 tree translate_isl_ast_to_gimple::
272 gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
274 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
275 isl_val *val = isl_ast_expr_get_val (expr);
276 size_t n = isl_val_n_abs_num_chunks (val, sizeof (HOST_WIDE_INT));
277 HOST_WIDE_INT *chunks = XALLOCAVEC (HOST_WIDE_INT, n);
278 tree res;
279 if (isl_val_get_abs_num_chunks (val, sizeof (HOST_WIDE_INT), chunks) == -1)
280 res = NULL_TREE;
281 else
283 widest_int wi = widest_int::from_array (chunks, n, true);
284 if (isl_val_is_neg (val))
285 wi = -wi;
286 res = wide_int_to_tree (type, wi);
288 isl_val_free (val);
289 isl_ast_expr_free (expr);
290 return res;
293 /* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
294 type TYPE. */
296 tree translate_isl_ast_to_gimple::
297 binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
299 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
300 tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
301 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
302 tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
304 enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
305 isl_ast_expr_free (expr);
307 if (codegen_error_p ())
308 return NULL_TREE;
310 switch (expr_type)
312 case isl_ast_op_add:
313 return fold_build2 (PLUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
315 case isl_ast_op_sub:
316 return fold_build2 (MINUS_EXPR, type, tree_lhs_expr, tree_rhs_expr);
318 case isl_ast_op_mul:
319 return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
321 case isl_ast_op_div:
322 /* As isl operates on arbitrary precision numbers, we may end up with
323 division by 2^64 that is folded to 0. */
324 if (integer_zerop (tree_rhs_expr))
326 set_codegen_error ();
327 return NULL_TREE;
329 return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
331 case isl_ast_op_pdiv_q:
332 /* As isl operates on arbitrary precision numbers, we may end up with
333 division by 2^64 that is folded to 0. */
334 if (integer_zerop (tree_rhs_expr))
336 set_codegen_error ();
337 return NULL_TREE;
339 return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
341 case isl_ast_op_zdiv_r:
342 case isl_ast_op_pdiv_r:
343 /* As isl operates on arbitrary precision numbers, we may end up with
344 division by 2^64 that is folded to 0. */
345 if (integer_zerop (tree_rhs_expr))
347 set_codegen_error ();
348 return NULL_TREE;
350 return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
352 case isl_ast_op_fdiv_q:
353 /* As isl operates on arbitrary precision numbers, we may end up with
354 division by 2^64 that is folded to 0. */
355 if (integer_zerop (tree_rhs_expr))
357 set_codegen_error ();
358 return NULL_TREE;
360 return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
362 case isl_ast_op_and:
363 return fold_build2 (TRUTH_ANDIF_EXPR, type,
364 tree_lhs_expr, tree_rhs_expr);
366 case isl_ast_op_or:
367 return fold_build2 (TRUTH_ORIF_EXPR, type, tree_lhs_expr, tree_rhs_expr);
369 case isl_ast_op_eq:
370 return fold_build2 (EQ_EXPR, type, tree_lhs_expr, tree_rhs_expr);
372 case isl_ast_op_le:
373 return fold_build2 (LE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
375 case isl_ast_op_lt:
376 return fold_build2 (LT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
378 case isl_ast_op_ge:
379 return fold_build2 (GE_EXPR, type, tree_lhs_expr, tree_rhs_expr);
381 case isl_ast_op_gt:
382 return fold_build2 (GT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
384 default:
385 gcc_unreachable ();
389 /* Converts a ternary isl_ast_expr_op expression E to a GCC expression tree of
390 type TYPE. */
392 tree translate_isl_ast_to_gimple::
393 ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
395 enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr);
396 gcc_assert (t == isl_ast_op_cond || t == isl_ast_op_select);
397 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
398 tree a = gcc_expression_from_isl_expression (type, arg_expr, ip);
399 arg_expr = isl_ast_expr_get_op_arg (expr, 1);
400 tree b = gcc_expression_from_isl_expression (type, arg_expr, ip);
401 arg_expr = isl_ast_expr_get_op_arg (expr, 2);
402 tree c = gcc_expression_from_isl_expression (type, arg_expr, ip);
403 isl_ast_expr_free (expr);
405 if (codegen_error_p ())
406 return NULL_TREE;
408 return fold_build3 (COND_EXPR, type, a, b, c);
411 /* Converts a unary isl_ast_expr_op expression E to a GCC expression tree of
412 type TYPE. */
414 tree translate_isl_ast_to_gimple::
415 unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
417 gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
418 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
419 tree tree_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
420 isl_ast_expr_free (expr);
421 return codegen_error_p () ? NULL_TREE
422 : fold_build1 (NEGATE_EXPR, type, tree_expr);
425 /* Converts an isl_ast_expr_op expression E with unknown number of arguments
426 to a GCC expression tree of type TYPE. */
428 tree translate_isl_ast_to_gimple::
429 nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
431 enum tree_code op_code;
432 switch (isl_ast_expr_get_op_type (expr))
434 case isl_ast_op_max:
435 op_code = MAX_EXPR;
436 break;
438 case isl_ast_op_min:
439 op_code = MIN_EXPR;
440 break;
442 default:
443 gcc_unreachable ();
445 isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
446 tree res = gcc_expression_from_isl_expression (type, arg_expr, ip);
448 if (codegen_error_p ())
450 isl_ast_expr_free (expr);
451 return NULL_TREE;
454 int i;
455 for (i = 1; i < isl_ast_expr_get_op_n_arg (expr); i++)
457 arg_expr = isl_ast_expr_get_op_arg (expr, i);
458 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
460 if (codegen_error_p ())
462 isl_ast_expr_free (expr);
463 return NULL_TREE;
466 res = fold_build2 (op_code, type, res, t);
468 isl_ast_expr_free (expr);
469 return res;
472 /* Converts an isl_ast_expr_op expression E to a GCC expression tree of
473 type TYPE. */
475 tree translate_isl_ast_to_gimple::
476 gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
477 ivs_params &ip)
479 if (codegen_error_p ())
481 isl_ast_expr_free (expr);
482 return NULL_TREE;
485 gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
486 switch (isl_ast_expr_get_op_type (expr))
488 /* These isl ast expressions are not supported yet. */
489 case isl_ast_op_error:
490 case isl_ast_op_call:
491 case isl_ast_op_and_then:
492 case isl_ast_op_or_else:
493 gcc_unreachable ();
495 case isl_ast_op_max:
496 case isl_ast_op_min:
497 return nary_op_to_tree (type, expr, ip);
499 case isl_ast_op_add:
500 case isl_ast_op_sub:
501 case isl_ast_op_mul:
502 case isl_ast_op_div:
503 case isl_ast_op_pdiv_q:
504 case isl_ast_op_pdiv_r:
505 case isl_ast_op_fdiv_q:
506 case isl_ast_op_zdiv_r:
507 case isl_ast_op_and:
508 case isl_ast_op_or:
509 case isl_ast_op_eq:
510 case isl_ast_op_le:
511 case isl_ast_op_lt:
512 case isl_ast_op_ge:
513 case isl_ast_op_gt:
514 return binary_op_to_tree (type, expr, ip);
516 case isl_ast_op_minus:
517 return unary_op_to_tree (type, expr, ip);
519 case isl_ast_op_cond:
520 case isl_ast_op_select:
521 return ternary_op_to_tree (type, expr, ip);
523 default:
524 gcc_unreachable ();
527 return NULL_TREE;
530 /* Converts an isl AST expression E back to a GCC expression tree of
531 type TYPE. */
533 tree translate_isl_ast_to_gimple::
534 gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
535 ivs_params &ip)
537 if (codegen_error_p ())
539 isl_ast_expr_free (expr);
540 return NULL_TREE;
543 switch (isl_ast_expr_get_type (expr))
545 case isl_ast_expr_id:
546 return gcc_expression_from_isl_ast_expr_id (type, expr, ip);
548 case isl_ast_expr_int:
549 return gcc_expression_from_isl_expr_int (type, expr);
551 case isl_ast_expr_op:
552 return gcc_expression_from_isl_expr_op (type, expr, ip);
554 default:
555 gcc_unreachable ();
558 return NULL_TREE;
561 /* Creates a new LOOP corresponding to isl_ast_node_for. Inserts an
562 induction variable for the new LOOP. New LOOP is attached to CFG
563 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
564 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
565 isl's scattering name to the induction variable created for the
566 loop of STMT. The new induction variable is inserted in the NEWIVS
567 vector and is of type TYPE. */
569 struct loop *translate_isl_ast_to_gimple::
570 graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
571 loop_p outer, tree type, tree lb, tree ub,
572 ivs_params &ip)
574 isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
575 tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
577 /* To fail code generation, we generate wrong code until we discard it. */
578 if (codegen_error_p ())
579 stride = integer_zero_node;
581 tree ivvar = create_tmp_var (type, "graphite_IV");
582 tree iv, iv_after_increment;
583 loop_p loop = create_empty_loop_on_edge
584 (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
585 outer ? outer : entry_edge->src->loop_father);
587 isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
588 isl_id *id = isl_ast_expr_get_id (for_iterator);
589 std::map<isl_id *, tree>::iterator res;
590 res = ip.find (id);
591 if (ip.count (id))
592 isl_id_free (res->first);
593 ip[id] = iv;
594 isl_ast_expr_free (for_iterator);
595 return loop;
598 /* Create the loop for a isl_ast_node_for.
600 - NEXT_E is the edge where new generated code should be attached. */
602 edge translate_isl_ast_to_gimple::
603 translate_isl_ast_for_loop (loop_p context_loop,
604 __isl_keep isl_ast_node *node_for, edge next_e,
605 tree type, tree lb, tree ub,
606 ivs_params &ip)
608 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
609 struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
610 type, lb, ub, ip);
611 edge last_e = single_exit (loop);
612 edge to_body = single_succ_edge (loop->header);
613 basic_block after = to_body->dest;
615 /* Translate the body of the loop. */
616 isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
617 next_e = translate_isl_ast (loop, for_body, to_body, ip);
618 isl_ast_node_free (for_body);
620 /* Early return if we failed to translate loop body. */
621 if (!next_e || codegen_error_p ())
622 return NULL;
624 if (next_e->dest != after)
625 redirect_edge_succ_nodup (next_e, after);
626 set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
628 if (flag_loop_parallelize_all)
630 isl_id *id = isl_ast_node_get_annotation (node_for);
631 gcc_assert (id);
632 ast_build_info *for_info = (ast_build_info *) isl_id_get_user (id);
633 loop->can_be_parallel = for_info->is_parallelizable;
634 free (for_info);
635 isl_id_free (id);
638 return last_e;
641 /* We use this function to get the upper bound because of the form,
642 which is used by isl to represent loops:
644 for (iterator = init; cond; iterator += inc)
652 The loop condition is an arbitrary expression, which contains the
653 current loop iterator.
655 (e.g. iterator + 3 < B && C > iterator + A)
657 We have to know the upper bound of the iterator to generate a loop
658 in Gimple form. It can be obtained from the special representation
659 of the loop condition, which is generated by isl,
660 if the ast_build_atomic_upper_bound option is set. In this case,
661 isl generates a loop condition that consists of the current loop
662 iterator, + an operator (< or <=) and an expression not involving
663 the iterator, which is processed and returned by this function.
665 (e.g iterator <= upper-bound-expression-without-iterator) */
667 static __isl_give isl_ast_expr *
668 get_upper_bound (__isl_keep isl_ast_node *node_for)
670 gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
671 isl_ast_expr *for_cond = isl_ast_node_for_get_cond (node_for);
672 gcc_assert (isl_ast_expr_get_type (for_cond) == isl_ast_expr_op);
673 isl_ast_expr *res;
674 switch (isl_ast_expr_get_op_type (for_cond))
676 case isl_ast_op_le:
677 res = isl_ast_expr_get_op_arg (for_cond, 1);
678 break;
680 case isl_ast_op_lt:
682 /* (iterator < ub) => (iterator <= ub - 1). */
683 isl_val *one =
684 isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
685 isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
686 res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
687 break;
690 default:
691 gcc_unreachable ();
693 isl_ast_expr_free (for_cond);
694 return res;
697 /* Translates an isl_ast_node_for to Gimple. */
699 edge translate_isl_ast_to_gimple::
700 translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
701 edge next_e, ivs_params &ip)
703 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
704 tree type
705 = build_nonstandard_integer_type (graphite_expression_type_precision, 0);
707 isl_ast_expr *for_init = isl_ast_node_for_get_init (node);
708 tree lb = gcc_expression_from_isl_expression (type, for_init, ip);
709 /* To fail code generation, we generate wrong code until we discard it. */
710 if (codegen_error_p ())
711 lb = integer_zero_node;
713 isl_ast_expr *upper_bound = get_upper_bound (node);
714 tree ub = gcc_expression_from_isl_expression (type, upper_bound, ip);
715 /* To fail code generation, we generate wrong code until we discard it. */
716 if (codegen_error_p ())
717 ub = integer_zero_node;
719 edge last_e = single_succ_edge (split_edge (next_e));
720 translate_isl_ast_for_loop (context_loop, node, next_e,
721 type, lb, ub, ip);
722 return last_e;
725 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the induction
726 variables of the loops around GBB in SESE.
728 FIXME: Instead of using a vec<tree> that maps each loop id to a possible
729 chrec, we could consider using a map<int, tree> that maps loop ids to the
730 corresponding tree expressions. */
732 void translate_isl_ast_to_gimple::
733 build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
734 __isl_keep isl_ast_expr *user_expr, ivs_params &ip,
735 sese_l &region)
737 gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
738 isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
739 int i;
740 isl_ast_expr *arg_expr;
741 for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
743 arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
744 tree type =
745 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
746 tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
748 /* To fail code generation, we generate wrong code until we discard it. */
749 if (codegen_error_p ())
750 t = integer_zero_node;
752 loop_p old_loop = gbb_loop_at_index (gbb, region, i - 2);
753 /* Record sth only for real loops. */
754 if (loop_in_sese_p (old_loop, region))
755 iv_map[old_loop->num] = t;
759 /* Translates an isl_ast_node_user to Gimple.
761 FIXME: We should remove iv_map.create (loop->num + 1), if it is possible. */
763 edge translate_isl_ast_to_gimple::
764 translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
765 edge next_e, ivs_params &ip)
767 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
769 isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
770 isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
771 gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
773 isl_id *name_id = isl_ast_expr_get_id (name_expr);
774 poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
775 gcc_assert (pbb);
777 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
779 isl_ast_expr_free (name_expr);
780 isl_id_free (name_id);
782 gcc_assert (GBB_BB (gbb) != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
783 "The entry block should not even appear within a scop");
785 const int nb_loops = number_of_loops (cfun);
786 vec<tree> iv_map;
787 iv_map.create (nb_loops);
788 iv_map.safe_grow_cleared (nb_loops);
790 build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
791 isl_ast_expr_free (user_expr);
793 basic_block old_bb = GBB_BB (gbb);
794 if (dump_file)
796 fprintf (dump_file,
797 "[codegen] copying from bb_%d on edge (bb_%d, bb_%d)\n",
798 old_bb->index, next_e->src->index, next_e->dest->index);
799 print_loops_bb (dump_file, GBB_BB (gbb), 0, 3);
803 next_e = copy_bb_and_scalar_dependences (old_bb, next_e, iv_map);
805 iv_map.release ();
807 if (codegen_error_p ())
808 return NULL;
810 if (dump_file)
812 fprintf (dump_file, "[codegen] (after copy) new basic block\n");
813 print_loops_bb (dump_file, next_e->src, 0, 3);
816 return next_e;
819 /* Translates an isl_ast_node_block to Gimple. */
821 edge translate_isl_ast_to_gimple::
822 translate_isl_ast_node_block (loop_p context_loop,
823 __isl_keep isl_ast_node *node,
824 edge next_e, ivs_params &ip)
826 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
827 isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
828 int i;
829 for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
831 isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
832 next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
833 isl_ast_node_free (tmp_node);
835 isl_ast_node_list_free (node_list);
836 return next_e;
839 /* Creates a new if region corresponding to isl's cond. */
841 edge translate_isl_ast_to_gimple::
842 graphite_create_new_guard (edge entry_edge, __isl_take isl_ast_expr *if_cond,
843 ivs_params &ip)
845 tree type =
846 build_nonstandard_integer_type (graphite_expression_type_precision, 0);
847 tree cond_expr = gcc_expression_from_isl_expression (type, if_cond, ip);
849 /* To fail code generation, we generate wrong code until we discard it. */
850 if (codegen_error_p ())
851 cond_expr = integer_zero_node;
853 edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
854 return exit_edge;
857 /* Translates an isl_ast_node_if to Gimple. */
859 edge translate_isl_ast_to_gimple::
860 translate_isl_ast_node_if (loop_p context_loop,
861 __isl_keep isl_ast_node *node,
862 edge next_e, ivs_params &ip)
864 gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_if);
865 isl_ast_expr *if_cond = isl_ast_node_if_get_cond (node);
866 edge last_e = graphite_create_new_guard (next_e, if_cond, ip);
867 edge true_e = get_true_edge_from_guard_bb (next_e->dest);
868 merge_points.safe_push (last_e);
870 isl_ast_node *then_node = isl_ast_node_if_get_then (node);
871 translate_isl_ast (context_loop, then_node, true_e, ip);
872 isl_ast_node_free (then_node);
874 edge false_e = get_false_edge_from_guard_bb (next_e->dest);
875 isl_ast_node *else_node = isl_ast_node_if_get_else (node);
876 if (isl_ast_node_get_type (else_node) != isl_ast_node_error)
877 translate_isl_ast (context_loop, else_node, false_e, ip);
879 isl_ast_node_free (else_node);
880 return last_e;
883 /* Translates an isl AST node NODE to GCC representation in the
884 context of a SESE. */
886 edge translate_isl_ast_to_gimple::
887 translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
888 edge next_e, ivs_params &ip)
890 if (codegen_error_p ())
891 return NULL;
893 switch (isl_ast_node_get_type (node))
895 case isl_ast_node_error:
896 gcc_unreachable ();
898 case isl_ast_node_for:
899 return translate_isl_ast_node_for (context_loop, node,
900 next_e, ip);
902 case isl_ast_node_if:
903 return translate_isl_ast_node_if (context_loop, node,
904 next_e, ip);
906 case isl_ast_node_user:
907 return translate_isl_ast_node_user (node, next_e, ip);
909 case isl_ast_node_block:
910 return translate_isl_ast_node_block (context_loop, node,
911 next_e, ip);
913 case isl_ast_node_mark:
915 isl_ast_node *n = isl_ast_node_mark_get_node (node);
916 edge e = translate_isl_ast (context_loop, n, next_e, ip);
917 isl_ast_node_free (n);
918 return e;
921 default:
922 gcc_unreachable ();
926 /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR).
927 When OLD_NAME and EXPR are the same we assert. */
929 void translate_isl_ast_to_gimple::
930 set_rename (tree old_name, tree expr)
932 if (dump_file)
934 fprintf (dump_file, "[codegen] setting rename: old_name = ");
935 print_generic_expr (dump_file, old_name);
936 fprintf (dump_file, ", new_name = ");
937 print_generic_expr (dump_file, expr);
938 fprintf (dump_file, "\n");
941 if (old_name == expr)
942 return;
944 vec <tree> *renames = region->rename_map->get (old_name);
946 if (renames)
947 renames->safe_push (expr);
948 else
950 vec<tree> r;
951 r.create (2);
952 r.safe_push (expr);
953 region->rename_map->put (old_name, r);
956 tree t;
957 int i;
958 /* For a parameter of a scop we don't want to rename it. */
959 FOR_EACH_VEC_ELT (region->params, i, t)
960 if (old_name == t)
961 region->parameter_rename_map->put(old_name, expr);
964 /* Return an iterator to the instructions comes last in the execution order.
965 Either GSI1 and GSI2 should belong to the same basic block or one of their
966 respective basic blocks should dominate the other. */
968 gimple_stmt_iterator
969 later_of_the_two (gimple_stmt_iterator gsi1, gimple_stmt_iterator gsi2)
971 basic_block bb1 = gsi_bb (gsi1);
972 basic_block bb2 = gsi_bb (gsi2);
974 /* Find the iterator which is the latest. */
975 if (bb1 == bb2)
977 gimple *stmt1 = gsi_stmt (gsi1);
978 gimple *stmt2 = gsi_stmt (gsi2);
980 if (stmt1 != NULL && stmt2 != NULL)
982 bool is_phi1 = gimple_code (stmt1) == GIMPLE_PHI;
983 bool is_phi2 = gimple_code (stmt2) == GIMPLE_PHI;
985 if (is_phi1 != is_phi2)
986 return is_phi1 ? gsi2 : gsi1;
989 /* For empty basic blocks gsis point to the end of the sequence. Since
990 there is no operator== defined for gimple_stmt_iterator and for gsis
991 not pointing to a valid statement gsi_next would assert. */
992 gimple_stmt_iterator gsi = gsi1;
993 do {
994 if (gsi_stmt (gsi) == gsi_stmt (gsi2))
995 return gsi2;
996 gsi_next (&gsi);
997 } while (!gsi_end_p (gsi));
999 return gsi1;
1002 /* Find the basic block closest to the basic block which defines stmt. */
1003 if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
1004 return gsi1;
1006 gcc_assert (dominated_by_p (CDI_DOMINATORS, bb2, bb1));
1007 return gsi2;
1010 /* Insert each statement from SEQ at its earliest insertion p. */
1012 void translate_isl_ast_to_gimple::
1013 gsi_insert_earliest (gimple_seq seq)
1015 update_modified_stmts (seq);
1016 sese_l &codegen_region = region->if_region->true_region->region;
1017 basic_block begin_bb = get_entry_bb (codegen_region);
1019 /* Inserting the gimple statements in a vector because gimple_seq behave
1020 in strage ways when inserting the stmts from it into different basic
1021 blocks one at a time. */
1022 auto_vec<gimple *, 3> stmts;
1023 for (gimple_stmt_iterator gsi = gsi_start (seq); !gsi_end_p (gsi);
1024 gsi_next (&gsi))
1025 stmts.safe_push (gsi_stmt (gsi));
1027 int i;
1028 gimple *use_stmt;
1029 FOR_EACH_VEC_ELT (stmts, i, use_stmt)
1031 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1032 gimple_stmt_iterator gsi_def_stmt = gsi_start_bb_nondebug (begin_bb);
1034 use_operand_p use_p;
1035 ssa_op_iter op_iter;
1036 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, op_iter, SSA_OP_USE)
1038 /* Iterator to the current def of use_p. For function parameters or
1039 anything where def is not found, insert at the beginning of the
1040 generated region. */
1041 gimple_stmt_iterator gsi_stmt = gsi_def_stmt;
1043 tree op = USE_FROM_PTR (use_p);
1044 gimple *stmt = SSA_NAME_DEF_STMT (op);
1045 if (stmt && (gimple_code (stmt) != GIMPLE_NOP))
1046 gsi_stmt = gsi_for_stmt (stmt);
1048 /* For region parameters, insert at the beginning of the generated
1049 region. */
1050 if (!bb_in_sese_p (gsi_bb (gsi_stmt), codegen_region))
1051 gsi_stmt = gsi_def_stmt;
1053 gsi_def_stmt = later_of_the_two (gsi_stmt, gsi_def_stmt);
1056 if (!gsi_stmt (gsi_def_stmt))
1058 gimple_stmt_iterator gsi = gsi_after_labels (gsi_bb (gsi_def_stmt));
1059 gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
1061 else if (gimple_code (gsi_stmt (gsi_def_stmt)) == GIMPLE_PHI)
1063 gimple_stmt_iterator bsi
1064 = gsi_start_bb_nondebug (gsi_bb (gsi_def_stmt));
1065 /* Insert right after the PHI statements. */
1066 gsi_insert_before (&bsi, use_stmt, GSI_NEW_STMT);
1068 else
1069 gsi_insert_after (&gsi_def_stmt, use_stmt, GSI_NEW_STMT);
1071 if (dump_file)
1073 fprintf (dump_file, "[codegen] inserting statement: ");
1074 print_gimple_stmt (dump_file, use_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
1075 print_loops_bb (dump_file, gimple_bb (use_stmt), 0, 3);
1080 /* For ops which are scev_analyzeable, we can regenerate a new name from its
1081 scalar evolution around LOOP. */
1083 tree translate_isl_ast_to_gimple::
1084 get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
1085 basic_block new_bb, basic_block,
1086 vec<tree> iv_map)
1088 tree scev = scalar_evolution_in_region (region->region, loop, old_name);
1090 /* At this point we should know the exact scev for each
1091 scalar SSA_NAME used in the scop: all the other scalar
1092 SSA_NAMEs should have been translated out of SSA using
1093 arrays with one element. */
1094 tree new_expr;
1095 if (chrec_contains_undetermined (scev))
1097 set_codegen_error ();
1098 return build_zero_cst (TREE_TYPE (old_name));
1101 new_expr = chrec_apply_map (scev, iv_map);
1103 /* The apply should produce an expression tree containing
1104 the uses of the new induction variables. We should be
1105 able to use new_expr instead of the old_name in the newly
1106 generated loop nest. */
1107 if (chrec_contains_undetermined (new_expr)
1108 || tree_contains_chrecs (new_expr, NULL))
1110 set_codegen_error ();
1111 return build_zero_cst (TREE_TYPE (old_name));
1114 if (TREE_CODE (new_expr) == SSA_NAME)
1116 basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (new_expr));
1117 if (bb && !dominated_by_p (CDI_DOMINATORS, new_bb, bb))
1119 set_codegen_error ();
1120 return build_zero_cst (TREE_TYPE (old_name));
1124 /* Replace the old_name with the new_expr. */
1125 return force_gimple_operand (unshare_expr (new_expr), stmts,
1126 true, NULL_TREE);
1130 /* Return true if STMT should be copied from region to the new code-generated
1131 region. LABELs, CONDITIONS, induction-variables and region parameters need
1132 not be copied. */
1134 static bool
1135 should_copy_to_new_region (gimple *stmt, sese_info_p region)
1137 /* Do not copy labels or conditions. */
1138 if (gimple_code (stmt) == GIMPLE_LABEL
1139 || gimple_code (stmt) == GIMPLE_COND)
1140 return false;
1142 tree lhs;
1143 /* Do not copy induction variables. */
1144 if (is_gimple_assign (stmt)
1145 && (lhs = gimple_assign_lhs (stmt))
1146 && TREE_CODE (lhs) == SSA_NAME
1147 && is_gimple_reg (lhs)
1148 && scev_analyzable_p (lhs, region->region))
1149 return false;
1151 /* Do not copy parameters that have been generated in the header of the
1152 scop. */
1153 if (is_gimple_assign (stmt)
1154 && (lhs = gimple_assign_lhs (stmt))
1155 && TREE_CODE (lhs) == SSA_NAME
1156 && region->parameter_rename_map->get(lhs))
1157 return false;
1159 return true;
1162 /* Create new names for all the definitions created by COPY and add replacement
1163 mappings for each new name. */
1165 void translate_isl_ast_to_gimple::
1166 set_rename_for_each_def (gimple *stmt)
1168 def_operand_p def_p;
1169 ssa_op_iter op_iter;
1170 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_ALL_DEFS)
1172 tree old_name = DEF_FROM_PTR (def_p);
1173 create_new_def_for (old_name, stmt, def_p);
1177 /* Duplicates the statements of basic block BB into basic block NEW_BB
1178 and compute the new induction variables according to the IV_MAP. */
1180 bool translate_isl_ast_to_gimple::
1181 graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
1182 vec<tree> iv_map)
1184 /* Iterator poining to the place where new statement (s) will be inserted. */
1185 gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
1187 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1188 gsi_next (&gsi))
1190 gimple *stmt = gsi_stmt (gsi);
1191 if (!should_copy_to_new_region (stmt, region))
1192 continue;
1194 /* Create a new copy of STMT and duplicate STMT's virtual
1195 operands. */
1196 gimple *copy = gimple_copy (stmt);
1197 gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
1199 /* Rather than not copying debug stmts we reset them.
1200 ??? Where we can rewrite uses without inserting new
1201 stmts we could simply do that. */
1202 if (is_gimple_debug (copy))
1204 if (gimple_debug_bind_p (copy))
1205 gimple_debug_bind_reset_value (copy);
1206 else if (gimple_debug_source_bind_p (copy))
1208 else
1209 gcc_unreachable ();
1212 if (dump_file)
1214 fprintf (dump_file, "[codegen] inserting statement: ");
1215 print_gimple_stmt (dump_file, copy, 0);
1218 maybe_duplicate_eh_stmt (copy, stmt);
1219 gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
1221 /* Crete new names for each def in the copied stmt. */
1222 set_rename_for_each_def (copy);
1224 if (codegen_error_p ())
1225 return false;
1227 /* For each SSA_NAME in the parameter_rename_map rename their usage. */
1228 ssa_op_iter iter;
1229 use_operand_p use_p;
1230 if (!is_gimple_debug (copy))
1231 FOR_EACH_SSA_USE_OPERAND (use_p, copy, iter, SSA_OP_USE)
1233 tree old_name = USE_FROM_PTR (use_p);
1235 if (TREE_CODE (old_name) != SSA_NAME
1236 || SSA_NAME_IS_DEFAULT_DEF (old_name))
1237 continue;
1239 tree *new_expr = region->parameter_rename_map->get (old_name);
1240 tree new_name;
1241 if (!new_expr
1242 && scev_analyzable_p (old_name, region->region))
1244 gimple_seq stmts = NULL;
1245 new_name = get_rename_from_scev (old_name, &stmts,
1246 bb->loop_father,
1247 new_bb, bb, iv_map);
1248 if (! codegen_error_p ())
1249 gsi_insert_earliest (stmts);
1250 new_expr = &new_name;
1253 if (!new_expr)
1254 continue;
1256 replace_exp (use_p, *new_expr);
1259 update_stmt (copy);
1262 return true;
1266 /* Copies BB and includes in the copied BB all the statements that can
1267 be reached following the use-def chains from the memory accesses,
1268 and returns the next edge following this new block. */
1270 edge translate_isl_ast_to_gimple::
1271 copy_bb_and_scalar_dependences (basic_block bb, edge next_e, vec<tree> iv_map)
1273 basic_block new_bb = split_edge (next_e);
1274 gimple_stmt_iterator gsi_tgt = gsi_last_bb (new_bb);
1275 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
1276 gsi_next (&psi))
1278 gphi *phi = psi.phi ();
1279 tree res = gimple_phi_result (phi);
1280 if (virtual_operand_p (res)
1281 || scev_analyzable_p (res, region->region))
1282 continue;
1284 tree new_phi_def;
1285 vec <tree> *renames = region->rename_map->get (res);
1286 if (! renames || renames->is_empty ())
1288 new_phi_def = create_tmp_reg (TREE_TYPE (res));
1289 set_rename (res, new_phi_def);
1291 else
1293 gcc_assert (renames->length () == 1);
1294 new_phi_def = (*renames)[0];
1297 gassign *ass = gimple_build_assign (NULL_TREE, new_phi_def);
1298 create_new_def_for (res, ass, NULL);
1299 gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
1302 vec <basic_block> *copied_bbs = region->copied_bb_map->get (bb);
1303 if (copied_bbs)
1304 copied_bbs->safe_push (new_bb);
1305 else
1307 vec<basic_block> bbs;
1308 bbs.create (2);
1309 bbs.safe_push (new_bb);
1310 region->copied_bb_map->put (bb, bbs);
1313 if (!graphite_copy_stmts_from_block (bb, new_bb, iv_map))
1315 set_codegen_error ();
1316 return NULL;
1319 /* Insert out-of SSA copies on the original BB outgoing edges. */
1320 gsi_tgt = gsi_last_bb (new_bb);
1321 basic_block bb_for_succs = bb;
1322 if (bb_for_succs == bb_for_succs->loop_father->latch
1323 && bb_in_sese_p (bb_for_succs, region->region)
1324 && sese_trivially_empty_bb_p (bb_for_succs))
1325 bb_for_succs = NULL;
1326 while (bb_for_succs)
1328 basic_block latch = NULL;
1329 edge_iterator ei;
1330 edge e;
1331 FOR_EACH_EDGE (e, ei, bb_for_succs->succs)
1333 for (gphi_iterator psi = gsi_start_phis (e->dest); !gsi_end_p (psi);
1334 gsi_next (&psi))
1336 gphi *phi = psi.phi ();
1337 tree res = gimple_phi_result (phi);
1338 if (virtual_operand_p (res)
1339 || scev_analyzable_p (res, region->region))
1340 continue;
1342 tree new_phi_def;
1343 vec <tree> *renames = region->rename_map->get (res);
1344 if (! renames || renames->is_empty ())
1346 new_phi_def = create_tmp_reg (TREE_TYPE (res));
1347 set_rename (res, new_phi_def);
1349 else
1351 gcc_assert (renames->length () == 1);
1352 new_phi_def = (*renames)[0];
1355 tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
1356 if (TREE_CODE (arg) == SSA_NAME
1357 && scev_analyzable_p (arg, region->region))
1359 gimple_seq stmts = NULL;
1360 tree new_name = get_rename_from_scev (arg, &stmts,
1361 bb->loop_father,
1362 new_bb, bb, iv_map);
1363 if (! codegen_error_p ())
1364 gsi_insert_earliest (stmts);
1365 arg = new_name;
1367 gassign *ass = gimple_build_assign (new_phi_def, arg);
1368 gsi_insert_after (&gsi_tgt, ass, GSI_NEW_STMT);
1370 if (e->dest == bb_for_succs->loop_father->latch
1371 && bb_in_sese_p (e->dest, region->region)
1372 && sese_trivially_empty_bb_p (e->dest))
1373 latch = e->dest;
1375 bb_for_succs = latch;
1378 return single_succ_edge (new_bb);
1381 /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
1383 void translate_isl_ast_to_gimple::
1384 add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
1386 sese_info_p region = scop->scop_info;
1387 unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
1388 gcc_assert (nb_parameters == region->params.length ());
1389 unsigned i;
1390 for (i = 0; i < nb_parameters; i++)
1392 isl_id *tmp_id = isl_set_get_dim_id (scop->param_context,
1393 isl_dim_param, i);
1394 ip[tmp_id] = region->params[i];
1399 /* Generates a build, which specifies the constraints on the parameters. */
1401 __isl_give isl_ast_build *translate_isl_ast_to_gimple::
1402 generate_isl_context (scop_p scop)
1404 isl_set *context_isl = isl_set_params (isl_set_copy (scop->param_context));
1405 return isl_ast_build_from_context (context_isl);
1408 /* This method is executed before the construction of a for node. */
1409 __isl_give isl_id *
1410 ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
1412 isl_union_map *dependences = (isl_union_map *) user;
1413 ast_build_info *for_info = XNEW (struct ast_build_info);
1414 isl_union_map *schedule = isl_ast_build_get_schedule (build);
1415 isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
1416 int dimension = isl_space_dim (schedule_space, isl_dim_out);
1417 for_info->is_parallelizable =
1418 !carries_deps (schedule, dependences, dimension);
1419 isl_union_map_free (schedule);
1420 isl_space_free (schedule_space);
1421 isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
1422 return id;
1425 /* Generate isl AST from schedule of SCOP. */
1427 __isl_give isl_ast_node *translate_isl_ast_to_gimple::
1428 scop_to_isl_ast (scop_p scop)
1430 gcc_assert (scop->transformed_schedule);
1432 /* Set the separate option to reduce control flow overhead. */
1433 isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
1434 (isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
1435 isl_ast_build *context_isl = generate_isl_context (scop);
1437 if (flag_loop_parallelize_all)
1439 scop_get_dependences (scop);
1440 context_isl =
1441 isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
1442 scop->dependence);
1445 isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
1446 (context_isl, schedule);
1447 isl_ast_build_free (context_isl);
1448 return ast_isl;
1451 /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
1452 DEF_STMT. GSI points to entry basic block of the TO_REGION. */
1454 static void
1455 copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
1456 gimple_stmt_iterator *gsi)
1458 if (!defined_in_sese_p (tr, region->region))
1459 return;
1461 ssa_op_iter iter;
1462 use_operand_p use_p;
1463 FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
1465 tree use_tr = USE_FROM_PTR (use_p);
1467 /* Do not copy parameters that have been generated in the header of the
1468 scop. */
1469 if (region->parameter_rename_map->get(use_tr))
1470 continue;
1472 gimple *def_of_use = SSA_NAME_DEF_STMT (use_tr);
1473 if (!def_of_use)
1474 continue;
1476 copy_def (use_tr, def_of_use, region, to_region, gsi);
1479 gimple *copy = gimple_copy (def_stmt);
1480 gsi_insert_after (gsi, copy, GSI_NEW_STMT);
1482 /* Create new names for all the definitions created by COPY and
1483 add replacement mappings for each new name. */
1484 def_operand_p def_p;
1485 ssa_op_iter op_iter;
1486 FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
1488 tree old_name = DEF_FROM_PTR (def_p);
1489 tree new_name = create_new_def_for (old_name, copy, def_p);
1490 region->parameter_rename_map->put(old_name, new_name);
1493 update_stmt (copy);
1496 static void
1497 copy_internal_parameters (sese_info_p region, sese_info_p to_region)
1499 /* For all the parameters which definitino is in the if_region->false_region,
1500 insert code on true_region (if_region->true_region->entry). */
1502 int i;
1503 tree tr;
1504 gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
1506 FOR_EACH_VEC_ELT (region->params, i, tr)
1508 // If def is not in region.
1509 gimple *def_stmt = SSA_NAME_DEF_STMT (tr);
1510 if (def_stmt)
1511 copy_def (tr, def_stmt, region, to_region, &gsi);
1515 /* GIMPLE Loop Generator: generates loops in GIMPLE form for the given SCOP.
1516 Return true if code generation succeeded. */
1518 bool
1519 graphite_regenerate_ast_isl (scop_p scop)
1521 sese_info_p region = scop->scop_info;
1522 translate_isl_ast_to_gimple t (region);
1524 ifsese if_region = NULL;
1525 isl_ast_node *root_node;
1526 ivs_params ip;
1528 timevar_push (TV_GRAPHITE_CODE_GEN);
1529 t.add_parameters_to_ivs_params (scop, ip);
1530 root_node = t.scop_to_isl_ast (scop);
1532 if (dump_file && (dump_flags & TDF_DETAILS))
1534 fprintf (dump_file, "[scheduler] original schedule:\n");
1535 print_isl_schedule (dump_file, scop->original_schedule);
1536 fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
1537 print_isl_schedule (dump_file, scop->transformed_schedule);
1539 fprintf (dump_file, "[scheduler] original ast:\n");
1540 print_schedule_ast (dump_file, scop->original_schedule, scop);
1541 fprintf (dump_file, "[scheduler] AST generated by isl:\n");
1542 print_isl_ast (dump_file, root_node);
1545 if_region = move_sese_in_condition (region);
1546 region->if_region = if_region;
1548 loop_p context_loop = region->region.entry->src->loop_father;
1550 /* Copy all the parameters which are defined in the region. */
1551 copy_internal_parameters(if_region->false_region, if_region->true_region);
1553 edge e = single_succ_edge (if_region->true_region->region.entry->dest);
1554 basic_block bb = split_edge (e);
1556 /* Update the true_region exit edge. */
1557 region->if_region->true_region->region.exit = single_succ_edge (bb);
1559 t.translate_isl_ast (context_loop, root_node, e, ip);
1560 if (! t.codegen_error_p ())
1562 sese_insert_phis_for_liveouts (region,
1563 if_region->region->region.exit->src,
1564 if_region->false_region->region.exit,
1565 if_region->true_region->region.exit);
1566 if (dump_file)
1567 fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
1569 mark_virtual_operands_for_renaming (cfun);
1570 update_ssa (TODO_update_ssa);
1571 checking_verify_ssa (true, true);
1572 rewrite_into_loop_closed_ssa (NULL, 0);
1575 if (t.codegen_error_p ())
1577 if (dump_file)
1578 fprintf (dump_file, "codegen error: "
1579 "reverting back to the original code.\n");
1580 set_ifsese_condition (if_region, integer_zero_node);
1582 /* We registered new names, scrap that. */
1583 if (need_ssa_update_p (cfun))
1584 delete_update_ssa ();
1585 /* Remove the unreachable region. */
1586 remove_edge_and_dominated_blocks (if_region->true_region->region.entry);
1587 basic_block ifb = if_region->false_region->region.entry->src;
1588 gimple_stmt_iterator gsi = gsi_last_bb (ifb);
1589 gsi_remove (&gsi, true);
1590 if_region->false_region->region.entry->flags &= ~EDGE_FALSE_VALUE;
1591 if_region->false_region->region.entry->flags |= EDGE_FALLTHRU;
1592 /* remove_edge_and_dominated_blocks marks loops for removal but
1593 doesn't actually remove them (fix that...). */
1594 loop_p loop;
1595 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
1596 if (! loop->header)
1597 delete_loop (loop);
1600 /* Verifies properties that GRAPHITE should maintain during translation. */
1601 checking_verify_loop_structure ();
1602 checking_verify_loop_closed_ssa (true);
1604 free (if_region->true_region);
1605 free (if_region->region);
1606 free (if_region);
1608 ivs_params_clear (ip);
1609 isl_ast_node_free (root_node);
1610 timevar_pop (TV_GRAPHITE_CODE_GEN);
1612 return !t.codegen_error_p ();
1615 #endif /* HAVE_isl */