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