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