xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/gimple-streamer-in.c (revision 212397c69a103ae7e5eafa8731ddfae671d2dee7)
1 /* Routines for reading GIMPLE from a file stream.
2 
3    Copyright (C) 2011-2013 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 = (*SSANAMES (fn))[ix];
46   len = EDGE_COUNT (bb->preds);
47   result = create_phi_node (phi_result, bb);
48 
49   /* We have to go through a lookup process here because the preds in the
50      reconstructed graph are generally in a different order than they
51      were in the original program.  */
52   for (i = 0; i < len; i++)
53     {
54       tree def = stream_read_tree (ib, data_in);
55       int src_index = streamer_read_uhwi (ib);
56       bitpack_d bp = streamer_read_bitpack (ib);
57       location_t arg_loc = stream_input_location (&bp, 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, stream_input_location (&bp, 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 *opp, op = stream_read_tree (ib, data_in);
147 	  gimple_set_op (stmt, i, op);
148 	  if (!op)
149 	    continue;
150 
151 	  opp = gimple_op_ptr (stmt, i);
152 	  if (TREE_CODE (*opp) == ADDR_EXPR)
153 	    opp = &TREE_OPERAND (*opp, 0);
154 	  while (handled_component_p (*opp))
155 	    {
156 	      if (TREE_CODE (*opp) == COMPONENT_REF)
157 		{
158 		  /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
159 		     by decl merging.  */
160 		  tree field, type, tem;
161 		  tree closest_match = NULL_TREE;
162 		  field = TREE_OPERAND (*opp, 1);
163 		  type = DECL_CONTEXT (field);
164 		  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
165 		    {
166 		      if (TREE_CODE (tem) != FIELD_DECL)
167 			continue;
168 		      if (tem == field)
169 			break;
170 		      if (DECL_NONADDRESSABLE_P (tem)
171 			  == DECL_NONADDRESSABLE_P (field)
172 			  && gimple_compare_field_offset (tem, field))
173 			{
174 			  if (types_compatible_p (TREE_TYPE (tem),
175 						  TREE_TYPE (field)))
176 			    break;
177 			  else
178 			    closest_match = tem;
179 			}
180 		    }
181 		  /* In case of type mismatches across units we can fail
182 		     to unify some types and thus not find a proper
183 		     field-decl here.  */
184 		  if (tem == NULL_TREE)
185 		    {
186 		      /* Thus, emit a ODR violation warning.  */
187 		      if (warning_at (gimple_location (stmt), 0,
188 				      "use of type %<%E%> with two mismatching "
189 				      "declarations at field %<%E%>",
190 				      type, TREE_OPERAND (*opp, 1)))
191 			{
192 			  if (TYPE_FIELDS (type))
193 			    inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
194 				    "original type declared here");
195 			  inform (DECL_SOURCE_LOCATION (TREE_OPERAND (*opp, 1)),
196 				  "field in mismatching type declared here");
197 			  if (TYPE_NAME (TREE_TYPE (field))
198 			      && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
199 				  == TYPE_DECL))
200 			    inform (DECL_SOURCE_LOCATION
201 				      (TYPE_NAME (TREE_TYPE (field))),
202 				    "type of field declared here");
203 			  if (closest_match
204 			      && TYPE_NAME (TREE_TYPE (closest_match))
205 			      && (TREE_CODE (TYPE_NAME
206 				   (TREE_TYPE (closest_match))) == TYPE_DECL))
207 			    inform (DECL_SOURCE_LOCATION
208 				      (TYPE_NAME (TREE_TYPE (closest_match))),
209 				    "type of mismatching field declared here");
210 			}
211 		      /* And finally fixup the types.  */
212 		      TREE_OPERAND (*opp, 0)
213 			= build1 (VIEW_CONVERT_EXPR, type,
214 				  TREE_OPERAND (*opp, 0));
215 		    }
216 		  else
217 		    TREE_OPERAND (*opp, 1) = tem;
218 		}
219 	      else if ((TREE_CODE (*opp) == ARRAY_REF
220 			|| TREE_CODE (*opp) == ARRAY_RANGE_REF)
221 		       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (*opp, 0)))
222 			   != ARRAY_TYPE))
223 		{
224 		  /* And ARRAY_REFs to objects that had mismatched types
225 		     during symbol merging to avoid ICEs.  */
226 		  TREE_OPERAND (*opp, 0)
227 		    = build1 (VIEW_CONVERT_EXPR,
228 			      build_array_type (TREE_TYPE (*opp), NULL_TREE),
229 			      TREE_OPERAND (*opp, 0));
230 		}
231 
232 	      opp = &TREE_OPERAND (*opp, 0);
233 	    }
234 	  /* At LTO output time we wrap all global decls in MEM_REFs to
235 	     allow seamless replacement with prevailing decls.  Undo this
236 	     here if the prevailing decl allows for this.
237 	     ???  Maybe we should simply fold all stmts.  */
238 	  if (TREE_CODE (*opp) == MEM_REF
239 	      && TREE_CODE (TREE_OPERAND (*opp, 0)) == ADDR_EXPR
240 	      && integer_zerop (TREE_OPERAND (*opp, 1))
241 	      && (TREE_THIS_VOLATILE (*opp)
242 		  == TREE_THIS_VOLATILE
243 		       (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0)))
244 	      && !TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (*opp, 1)))
245 	      && (TREE_TYPE (*opp)
246 		  == TREE_TYPE (TREE_TYPE (TREE_OPERAND (*opp, 1))))
247 	      && (TREE_TYPE (*opp)
248 		  == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0))))
249 	    *opp = TREE_OPERAND (TREE_OPERAND (*opp, 0), 0);
250 	}
251       if (is_gimple_call (stmt))
252 	{
253 	  if (gimple_call_internal_p (stmt))
254 	    gimple_call_set_internal_fn
255 	      (stmt, streamer_read_enum (ib, internal_fn, IFN_LAST));
256 	  else
257 	    gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in));
258 	}
259       break;
260 
261     case GIMPLE_NOP:
262     case GIMPLE_PREDICT:
263       break;
264 
265     case GIMPLE_TRANSACTION:
266       gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in));
267       break;
268 
269     default:
270       internal_error ("bytecode stream: unknown GIMPLE statement tag %s",
271 		      lto_tag_name (tag));
272     }
273 
274   /* Update the properties of symbols, SSA names and labels associated
275      with STMT.  */
276   if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
277     {
278       tree lhs = gimple_get_lhs (stmt);
279       if (lhs && TREE_CODE (lhs) == SSA_NAME)
280 	SSA_NAME_DEF_STMT (lhs) = stmt;
281     }
282   else if (code == GIMPLE_LABEL)
283     gcc_assert (emit_label_in_global_context_p (gimple_label_label (stmt))
284 	        || DECL_CONTEXT (gimple_label_label (stmt)) == fn->decl);
285   else if (code == GIMPLE_ASM)
286     {
287       unsigned i;
288 
289       for (i = 0; i < gimple_asm_noutputs (stmt); i++)
290 	{
291 	  tree op = TREE_VALUE (gimple_asm_output_op (stmt, i));
292 	  if (TREE_CODE (op) == SSA_NAME)
293 	    SSA_NAME_DEF_STMT (op) = stmt;
294 	}
295     }
296 
297   /* Reset alias information.  */
298   if (code == GIMPLE_CALL)
299     gimple_call_reset_alias_info (stmt);
300 
301   /* Mark the statement modified so its operand vectors can be filled in.  */
302   gimple_set_modified (stmt, true);
303 
304   return stmt;
305 }
306 
307 
308 /* Read a basic block with tag TAG from DATA_IN using input block IB.
309    FN is the function being processed.  */
310 
311 void
312 input_bb (struct lto_input_block *ib, enum LTO_tags tag,
313 	  struct data_in *data_in, struct function *fn,
314 	  int count_materialization_scale)
315 {
316   unsigned int index;
317   basic_block bb;
318   gimple_stmt_iterator bsi;
319 
320   /* This routine assumes that CFUN is set to FN, as it needs to call
321      basic GIMPLE routines that use CFUN.  */
322   gcc_assert (cfun == fn);
323 
324   index = streamer_read_uhwi (ib);
325   bb = BASIC_BLOCK_FOR_FUNCTION (fn, index);
326 
327   bb->count = (streamer_read_hwi (ib) * count_materialization_scale
328 	       + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
329   bb->frequency = streamer_read_hwi (ib);
330   bb->flags = streamer_read_hwi (ib);
331 
332   /* LTO_bb1 has statements.  LTO_bb0 does not.  */
333   if (tag == LTO_bb0)
334     return;
335 
336   bsi = gsi_start_bb (bb);
337   tag = streamer_read_record_start (ib);
338   while (tag)
339     {
340       gimple stmt = input_gimple_stmt (ib, data_in, fn, tag);
341       gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
342 
343       /* After the statement, expect a 0 delimiter or the EH region
344 	 that the previous statement belongs to.  */
345       tag = streamer_read_record_start (ib);
346       lto_tag_check_set (tag, 2, LTO_eh_region, LTO_null);
347 
348       if (tag == LTO_eh_region)
349 	{
350 	  HOST_WIDE_INT region = streamer_read_hwi (ib);
351 	  gcc_assert (region == (int) region);
352 	  add_stmt_to_eh_lp (stmt, region);
353 	}
354 
355       tag = streamer_read_record_start (ib);
356     }
357 
358   tag = streamer_read_record_start (ib);
359   while (tag)
360     {
361       input_phi (ib, bb, data_in, fn);
362       tag = streamer_read_record_start (ib);
363     }
364 }
365