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