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