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