1/* LTO IL options.
2
3   Copyright (C) 2009-2015 Free Software Foundation, Inc.
4   Contributed by Simon Baldwin <simonb@google.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along 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 "hash-set.h"
26#include "machmode.h"
27#include "vec.h"
28#include "double-int.h"
29#include "input.h"
30#include "alias.h"
31#include "symtab.h"
32#include "options.h"
33#include "wide-int.h"
34#include "inchash.h"
35#include "tree.h"
36#include "fold-const.h"
37#include "predict.h"
38#include "tm.h"
39#include "hard-reg-set.h"
40#include "input.h"
41#include "function.h"
42#include "basic-block.h"
43#include "tree-ssa-alias.h"
44#include "internal-fn.h"
45#include "gimple-expr.h"
46#include "is-a.h"
47#include "gimple.h"
48#include "bitmap.h"
49#include "flags.h"
50#include "opts.h"
51#include "options.h"
52#include "common/common-target.h"
53#include "diagnostic.h"
54#include "hash-map.h"
55#include "plugin-api.h"
56#include "ipa-ref.h"
57#include "cgraph.h"
58#include "lto-streamer.h"
59#include "lto-section-names.h"
60#include "toplev.h"
61
62/* Append the option piece OPT to the COLLECT_GCC_OPTIONS string
63   set up by OB, appropriately quoted and separated by spaces
64   (if !*FIRST_P).  */
65
66static void
67append_to_collect_gcc_options (struct obstack *ob,
68			       bool *first_p, const char *opt)
69{
70  const char *p, *q = opt;
71  if (!*first_p)
72    obstack_grow (ob, " ", 1);
73  obstack_grow (ob, "'", 1);
74  while ((p = strchr (q, '\'')))
75    {
76      obstack_grow (ob, q, p - q);
77      obstack_grow (ob, "'\\''", 4);
78      q = ++p;
79    }
80  obstack_grow (ob, q, strlen (q));
81  obstack_grow (ob, "'", 1);
82  *first_p = false;
83}
84
85/* Write currently held options to an LTO IL section.  */
86
87void
88lto_write_options (void)
89{
90  char *section_name;
91  struct obstack temporary_obstack;
92  unsigned int i, j;
93  char *args;
94  bool first_p = true;
95
96  section_name = lto_get_section_name (LTO_section_opts, NULL, NULL);
97  lto_begin_section (section_name, false);
98
99  obstack_init (&temporary_obstack);
100
101  /* Output options that affect GIMPLE IL semantics and are implicitly
102     enabled by the frontend.
103     This for now includes an explicit set of options that we also handle
104     explicitly in lto-wrapper.c.  In the end the effects on GIMPLE IL
105     semantics should be explicitely encoded in the IL or saved per
106     function rather than per compilation unit.  */
107  /* -fexceptions causes the EH machinery to be initialized, enabling
108     generation of unwind data so that explicit throw() calls work.  */
109  if (!global_options_set.x_flag_exceptions
110      && global_options.x_flag_exceptions)
111    append_to_collect_gcc_options (&temporary_obstack, &first_p,
112				   "-fexceptions");
113  /* -fnon-call-exceptions changes the generation of exception
114      regions.  It is enabled implicitly by the Go frontend.  */
115  if (!global_options_set.x_flag_non_call_exceptions
116      && global_options.x_flag_non_call_exceptions)
117    append_to_collect_gcc_options (&temporary_obstack, &first_p,
118				   "-fnon-call-exceptions");
119  /* The default -ffp-contract changes depending on the language
120     standard.  Pass thru conservative standard settings.  */
121  if (!global_options_set.x_flag_fp_contract_mode)
122    switch (global_options.x_flag_fp_contract_mode)
123      {
124      case FP_CONTRACT_OFF:
125	append_to_collect_gcc_options (&temporary_obstack, &first_p,
126				       "-ffp-contract=off");
127	break;
128      case FP_CONTRACT_ON:
129	append_to_collect_gcc_options (&temporary_obstack, &first_p,
130				       "-ffp-contract=on");
131	break;
132      case FP_CONTRACT_FAST:
133	/* Nothing.  That merges conservatively and is the default for LTO.  */
134	break;
135      default:
136	gcc_unreachable ();
137      }
138  /* The default -fmath-errno, -fsigned-zeros and -ftrapping-math change
139     depending on the language (they can be disabled by the Ada and Java
140     front-ends).  Pass thru conservative standard settings.  */
141  if (!global_options_set.x_flag_errno_math)
142    append_to_collect_gcc_options (&temporary_obstack, &first_p,
143				   global_options.x_flag_errno_math
144				   ? "-fmath-errno"
145				   : "-fno-math-errno");
146  if (!global_options_set.x_flag_signed_zeros)
147    append_to_collect_gcc_options (&temporary_obstack, &first_p,
148				   global_options.x_flag_signed_zeros
149				   ? "-fsigned-zeros"
150				   : "-fno-signed-zeros");
151  if (!global_options_set.x_flag_trapping_math)
152    append_to_collect_gcc_options (&temporary_obstack, &first_p,
153				   global_options.x_flag_trapping_math
154				   ? "-ftrapping-math"
155				   : "-fno-trapping-math");
156  /* We need to merge -f[no-]strict-overflow, -f[no-]wrapv and -f[no-]trapv
157     conservatively, so stream out their defaults.  */
158  if (!global_options_set.x_flag_wrapv
159      && global_options.x_flag_wrapv)
160    append_to_collect_gcc_options (&temporary_obstack, &first_p, "-fwrapv");
161  if (!global_options_set.x_flag_trapv
162      && !global_options.x_flag_trapv)
163    append_to_collect_gcc_options (&temporary_obstack, &first_p, "-fno-trapv");
164  if (!global_options_set.x_flag_strict_overflow
165      && !global_options.x_flag_strict_overflow)
166    append_to_collect_gcc_options (&temporary_obstack, &first_p,
167			       "-fno-strict-overflow");
168
169  if (!global_options_set.x_flag_openmp
170      && !global_options.x_flag_openmp)
171    append_to_collect_gcc_options (&temporary_obstack, &first_p, "-fno-openmp");
172  if (!global_options_set.x_flag_openacc
173      && !global_options.x_flag_openacc)
174    append_to_collect_gcc_options (&temporary_obstack, &first_p,
175				   "-fno-openacc");
176
177  /* Append options from target hook and store them to offload_lto section.  */
178  if (lto_stream_offload_p)
179    {
180      char *offload_opts = targetm.offload_options ();
181      char *offload_ptr = offload_opts;
182      while (offload_ptr)
183       {
184	 char *next = strchr (offload_ptr, ' ');
185	 if (next)
186	   *next++ = '\0';
187	 append_to_collect_gcc_options (&temporary_obstack, &first_p,
188					offload_ptr);
189	 offload_ptr = next;
190       }
191      free (offload_opts);
192    }
193
194  /* Output explicitly passed options.  */
195  for (i = 1; i < save_decoded_options_count; ++i)
196    {
197      struct cl_decoded_option *option = &save_decoded_options[i];
198
199      /* Skip explicitly some common options that we do not need.  */
200      switch (option->opt_index)
201      {
202	case OPT_dumpbase:
203	case OPT_SPECIAL_unknown:
204	case OPT_SPECIAL_ignore:
205	case OPT_SPECIAL_program_name:
206	case OPT_SPECIAL_input_file:
207	  continue;
208
209	default:
210	  break;
211      }
212
213      /* Skip frontend and driver specific options here.  */
214      if (!(cl_options[option->opt_index].flags & (CL_COMMON|CL_TARGET|CL_LTO)))
215	continue;
216
217      /* Do not store target-specific options in offload_lto section.  */
218      if ((cl_options[option->opt_index].flags & CL_TARGET)
219	  && lto_stream_offload_p)
220       continue;
221
222      /* Drop options created from the gcc driver that will be rejected
223	 when passed on to the driver again.  */
224      if (cl_options[option->opt_index].cl_reject_driver)
225	continue;
226
227      /* Also drop all options that are handled by the driver as well,
228	 which includes things like -o and -v or -fhelp for example.
229	 We do not need those.  The only exception is -foffload option, if we
230	 write it in offload_lto section.  Also drop all diagnostic options.  */
231      if ((cl_options[option->opt_index].flags & (CL_DRIVER|CL_WARNING))
232	  && (!lto_stream_offload_p || option->opt_index != OPT_foffload_))
233	continue;
234
235      for (j = 0; j < option->canonical_option_num_elements; ++j)
236	append_to_collect_gcc_options (&temporary_obstack, &first_p,
237				       option->canonical_option[j]);
238    }
239  obstack_grow (&temporary_obstack, "\0", 1);
240  args = XOBFINISH (&temporary_obstack, char *);
241  lto_write_data (args, strlen (args) + 1);
242  lto_end_section ();
243
244  obstack_free (&temporary_obstack, NULL);
245  free (section_name);
246}
247