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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [lto-opts.c] - Blame information for rev 455

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

Line No. Rev Author Line
1 280 jeremybenn
/* LTO IL options.
2
 
3
   Copyright 2009 Free Software Foundation, Inc.
4
   Contributed by Simon Baldwin <simonb@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 "tree.h"
26
#include "hashtab.h"
27
#include "ggc.h"
28
#include "vec.h"
29
#include "bitmap.h"
30
#include "flags.h"
31
#include "opts.h"
32
#include "options.h"
33
#include "target.h"
34
#include "toplev.h"
35
#include "lto-streamer.h"
36
 
37
/* When a file is initially compiled, the options used when generating
38
   the IL are not necessarily the same as those used when linking the
39
   objects into the final executable.  In general, most build systems
40
   will proceed with something along the lines of:
41
 
42
        $ gcc <cc-flags> -flto -c f1.c -o f1.o
43
        $ gcc <cc-flags> -flto -c f2.c -o f2.o
44
        ...
45
        $ gcc <cc-flags> -flto -c fN.c -o fN.o
46
 
47
   And the final link may or may not include the same <cc-flags> used
48
   to generate the initial object files:
49
 
50
        $ gcc <ld-flags> -flto -o prog f1.o ... fN.o
51
 
52
   Since we will be generating final code during the link step, some
53
   of the flags used during the compile step need to be re-applied
54
   during the link step.  For instance, flags in the -m family.
55
 
56
   The idea is to save a selected set of <cc-flags> in a special
57
   section of the initial object files.  This section is then read
58
   during linking and the options re-applied.
59
 
60
   FIXME lto.  Currently the scheme is limited in that only the
61
   options saved on the first object file (f1.o) are read back during
62
   the link step.  This means that the options used to compile f1.o
63
   will be applied to ALL the object files in the final link step.
64
   More work needs to be done to implement a merging and validation
65
   mechanism, as this will not be enough for all cases.  */
66
 
67
/* Saved options hold the type of the option (currently CL_TARGET or
68
   CL_COMMON), and the code, argument, and value.  */
69
 
70
typedef struct GTY(()) opt_d
71
{
72
  unsigned int type;
73
  size_t code;
74
  char *arg;
75
  int value;
76
} opt_t;
77
 
78
DEF_VEC_O (opt_t);
79
DEF_VEC_ALLOC_O (opt_t, heap);
80
 
81
 
82
/* Options are held in two vectors, one for those registered by
83
   command line handling code, and the other for those read in from
84
   any LTO IL input.  */
85
static VEC(opt_t, heap) *user_options = NULL;
86
static VEC(opt_t, heap) *file_options = NULL;
87
 
88
/* Iterate FROM in reverse, writing option codes not yet in CODES into *TO.
89
   Mark each new option code encountered in CODES.  */
90
 
91
static void
92
reverse_iterate_options (VEC(opt_t, heap) *from, VEC(opt_t, heap) **to,
93
                         bitmap codes)
94
{
95
  int i;
96
 
97
  for (i = VEC_length (opt_t, from); i > 0; i--)
98
    {
99
      const opt_t *const o = VEC_index (opt_t, from, i - 1);
100
 
101
      if (bitmap_set_bit (codes, o->code))
102
        VEC_safe_push (opt_t, heap, *to, o);
103
    }
104
}
105
 
106
/* Concatenate options vectors FIRST and SECOND, rationalize so that only the
107
   final of any given option remains, and return the result.  */
108
 
109
static VEC(opt_t, heap) *
110
concatenate_options (VEC(opt_t, heap) *first, VEC(opt_t, heap) *second)
111
{
112
  VEC(opt_t, heap) *results = NULL;
113
  bitmap codes = lto_bitmap_alloc ();
114
 
115
  reverse_iterate_options (second, &results, codes);
116
  reverse_iterate_options (first, &results, codes);
117
 
118
  lto_bitmap_free (codes);
119
  return results;
120
}
121
 
122
/* Clear the options vector in *OPTS_P and set it to NULL.  */
123
 
124
static void
125
clear_options (VEC(opt_t, heap) **opts_p)
126
{
127
  int i;
128
  opt_t *o;
129
 
130
  for (i = 0; VEC_iterate (opt_t, *opts_p, i, o); i++)
131
    free (o->arg);
132
 
133
  VEC_free (opt_t, heap, *opts_p);
134
}
135
 
136
/* Write LENGTH bytes from ADDR to STREAM.  */
137
 
138
static void
139
output_data_stream (struct lto_output_stream *stream,
140
                    const void *addr, size_t length)
141
{
142
  lto_output_data_stream (stream, addr, length);
143
}
144
 
145
/* Write string STRING to STREAM.  */
146
 
147
static void
148
output_string_stream (struct lto_output_stream *stream, const char *string)
149
{
150
  bool flag = false;
151
 
152
  if (string != NULL)
153
    {
154
      const size_t length = strlen (string);
155
 
156
      flag = true;
157
      output_data_stream (stream, &flag, sizeof (flag));
158
      output_data_stream (stream, &length, sizeof (length));
159
      output_data_stream (stream, string, length);
160
    }
161
  else
162
    output_data_stream (stream, &flag, sizeof (flag));
163
}
164
 
165
/* Read LENGTH bytes from STREAM to ADDR.  */
166
 
167
static void
168
input_data_block (struct lto_input_block *ib, void *addr, size_t length)
169
{
170
  size_t i;
171
  unsigned char *const buffer = (unsigned char *const) addr;
172
 
173
  for (i = 0; i < length; i++)
174
    buffer[i] = lto_input_1_unsigned (ib);
175
}
176
 
177
/* Return a string from IB.  The string is allocated, and the caller is
178
   responsible for freeing it.  */
179
 
180
static char *
181
input_string_block (struct lto_input_block *ib)
182
{
183
  bool flag;
184
 
185
  input_data_block (ib, &flag, sizeof (flag));
186
  if (flag)
187
    {
188
      size_t length;
189
      char *string;
190
 
191
      input_data_block (ib, &length, sizeof (length));
192
      string = (char *) xcalloc (1, length + 1);
193
      input_data_block (ib, string, length);
194
 
195
      return string;
196
    }
197
  else
198
    return NULL;
199
}
200
 
201
/* Return true if this option is one we need to save in LTO output files.
202
   At present, we pass along all target options, and common options that
203
   involve position independent code.
204
 
205
   TODO This list of options requires expansion and rationalization.
206
   Among others, optimization options may well be appropriate here.  */
207
 
208
static bool
209
register_user_option_p (size_t code, int type)
210
{
211
  if (type == CL_TARGET)
212
    return true;
213
  else if (type == CL_COMMON)
214
    {
215
      return (code == OPT_fPIC
216
              || code == OPT_fpic
217
              || code == OPT_fPIE
218
              || code == OPT_fpie
219
              || code == OPT_fcommon
220
              || code == OPT_fexceptions);
221
    }
222
 
223
  return false;
224
}
225
 
226
/* Note command line option with the given TYPE and CODE, ARG, and VALUE.
227
   If relevant to LTO, save it in the user options vector.  */
228
 
229
void
230
lto_register_user_option (size_t code, const char *arg, int value, int type)
231
{
232
  if (register_user_option_p (code, type))
233
    {
234
      opt_t o;
235
 
236
      o.type = type;
237
      o.code = code;
238
      if (arg != NULL)
239
        {
240
          o.arg = (char *) xmalloc (strlen (arg) + 1);
241
          strcpy (o.arg, arg);
242
        }
243
      else
244
        o.arg = NULL;
245
      o.value = value;
246
      VEC_safe_push (opt_t, heap, user_options, &o);
247
    }
248
}
249
 
250
/* Empty the saved user options vector.  */
251
 
252
void
253
lto_clear_user_options (void)
254
{
255
  clear_options (&user_options);
256
}
257
 
258
/* Empty the saved file options vector.  */
259
 
260
void
261
lto_clear_file_options (void)
262
{
263
  clear_options (&file_options);
264
}
265
 
266
/* Concatenate the user options and any file options read from an LTO IL
267
   file, and serialize them to STREAM.  File options precede user options
268
   so that the latter override the former when reissued.  */
269
 
270
static void
271
output_options (struct lto_output_stream *stream)
272
{
273
  VEC(opt_t, heap) *opts = concatenate_options (file_options, user_options);
274
  const size_t length = VEC_length (opt_t, opts);
275
  int i;
276
  opt_t *o;
277
 
278
  output_data_stream (stream, &length, sizeof (length));
279
 
280
  for (i = 0; VEC_iterate (opt_t, opts, i, o); i++)
281
    {
282
      output_data_stream (stream, &o->type, sizeof (o->type));
283
      output_data_stream (stream, &o->code, sizeof (o->code));
284
      output_string_stream (stream, o->arg);
285
      output_data_stream (stream, &o->value, sizeof (o->value));
286
    }
287
 
288
  VEC_free (opt_t, heap, opts);
289
}
290
 
291
/* Write currently held options to an LTO IL section.  */
292
 
293
void
294
lto_write_options (void)
295
{
296
  char *const section_name = lto_get_section_name (LTO_section_opts, NULL);
297
  struct lto_output_stream stream;
298
  struct lto_simple_header header;
299
  struct lto_output_stream *header_stream;
300
 
301
  lto_begin_section (section_name, !flag_wpa);
302
  free (section_name);
303
 
304
  memset (&stream, 0, sizeof (stream));
305
  output_options (&stream);
306
 
307
  memset (&header, 0, sizeof (header));
308
  header.lto_header.major_version = LTO_major_version;
309
  header.lto_header.minor_version = LTO_minor_version;
310
  header.lto_header.section_type = LTO_section_opts;
311
 
312
  header.compressed_size = 0;
313
  header.main_size = stream.total_size;
314
 
315
  header_stream = ((struct lto_output_stream *)
316
                   xcalloc (1, sizeof (*header_stream)));
317
  lto_output_data_stream (header_stream, &header, sizeof (header));
318
  lto_write_stream (header_stream);
319
  free (header_stream);
320
 
321
  lto_write_stream (&stream);
322
  lto_end_section ();
323
}
324
 
325
/* Unserialize an options vector from IB, and append to file_options.  */
326
 
327
static void
328
input_options (struct lto_input_block *ib)
329
{
330
  size_t length, i;
331
 
332
  input_data_block (ib, &length, sizeof (length));
333
 
334
  for (i = 0; i < length; i++)
335
    {
336
      opt_t o;
337
 
338
      input_data_block (ib, &o.type, sizeof (o.type));
339
      input_data_block (ib, &o.code, sizeof (o.code));
340
      o.arg = input_string_block (ib);
341
      input_data_block (ib, &o.value, sizeof (o.value));
342
      VEC_safe_push (opt_t, heap, file_options, &o);
343
    }
344
}
345
 
346
/* Read options from an LTO IL section.  */
347
 
348
void
349
lto_read_file_options (struct lto_file_decl_data *file_data)
350
{
351
  size_t len;
352
  const char *data;
353
  const struct lto_simple_header *header;
354
  int32_t opts_offset;
355
  struct lto_input_block ib;
356
 
357
  data = lto_get_section_data (file_data, LTO_section_opts, NULL, &len);
358
  header = (const struct lto_simple_header *) data;
359
  opts_offset = sizeof (*header);
360
 
361
  lto_check_version (header->lto_header.major_version,
362
                     header->lto_header.minor_version);
363
 
364
  LTO_INIT_INPUT_BLOCK (ib, data + opts_offset, 0, header->main_size);
365
  input_options (&ib);
366
 
367
  lto_free_section_data (file_data, LTO_section_opts, 0, data, len);
368
}
369
 
370
/* Concatenate the user options and any file options read from an LTO IL
371
   file, and reissue them as if all had just been read in from the command
372
   line.  As with serialization, file options precede user options.  */
373
 
374
void
375
lto_reissue_options (void)
376
{
377
  VEC(opt_t, heap) *opts = concatenate_options (file_options, user_options);
378
  int i;
379
  opt_t *o;
380
 
381
  for (i = 0; VEC_iterate (opt_t, opts, i, o); i++)
382
    {
383
      const struct cl_option *option = &cl_options[o->code];
384
 
385
      if (option->flag_var)
386
        set_option (option, o->value, o->arg);
387
 
388
      if (o->type == CL_TARGET)
389
        targetm.handle_option (o->code, o->arg, o->value);
390
      else if (o->type == CL_COMMON)
391
        gcc_assert (option->flag_var);
392
      else
393
        gcc_unreachable ();
394
    }
395
 
396
  VEC_free (opt_t, heap, opts);
397
}

powered by: WebSVN 2.1.0

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