OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [gimple-streamer-in.c] - Blame information for rev 849

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.