gimple-streamer-in.cc revision 1.1 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