1 /* Routines for reading GIMPLE from a file stream. 2 3 Copyright 2011 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 "diagnostic.h" 26 #include "tree.h" 27 #include "tree-flow.h" 28 #include "data-streamer.h" 29 #include "tree-streamer.h" 30 #include "gimple-streamer.h" 31 32 /* Read a PHI function for basic block BB in function FN. DATA_IN is 33 the file being read. IB is the input block to use for reading. */ 34 35 static gimple 36 input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in, 37 struct function *fn) 38 { 39 unsigned HOST_WIDE_INT ix; 40 tree phi_result; 41 int i, len; 42 gimple result; 43 44 ix = streamer_read_uhwi (ib); 45 phi_result = VEC_index (tree, SSANAMES (fn), ix); 46 len = EDGE_COUNT (bb->preds); 47 result = create_phi_node (phi_result, bb); 48 SSA_NAME_DEF_STMT (phi_result) = result; 49 50 /* We have to go through a lookup process here because the preds in the 51 reconstructed graph are generally in a different order than they 52 were in the original program. */ 53 for (i = 0; i < len; i++) 54 { 55 tree def = stream_read_tree (ib, data_in); 56 int src_index = streamer_read_uhwi (ib); 57 location_t arg_loc = lto_input_location (ib, data_in); 58 basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index); 59 60 edge e = NULL; 61 int j; 62 63 for (j = 0; j < len; j++) 64 if (EDGE_PRED (bb, j)->src == sbb) 65 { 66 e = EDGE_PRED (bb, j); 67 break; 68 } 69 70 add_phi_arg (result, def, e, arg_loc); 71 } 72 73 return result; 74 } 75 76 77 /* Read a statement with tag TAG in function FN from block IB using 78 descriptors in DATA_IN. */ 79 80 static gimple 81 input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, 82 struct function *fn, enum LTO_tags tag) 83 { 84 gimple stmt; 85 enum gimple_code code; 86 unsigned HOST_WIDE_INT num_ops; 87 size_t i; 88 struct bitpack_d bp; 89 90 code = lto_tag_to_gimple_code (tag); 91 92 /* Read the tuple header. */ 93 bp = streamer_read_bitpack (ib); 94 num_ops = bp_unpack_var_len_unsigned (&bp); 95 stmt = gimple_alloc (code, num_ops); 96 stmt->gsbase.no_warning = bp_unpack_value (&bp, 1); 97 if (is_gimple_assign (stmt)) 98 stmt->gsbase.nontemporal_move = bp_unpack_value (&bp, 1); 99 stmt->gsbase.has_volatile_ops = bp_unpack_value (&bp, 1); 100 stmt->gsbase.subcode = bp_unpack_var_len_unsigned (&bp); 101 102 /* Read location information. */ 103 gimple_set_location (stmt, lto_input_location (ib, data_in)); 104 105 /* Read lexical block reference. */ 106 gimple_set_block (stmt, stream_read_tree (ib, data_in)); 107 108 /* Read in all the operands. */ 109 switch (code) 110 { 111 case GIMPLE_RESX: 112 gimple_resx_set_region (stmt, streamer_read_hwi (ib)); 113 break; 114 115 case GIMPLE_EH_MUST_NOT_THROW: 116 gimple_eh_must_not_throw_set_fndecl (stmt, stream_read_tree (ib, data_in)); 117 break; 118 119 case GIMPLE_EH_DISPATCH: 120 gimple_eh_dispatch_set_region (stmt, streamer_read_hwi (ib)); 121 break; 122 123 case GIMPLE_ASM: 124 { 125 /* FIXME lto. Move most of this into a new gimple_asm_set_string(). */ 126 tree str; 127 stmt->gimple_asm.ni = streamer_read_uhwi (ib); 128 stmt->gimple_asm.no = streamer_read_uhwi (ib); 129 stmt->gimple_asm.nc = streamer_read_uhwi (ib); 130 stmt->gimple_asm.nl = streamer_read_uhwi (ib); 131 str = streamer_read_string_cst (data_in, ib); 132 stmt->gimple_asm.string = TREE_STRING_POINTER (str); 133 } 134 /* Fallthru */ 135 136 case GIMPLE_ASSIGN: 137 case GIMPLE_CALL: 138 case GIMPLE_RETURN: 139 case GIMPLE_SWITCH: 140 case GIMPLE_LABEL: 141 case GIMPLE_COND: 142 case GIMPLE_GOTO: 143 case GIMPLE_DEBUG: 144 for (i = 0; i < num_ops; i++) 145 { 146 tree op = stream_read_tree (ib, data_in); 147 gimple_set_op (stmt, i, op); 148 if (!op) 149 continue; 150 151 /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled 152 by decl merging. */ 153 if (TREE_CODE (op) == ADDR_EXPR) 154 op = TREE_OPERAND (op, 0); 155 while (handled_component_p (op)) 156 { 157 if (TREE_CODE (op) == COMPONENT_REF) 158 { 159 tree field, type, tem; 160 tree closest_match = NULL_TREE; 161 field = TREE_OPERAND (op, 1); 162 type = DECL_CONTEXT (field); 163 for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) 164 { 165 if (TREE_CODE (tem) != FIELD_DECL) 166 continue; 167 if (tem == field) 168 break; 169 if (DECL_NONADDRESSABLE_P (tem) 170 == DECL_NONADDRESSABLE_P (field) 171 && gimple_compare_field_offset (tem, field)) 172 { 173 if (types_compatible_p (TREE_TYPE (tem), 174 TREE_TYPE (field))) 175 break; 176 else 177 closest_match = tem; 178 } 179 } 180 /* In case of type mismatches across units we can fail 181 to unify some types and thus not find a proper 182 field-decl here. */ 183 if (tem == NULL_TREE) 184 { 185 /* Thus, emit a ODR violation warning. */ 186 if (warning_at (gimple_location (stmt), 0, 187 "use of type %<%E%> with two mismatching " 188 "declarations at field %<%E%>", 189 type, TREE_OPERAND (op, 1))) 190 { 191 if (TYPE_FIELDS (type)) 192 inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)), 193 "original type declared here"); 194 inform (DECL_SOURCE_LOCATION (TREE_OPERAND (op, 1)), 195 "field in mismatching type declared here"); 196 if (TYPE_NAME (TREE_TYPE (field)) 197 && (TREE_CODE (TYPE_NAME (TREE_TYPE (field))) 198 == TYPE_DECL)) 199 inform (DECL_SOURCE_LOCATION 200 (TYPE_NAME (TREE_TYPE (field))), 201 "type of field declared here"); 202 if (closest_match 203 && TYPE_NAME (TREE_TYPE (closest_match)) 204 && (TREE_CODE (TYPE_NAME 205 (TREE_TYPE (closest_match))) == TYPE_DECL)) 206 inform (DECL_SOURCE_LOCATION 207 (TYPE_NAME (TREE_TYPE (closest_match))), 208 "type of mismatching field declared here"); 209 } 210 /* And finally fixup the types. */ 211 TREE_OPERAND (op, 0) 212 = build1 (VIEW_CONVERT_EXPR, type, 213 TREE_OPERAND (op, 0)); 214 } 215 else 216 TREE_OPERAND (op, 1) = tem; 217 } 218 219 op = TREE_OPERAND (op, 0); 220 } 221 } 222 if (is_gimple_call (stmt)) 223 { 224 if (gimple_call_internal_p (stmt)) 225 gimple_call_set_internal_fn 226 (stmt, streamer_read_enum (ib, internal_fn, IFN_LAST)); 227 else 228 gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in)); 229 } 230 break; 231 232 case GIMPLE_NOP: 233 case GIMPLE_PREDICT: 234 break; 235 236 case GIMPLE_TRANSACTION: 237 gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in)); 238 break; 239 240 default: 241 internal_error ("bytecode stream: unknown GIMPLE statement tag %s", 242 lto_tag_name (tag)); 243 } 244 245 /* Update the properties of symbols, SSA names and labels associated 246 with STMT. */ 247 if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL) 248 { 249 tree lhs = gimple_get_lhs (stmt); 250 if (lhs && TREE_CODE (lhs) == SSA_NAME) 251 SSA_NAME_DEF_STMT (lhs) = stmt; 252 } 253 else if (code == GIMPLE_LABEL) 254 gcc_assert (emit_label_in_global_context_p (gimple_label_label (stmt)) 255 || DECL_CONTEXT (gimple_label_label (stmt)) == fn->decl); 256 else if (code == GIMPLE_ASM) 257 { 258 unsigned i; 259 260 for (i = 0; i < gimple_asm_noutputs (stmt); i++) 261 { 262 tree op = TREE_VALUE (gimple_asm_output_op (stmt, i)); 263 if (TREE_CODE (op) == SSA_NAME) 264 SSA_NAME_DEF_STMT (op) = stmt; 265 } 266 } 267 268 /* Reset alias information. */ 269 if (code == GIMPLE_CALL) 270 gimple_call_reset_alias_info (stmt); 271 272 /* Mark the statement modified so its operand vectors can be filled in. */ 273 gimple_set_modified (stmt, true); 274 275 return stmt; 276 } 277 278 279 /* Read a basic block with tag TAG from DATA_IN using input block IB. 280 FN is the function being processed. */ 281 282 void 283 input_bb (struct lto_input_block *ib, enum LTO_tags tag, 284 struct data_in *data_in, struct function *fn, 285 int count_materialization_scale) 286 { 287 unsigned int index; 288 basic_block bb; 289 gimple_stmt_iterator bsi; 290 291 /* This routine assumes that CFUN is set to FN, as it needs to call 292 basic GIMPLE routines that use CFUN. */ 293 gcc_assert (cfun == fn); 294 295 index = streamer_read_uhwi (ib); 296 bb = BASIC_BLOCK_FOR_FUNCTION (fn, index); 297 298 bb->count = (streamer_read_hwi (ib) * count_materialization_scale 299 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE; 300 bb->loop_depth = streamer_read_hwi (ib); 301 bb->frequency = streamer_read_hwi (ib); 302 bb->flags = streamer_read_hwi (ib); 303 304 /* LTO_bb1 has statements. LTO_bb0 does not. */ 305 if (tag == LTO_bb0) 306 return; 307 308 bsi = gsi_start_bb (bb); 309 tag = streamer_read_record_start (ib); 310 while (tag) 311 { 312 gimple stmt = input_gimple_stmt (ib, data_in, fn, tag); 313 if (!is_gimple_debug (stmt)) 314 find_referenced_vars_in (stmt); 315 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); 316 317 /* After the statement, expect a 0 delimiter or the EH region 318 that the previous statement belongs to. */ 319 tag = streamer_read_record_start (ib); 320 lto_tag_check_set (tag, 2, LTO_eh_region, LTO_null); 321 322 if (tag == LTO_eh_region) 323 { 324 HOST_WIDE_INT region = streamer_read_hwi (ib); 325 gcc_assert (region == (int) region); 326 add_stmt_to_eh_lp (stmt, region); 327 } 328 329 tag = streamer_read_record_start (ib); 330 } 331 332 tag = streamer_read_record_start (ib); 333 while (tag) 334 { 335 gimple phi = input_phi (ib, bb, data_in, fn); 336 find_referenced_vars_in (phi); 337 tag = streamer_read_record_start (ib); 338 } 339 } 340