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