Home | History | Annotate | Line # | Download | only in gcc
      1  1.1  mrg /* Routines for reading GIMPLE from a file stream.
      2  1.1  mrg 
      3  1.1  mrg    Copyright (C) 2011-2022 Free Software Foundation, Inc.
      4  1.1  mrg    Contributed by Diego Novillo <dnovillo (at) google.com>
      5  1.1  mrg 
      6  1.1  mrg This file is part of GCC.
      7  1.1  mrg 
      8  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      9  1.1  mrg the terms of the GNU General Public License as published by the Free
     10  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     11  1.1  mrg version.
     12  1.1  mrg 
     13  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     14  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     15  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     16  1.1  mrg for more details.
     17  1.1  mrg 
     18  1.1  mrg You should have received a copy of the GNU General Public License
     19  1.1  mrg along with GCC; see the file COPYING3.  If not see
     20  1.1  mrg <http://www.gnu.org/licenses/>.  */
     21  1.1  mrg 
     22  1.1  mrg #include "config.h"
     23  1.1  mrg #include "system.h"
     24  1.1  mrg #include "coretypes.h"
     25  1.1  mrg #include "backend.h"
     26  1.1  mrg #include "tree.h"
     27  1.1  mrg #include "gimple.h"
     28  1.1  mrg #include "ssa.h"
     29  1.1  mrg #include "gimple-streamer.h"
     30  1.1  mrg #include "tree-eh.h"
     31  1.1  mrg #include "gimple-iterator.h"
     32  1.1  mrg #include "cgraph.h"
     33  1.1  mrg #include "value-prof.h"
     34  1.1  mrg 
     35  1.1  mrg /* Read a PHI function for basic block BB in function FN.  DATA_IN is
     36  1.1  mrg    the file being read.  IB is the input block to use for reading.  */
     37  1.1  mrg 
     38  1.1  mrg static gphi *
     39  1.1  mrg input_phi (class lto_input_block *ib, basic_block bb, class data_in *data_in,
     40  1.1  mrg 	   struct function *fn)
     41  1.1  mrg {
     42  1.1  mrg   unsigned HOST_WIDE_INT ix;
     43  1.1  mrg   tree phi_result;
     44  1.1  mrg   int i, len;
     45  1.1  mrg   gphi *result;
     46  1.1  mrg 
     47  1.1  mrg   ix = streamer_read_uhwi (ib);
     48  1.1  mrg   phi_result = (*SSANAMES (fn))[ix];
     49  1.1  mrg   len = EDGE_COUNT (bb->preds);
     50  1.1  mrg   result = create_phi_node (phi_result, bb);
     51  1.1  mrg 
     52  1.1  mrg   /* We have to go through a lookup process here because the preds in the
     53  1.1  mrg      reconstructed graph are generally in a different order than they
     54  1.1  mrg      were in the original program.  */
     55  1.1  mrg   for (i = 0; i < len; i++)
     56  1.1  mrg     {
     57  1.1  mrg       tree def = stream_read_tree (ib, data_in);
     58  1.1  mrg       int src_index = streamer_read_uhwi (ib);
     59  1.1  mrg       bitpack_d bp = streamer_read_bitpack (ib);
     60  1.1  mrg       basic_block sbb = BASIC_BLOCK_FOR_FN (fn, src_index);
     61  1.1  mrg       edge e = NULL;
     62  1.1  mrg       int j;
     63  1.1  mrg 
     64  1.1  mrg       for (j = 0; j < len; j++)
     65  1.1  mrg 	if (EDGE_PRED (bb, j)->src == sbb)
     66  1.1  mrg 	  {
     67  1.1  mrg 	    e = EDGE_PRED (bb, j);
     68  1.1  mrg 	    break;
     69  1.1  mrg 	  }
     70  1.1  mrg 
     71  1.1  mrg       add_phi_arg (result, def, e, UNKNOWN_LOCATION);
     72  1.1  mrg       /* Read location and lexical block information.  */
     73  1.1  mrg       location_t *arg_locp = gimple_phi_arg_location_ptr (result, e->dest_idx);
     74  1.1  mrg       data_in->location_cache.input_location_and_block (arg_locp, &bp, ib,
     75  1.1  mrg 							data_in);
     76  1.1  mrg     }
     77  1.1  mrg 
     78  1.1  mrg   return result;
     79  1.1  mrg }
     80  1.1  mrg 
     81  1.1  mrg 
     82  1.1  mrg /* Read a statement with tag TAG in function FN from block IB using
     83  1.1  mrg    descriptors in DATA_IN.  */
     84  1.1  mrg 
     85  1.1  mrg static gimple *
     86  1.1  mrg input_gimple_stmt (class lto_input_block *ib, class data_in *data_in,
     87  1.1  mrg 		   enum LTO_tags tag)
     88  1.1  mrg {
     89  1.1  mrg   gimple *stmt;
     90  1.1  mrg   enum gimple_code code;
     91  1.1  mrg   unsigned HOST_WIDE_INT num_ops;
     92  1.1  mrg   size_t i;
     93  1.1  mrg   struct bitpack_d bp;
     94  1.1  mrg   bool has_hist;
     95  1.1  mrg 
     96  1.1  mrg   code = lto_tag_to_gimple_code (tag);
     97  1.1  mrg 
     98  1.1  mrg   /* Read the tuple header.  */
     99  1.1  mrg   bp = streamer_read_bitpack (ib);
    100  1.1  mrg   num_ops = bp_unpack_var_len_unsigned (&bp);
    101  1.1  mrg   stmt = gimple_alloc (code, num_ops);
    102  1.1  mrg   stmt->no_warning = bp_unpack_value (&bp, 1);
    103  1.1  mrg   if (is_gimple_assign (stmt))
    104  1.1  mrg     stmt->nontemporal_move = bp_unpack_value (&bp, 1);
    105  1.1  mrg   stmt->has_volatile_ops = bp_unpack_value (&bp, 1);
    106  1.1  mrg   has_hist = bp_unpack_value (&bp, 1);
    107  1.1  mrg   stmt->subcode = bp_unpack_var_len_unsigned (&bp);
    108  1.1  mrg 
    109  1.1  mrg   /* Read location and lexical block information.  */
    110  1.1  mrg   data_in->location_cache.input_location_and_block (gimple_location_ptr (stmt),
    111  1.1  mrg 						    &bp, ib, data_in);
    112  1.1  mrg 
    113  1.1  mrg   /* Read in all the operands.  */
    114  1.1  mrg   switch (code)
    115  1.1  mrg     {
    116  1.1  mrg     case GIMPLE_RESX:
    117  1.1  mrg       gimple_resx_set_region (as_a <gresx *> (stmt),
    118  1.1  mrg 			      streamer_read_hwi (ib));
    119  1.1  mrg       break;
    120  1.1  mrg 
    121  1.1  mrg     case GIMPLE_EH_MUST_NOT_THROW:
    122  1.1  mrg       gimple_eh_must_not_throw_set_fndecl (
    123  1.1  mrg 	as_a <geh_mnt *> (stmt),
    124  1.1  mrg 	stream_read_tree (ib, data_in));
    125  1.1  mrg       break;
    126  1.1  mrg 
    127  1.1  mrg     case GIMPLE_EH_DISPATCH:
    128  1.1  mrg       gimple_eh_dispatch_set_region (as_a <geh_dispatch *> (stmt),
    129  1.1  mrg 				     streamer_read_hwi (ib));
    130  1.1  mrg       break;
    131  1.1  mrg 
    132  1.1  mrg     case GIMPLE_ASM:
    133  1.1  mrg       {
    134  1.1  mrg 	/* FIXME lto.  Move most of this into a new gimple_asm_set_string().  */
    135  1.1  mrg 	gasm *asm_stmt = as_a <gasm *> (stmt);
    136  1.1  mrg 	tree str;
    137  1.1  mrg 	asm_stmt->ni = streamer_read_uhwi (ib);
    138  1.1  mrg 	asm_stmt->no = streamer_read_uhwi (ib);
    139  1.1  mrg 	asm_stmt->nc = streamer_read_uhwi (ib);
    140  1.1  mrg 	asm_stmt->nl = streamer_read_uhwi (ib);
    141  1.1  mrg 	str = streamer_read_string_cst (data_in, ib);
    142  1.1  mrg 	asm_stmt->string = TREE_STRING_POINTER (str);
    143  1.1  mrg       }
    144  1.1  mrg       /* Fallthru  */
    145  1.1  mrg 
    146  1.1  mrg     case GIMPLE_ASSIGN:
    147  1.1  mrg     case GIMPLE_CALL:
    148  1.1  mrg     case GIMPLE_RETURN:
    149  1.1  mrg     case GIMPLE_SWITCH:
    150  1.1  mrg     case GIMPLE_LABEL:
    151  1.1  mrg     case GIMPLE_COND:
    152  1.1  mrg     case GIMPLE_GOTO:
    153  1.1  mrg     case GIMPLE_DEBUG:
    154  1.1  mrg       for (i = 0; i < num_ops; i++)
    155  1.1  mrg 	{
    156  1.1  mrg 	  tree *opp, op = stream_read_tree (ib, data_in);
    157  1.1  mrg 	  gimple_set_op (stmt, i, op);
    158  1.1  mrg 	  if (!op)
    159  1.1  mrg 	    continue;
    160  1.1  mrg 
    161  1.1  mrg 	  opp = gimple_op_ptr (stmt, i);
    162  1.1  mrg 	  if (TREE_CODE (*opp) == ADDR_EXPR)
    163  1.1  mrg 	    opp = &TREE_OPERAND (*opp, 0);
    164  1.1  mrg 	  while (handled_component_p (*opp))
    165  1.1  mrg 	    opp = &TREE_OPERAND (*opp, 0);
    166  1.1  mrg 	  /* At LTO output time we wrap all global decls in MEM_REFs to
    167  1.1  mrg 	     allow seamless replacement with prevailing decls.  Undo this
    168  1.1  mrg 	     here if the prevailing decl allows for this.
    169  1.1  mrg 	     ???  Maybe we should simply fold all stmts.  */
    170  1.1  mrg 	  if (TREE_CODE (*opp) == MEM_REF
    171  1.1  mrg 	      && TREE_CODE (TREE_OPERAND (*opp, 0)) == ADDR_EXPR
    172  1.1  mrg 	      && integer_zerop (TREE_OPERAND (*opp, 1))
    173  1.1  mrg 	      && (TREE_THIS_VOLATILE (*opp)
    174  1.1  mrg 		  == TREE_THIS_VOLATILE
    175  1.1  mrg 		       (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0)))
    176  1.1  mrg 	      && !TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (*opp, 1)))
    177  1.1  mrg 	      && (TREE_TYPE (*opp)
    178  1.1  mrg 		  == TREE_TYPE (TREE_TYPE (TREE_OPERAND (*opp, 1))))
    179  1.1  mrg 	      && (TREE_TYPE (*opp)
    180  1.1  mrg 		  == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0))))
    181  1.1  mrg 	    *opp = TREE_OPERAND (TREE_OPERAND (*opp, 0), 0);
    182  1.1  mrg 	}
    183  1.1  mrg       if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
    184  1.1  mrg 	{
    185  1.1  mrg 	  if (gimple_call_internal_p (call_stmt))
    186  1.1  mrg 	    gimple_call_set_internal_fn
    187  1.1  mrg 	      (call_stmt, streamer_read_enum (ib, internal_fn, IFN_LAST));
    188  1.1  mrg 	  else
    189  1.1  mrg 	    gimple_call_set_fntype (call_stmt, stream_read_tree (ib, data_in));
    190  1.1  mrg 	}
    191  1.1  mrg       break;
    192  1.1  mrg 
    193  1.1  mrg     case GIMPLE_NOP:
    194  1.1  mrg     case GIMPLE_PREDICT:
    195  1.1  mrg       break;
    196  1.1  mrg 
    197  1.1  mrg     case GIMPLE_TRANSACTION:
    198  1.1  mrg       gimple_transaction_set_label_norm (as_a <gtransaction *> (stmt),
    199  1.1  mrg 				         stream_read_tree (ib, data_in));
    200  1.1  mrg       gimple_transaction_set_label_uninst (as_a <gtransaction *> (stmt),
    201  1.1  mrg 				           stream_read_tree (ib, data_in));
    202  1.1  mrg       gimple_transaction_set_label_over (as_a <gtransaction *> (stmt),
    203  1.1  mrg 				         stream_read_tree (ib, data_in));
    204  1.1  mrg       break;
    205  1.1  mrg 
    206  1.1  mrg     default:
    207  1.1  mrg       internal_error ("bytecode stream: unknown GIMPLE statement tag %s",
    208  1.1  mrg 		      lto_tag_name (tag));
    209  1.1  mrg     }
    210  1.1  mrg 
    211  1.1  mrg   /* Update the properties of symbols, SSA names and labels associated
    212  1.1  mrg      with STMT.  */
    213  1.1  mrg   if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
    214  1.1  mrg     {
    215  1.1  mrg       tree lhs = gimple_get_lhs (stmt);
    216  1.1  mrg       if (lhs && TREE_CODE (lhs) == SSA_NAME)
    217  1.1  mrg 	SSA_NAME_DEF_STMT (lhs) = stmt;
    218  1.1  mrg     }
    219  1.1  mrg   else if (code == GIMPLE_ASM)
    220  1.1  mrg     {
    221  1.1  mrg       gasm *asm_stmt = as_a <gasm *> (stmt);
    222  1.1  mrg       unsigned i;
    223  1.1  mrg 
    224  1.1  mrg       for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
    225  1.1  mrg 	{
    226  1.1  mrg 	  tree op = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
    227  1.1  mrg 	  if (TREE_CODE (op) == SSA_NAME)
    228  1.1  mrg 	    SSA_NAME_DEF_STMT (op) = stmt;
    229  1.1  mrg 	}
    230  1.1  mrg     }
    231  1.1  mrg 
    232  1.1  mrg   /* Reset alias information.  */
    233  1.1  mrg   if (code == GIMPLE_CALL)
    234  1.1  mrg     gimple_call_reset_alias_info (as_a <gcall *> (stmt));
    235  1.1  mrg 
    236  1.1  mrg   /* Mark the statement modified so its operand vectors can be filled in.  */
    237  1.1  mrg   gimple_set_modified (stmt, true);
    238  1.1  mrg   if (has_hist)
    239  1.1  mrg     stream_in_histogram_value (ib, stmt);
    240  1.1  mrg 
    241  1.1  mrg   return stmt;
    242  1.1  mrg }
    243  1.1  mrg 
    244  1.1  mrg 
    245  1.1  mrg /* Read a basic block with tag TAG from DATA_IN using input block IB.
    246  1.1  mrg    FN is the function being processed.  */
    247  1.1  mrg 
    248  1.1  mrg void
    249  1.1  mrg input_bb (class lto_input_block *ib, enum LTO_tags tag,
    250  1.1  mrg 	  class data_in *data_in, struct function *fn,
    251  1.1  mrg 	  int count_materialization_scale)
    252  1.1  mrg {
    253  1.1  mrg   unsigned int index;
    254  1.1  mrg   basic_block bb;
    255  1.1  mrg   gimple_stmt_iterator bsi;
    256  1.1  mrg 
    257  1.1  mrg   /* This routine assumes that CFUN is set to FN, as it needs to call
    258  1.1  mrg      basic GIMPLE routines that use CFUN.  */
    259  1.1  mrg   gcc_assert (cfun == fn);
    260  1.1  mrg 
    261  1.1  mrg   index = streamer_read_uhwi (ib);
    262  1.1  mrg   bb = BASIC_BLOCK_FOR_FN (fn, index);
    263  1.1  mrg 
    264  1.1  mrg   bb->count = profile_count::stream_in (ib);
    265  1.1  mrg   if (count_materialization_scale != REG_BR_PROB_BASE
    266  1.1  mrg       && bb->count.ipa ().nonzero_p ())
    267  1.1  mrg     bb->count
    268  1.1  mrg       = bb->count.apply_scale (count_materialization_scale, REG_BR_PROB_BASE);
    269  1.1  mrg   bb->flags = streamer_read_hwi (ib);
    270  1.1  mrg   bb->discriminator = streamer_read_hwi (ib);
    271  1.1  mrg 
    272  1.1  mrg   /* LTO_bb1 has statements.  LTO_bb0 does not.  */
    273  1.1  mrg   if (tag == LTO_bb0)
    274  1.1  mrg     return;
    275  1.1  mrg 
    276  1.1  mrg   bsi = gsi_start_bb (bb);
    277  1.1  mrg   tag = streamer_read_record_start (ib);
    278  1.1  mrg   while (tag)
    279  1.1  mrg     {
    280  1.1  mrg       gimple *stmt = input_gimple_stmt (ib, data_in, tag);
    281  1.1  mrg       gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
    282  1.1  mrg 
    283  1.1  mrg       /* After the statement, expect a 0 delimiter or the EH region
    284  1.1  mrg 	 that the previous statement belongs to.  */
    285  1.1  mrg       tag = streamer_read_record_start (ib);
    286  1.1  mrg       lto_tag_check_set (tag, 2, LTO_eh_region, LTO_null);
    287  1.1  mrg 
    288  1.1  mrg       if (tag == LTO_eh_region)
    289  1.1  mrg 	{
    290  1.1  mrg 	  HOST_WIDE_INT region = streamer_read_hwi (ib);
    291  1.1  mrg 	  gcc_assert (region == (int) region);
    292  1.1  mrg 	  add_stmt_to_eh_lp (stmt, region);
    293  1.1  mrg 	}
    294  1.1  mrg 
    295  1.1  mrg       tag = streamer_read_record_start (ib);
    296  1.1  mrg     }
    297  1.1  mrg 
    298  1.1  mrg   tag = streamer_read_record_start (ib);
    299  1.1  mrg   while (tag)
    300  1.1  mrg     {
    301  1.1  mrg       input_phi (ib, bb, data_in, fn);
    302  1.1  mrg       tag = streamer_read_record_start (ib);
    303  1.1  mrg     }
    304  1.1  mrg }
    305