* [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type.
@ 2021-04-21 8:12 Martin Liška
2021-04-29 12:22 ` Richard Biener
0 siblings, 1 reply; 5+ messages in thread
From: Martin Liška @ 2021-04-21 8:12 UTC (permalink / raw)
To: gcc-patches
Now living in the 21st century, we don't longer need using the following tuple:
cl_decoded_option **decoded_options,
unsigned int *decoded_options_count)
but we can rather use a standard (our) vector.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed?
Thanks,
Martin
gcc/ChangeLog:
* lto-wrapper.c (get_options_from_collect_gcc_options): Change
return type.
(append_option): Remove.
(find_option): Rework to use the vector type.
(remove_option): Remove.
(merge_and_complain): Use vectors for cl_decoded_option data
type arguments.
(append_compiler_options): Likewise.
(append_diag_options): Likewise.
(append_linker_options): Likewise.
(append_offload_options): Likewise.
(compile_offload_image): Likewise.
(compile_images_for_offload_targets): Likewise.
(find_and_merge_options): Likewise.
(run_gcc): Likewise.
---
gcc/lto-wrapper.c | 384 ++++++++++++++++++++--------------------------
1 file changed, 165 insertions(+), 219 deletions(-)
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 03a5922f8ea..5ccf729b249 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -138,12 +138,12 @@ maybe_unlink (const char *file)
/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
environment. */
-static void
+static vec<cl_decoded_option>
get_options_from_collect_gcc_options (const char *collect_gcc,
- const char *collect_gcc_options,
- struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count)
+ const char *collect_gcc_options)
{
+ cl_decoded_option *decoded_options;
+ unsigned int decoded_options_count;
struct obstack argv_obstack;
const char **argv;
int argc;
@@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
argv = XOBFINISH (&argv_obstack, const char **);
decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
- decoded_options, decoded_options_count);
+ &decoded_options, &decoded_options_count);
+ vec<cl_decoded_option> decoded;
+ decoded.create (decoded_options_count);
+ for (unsigned i = 0; i < decoded_options_count; ++i)
+ decoded.quick_push (decoded_options[i]);
+ free (decoded_options);
+
obstack_free (&argv_obstack, NULL);
+
+ return decoded;
}
-/* Append OPTION to the options array DECODED_OPTIONS with size
- DECODED_OPTIONS_COUNT. */
+/* Find option in OPTIONS based on OPT_INDEX. NULL value is returned
+ if the option is not present. */
-static void
-append_option (struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count,
- struct cl_decoded_option *option)
+static cl_decoded_option *
+find_option (vec<cl_decoded_option> &options, size_t opt_index)
{
- ++*decoded_options_count;
- *decoded_options
- = (struct cl_decoded_option *)
- xrealloc (*decoded_options,
- (*decoded_options_count
- * sizeof (struct cl_decoded_option)));
- memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
- sizeof (struct cl_decoded_option));
-}
+ for (unsigned i = 0; i < options.length (); ++i)
+ if (options[i].opt_index == opt_index)
+ return &options[i];
-/* Remove option number INDEX from DECODED_OPTIONS, update
- DECODED_OPTIONS_COUNT. */
+ return NULL;
+}
-static void
-remove_option (struct cl_decoded_option **decoded_options,
- int index, unsigned int *decoded_options_count)
+static cl_decoded_option *
+find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
{
- --*decoded_options_count;
- memmove (&(*decoded_options)[index + 1],
- &(*decoded_options)[index],
- sizeof (struct cl_decoded_option)
- * (*decoded_options_count - index));
+ return find_option (options, option->opt_index);
}
/* Try to merge and complain about options FDECODED_OPTIONS when applied
ontop of DECODED_OPTIONS. */
static void
-merge_and_complain (struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count,
- struct cl_decoded_option *fdecoded_options,
- unsigned int fdecoded_options_count,
- struct cl_decoded_option *decoded_cl_options,
- unsigned int decoded_cl_options_count)
+merge_and_complain (vec<cl_decoded_option> decoded_options,
+ vec<cl_decoded_option> fdecoded_options,
+ vec<cl_decoded_option> decoded_cl_options)
{
unsigned int i, j;
- struct cl_decoded_option *pic_option = NULL;
- struct cl_decoded_option *pie_option = NULL;
- struct cl_decoded_option *cf_protection_option = NULL;
+ cl_decoded_option *pic_option = NULL;
+ cl_decoded_option *pie_option = NULL;
+ cl_decoded_option *cf_protection_option = NULL;
/* ??? Merge options from files. Most cases can be
handled by either unioning or intersecting
@@ -223,9 +215,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
/* Look for a -fcf-protection option in the link-time options
which overrides any -fcf-protection from the lto sections. */
- for (i = 0; i < decoded_cl_options_count; ++i)
+ for (i = 0; i < decoded_cl_options.length (); ++i)
{
- struct cl_decoded_option *foption = &decoded_cl_options[i];
+ cl_decoded_option *foption = &decoded_cl_options[i];
if (foption->opt_index == OPT_fcf_protection_)
{
cf_protection_option = foption;
@@ -234,9 +226,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
/* The following does what the old LTO option code did,
union all target and a selected set of common options. */
- for (i = 0; i < fdecoded_options_count; ++i)
+ for (i = 0; i < fdecoded_options.length (); ++i)
{
- struct cl_decoded_option *foption = &fdecoded_options[i];
+ cl_decoded_option *foption = &fdecoded_options[i];
+ cl_decoded_option *existing_opt = find_option (decoded_options, foption);
switch (foption->opt_index)
{
case OPT_SPECIAL_unknown:
@@ -264,11 +257,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
setting per OPT code, we pick the first we encounter.
??? This doesn't make too much sense, but when it doesn't
then we should complain. */
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
+ if (existing_opt == NULL)
+ decoded_options.safe_push (*foption);
break;
/* Figure out what PIC/PIE level wins and merge the results. */
@@ -284,25 +274,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_fopenmp:
case OPT_fopenacc:
/* For selected options we can merge conservatively. */
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
+ if (existing_opt == NULL)
+ decoded_options.safe_push (*foption);
/* -fopenmp > -fno-openmp,
-fopenacc > -fno-openacc */
- else if (foption->value > (*decoded_options)[j].value)
- (*decoded_options)[j] = *foption;
+ else if (foption->value > existing_opt->value)
+ *existing_opt = *foption;
break;
case OPT_fopenacc_dim_:
/* Append or check identical. */
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if (strcmp ((*decoded_options)[j].arg, foption->arg))
+ if (existing_opt == NULL)
+ decoded_options.safe_push (*foption);
+ else if (strcmp (existing_opt->arg, foption->arg))
fatal_error (input_location,
"option %s with different values",
foption->orig_option_with_args_text);
@@ -313,12 +297,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (!cf_protection_option
|| cf_protection_option->value == CF_CHECK)
{
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if ((*decoded_options)[j].value != foption->value)
+ if (existing_opt == NULL)
+ decoded_options.safe_push (*foption);
+ else if (existing_opt->value != foption->value)
{
if (cf_protection_option
&& cf_protection_option->value == CF_CHECK)
@@ -326,22 +307,21 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
"option %qs with mismatching values"
" (%s, %s)",
"-fcf-protection",
- (*decoded_options)[j].arg, foption->arg);
+ existing_opt->arg, foption->arg);
else
{
/* Merge and update the -fcf-protection option. */
- (*decoded_options)[j].value &= (foption->value
- & CF_FULL);
- switch ((*decoded_options)[j].value)
+ existing_opt->value &= (foption->value & CF_FULL);
+ switch (existing_opt->value)
{
case CF_NONE:
- (*decoded_options)[j].arg = "none";
+ existing_opt->arg = "none";
break;
case CF_BRANCH:
- (*decoded_options)[j].arg = "branch";
+ existing_opt->arg = "branch";
break;
case CF_RETURN:
- (*decoded_options)[j].arg = "return";
+ existing_opt->arg = "return";
break;
default:
gcc_unreachable ();
@@ -355,15 +335,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_Ofast:
case OPT_Og:
case OPT_Os:
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == OPT_O
- || (*decoded_options)[j].opt_index == OPT_Ofast
- || (*decoded_options)[j].opt_index == OPT_Og
- || (*decoded_options)[j].opt_index == OPT_Os)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if ((*decoded_options)[j].opt_index == foption->opt_index
+ existing_opt = NULL;
+ for (j = 0; j < decoded_options.length (); ++j)
+ if (decoded_options[j].opt_index == OPT_O
+ || decoded_options[j].opt_index == OPT_Ofast
+ || decoded_options[j].opt_index == OPT_Og
+ || decoded_options[j].opt_index == OPT_Os)
+ {
+ existing_opt = &decoded_options[j];
+ break;
+ }
+ if (existing_opt == NULL)
+ decoded_options.safe_push (*foption);
+ else if (existing_opt->opt_index == foption->opt_index
&& foption->opt_index != OPT_O)
/* Exact same options get merged. */
;
@@ -393,13 +377,13 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
default:
gcc_unreachable ();
}
- switch ((*decoded_options)[j].opt_index)
+ switch (existing_opt->opt_index)
{
case OPT_O:
- if ((*decoded_options)[j].arg[0] == '\0')
+ if (existing_opt->arg[0] == '\0')
level = MAX (level, 1);
else
- level = MAX (level, atoi ((*decoded_options)[j].arg));
+ level = MAX (level, atoi (existing_opt->arg));
break;
case OPT_Ofast:
level = MAX (level, 3);
@@ -413,23 +397,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
default:
gcc_unreachable ();
}
- (*decoded_options)[j].opt_index = OPT_O;
+ existing_opt->opt_index = OPT_O;
char *tem;
tem = xasprintf ("-O%d", level);
- (*decoded_options)[j].arg = &tem[2];
- (*decoded_options)[j].canonical_option[0] = tem;
- (*decoded_options)[j].value = 1;
+ existing_opt->arg = &tem[2];
+ existing_opt->canonical_option[0] = tem;
+ existing_opt->value = 1;
}
break;
case OPT_foffload_abi_:
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if (foption->value != (*decoded_options)[j].value)
+ if (existing_opt == NULL)
+ decoded_options.safe_push (*foption);
+ else if (foption->value != existing_opt->value)
fatal_error (input_location,
"option %s not used consistently in all LTO input"
" files", foption->orig_option_with_args_text);
@@ -437,7 +418,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_foffload_:
- append_option (decoded_options, decoded_options_count, foption);
+ decoded_options.safe_push (*foption);
break;
}
}
@@ -457,12 +438,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
It would be good to warn on mismatches, but it is bit hard to do as
we do not know what nothing translates to. */
- for (unsigned int j = 0; j < *decoded_options_count;)
- if ((*decoded_options)[j].opt_index == OPT_fPIC
- || (*decoded_options)[j].opt_index == OPT_fpic)
+ for (unsigned int j = 0; j < decoded_options.length ();)
+ if (decoded_options[j].opt_index == OPT_fPIC
+ || decoded_options[j].opt_index == OPT_fpic)
{
/* -fno-pic in one unit implies -fno-pic everywhere. */
- if ((*decoded_options)[j].value == 0)
+ if (decoded_options[j].value == 0)
j++;
/* If we have no pic option or merge in -fno-pic, we still may turn
existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
@@ -471,41 +452,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
{
if (pie_option)
{
- bool big = (*decoded_options)[j].opt_index == OPT_fPIC
+ bool big = decoded_options[j].opt_index == OPT_fPIC
&& pie_option->opt_index == OPT_fPIE;
- (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
+ decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
if (pie_option->value)
- (*decoded_options)[j].canonical_option[0]
+ decoded_options[j].canonical_option[0]
= big ? "-fPIE" : "-fpie";
else
- (*decoded_options)[j].canonical_option[0] = "-fno-pie";
- (*decoded_options)[j].value = pie_option->value;
- j++;
+ decoded_options[j].canonical_option[0] = "-fno-pie";
+ decoded_options[j].value = pie_option->value;
+ j++;
}
else if (pic_option)
{
- (*decoded_options)[j] = *pic_option;
- j++;
+ decoded_options[j] = *pic_option;
+ j++;
}
/* We do not know if target defaults to pic or not, so just remove
option if it is missing in one unit but enabled in other. */
else
- remove_option (decoded_options, j, decoded_options_count);
+ decoded_options.ordered_remove (j);
}
else if (pic_option->opt_index == OPT_fpic
- && (*decoded_options)[j].opt_index == OPT_fPIC)
+ && decoded_options[j].opt_index == OPT_fPIC)
{
- (*decoded_options)[j] = *pic_option;
+ decoded_options[j] = *pic_option;
j++;
}
else
j++;
}
- else if ((*decoded_options)[j].opt_index == OPT_fPIE
- || (*decoded_options)[j].opt_index == OPT_fpie)
+ else if (decoded_options[j].opt_index == OPT_fPIE
+ || decoded_options[j].opt_index == OPT_fpie)
{
/* -fno-pie in one unit implies -fno-pie everywhere. */
- if ((*decoded_options)[j].value == 0)
+ if (decoded_options[j].value == 0)
j++;
/* If we have no pie option or merge in -fno-pie, we still preserve
PIE/pie if pic/PIC is present. */
@@ -516,32 +497,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (pic_option)
{
if (pic_option->opt_index == OPT_fpic
- && (*decoded_options)[j].opt_index == OPT_fPIE)
+ && decoded_options[j].opt_index == OPT_fPIE)
{
- (*decoded_options)[j].opt_index = OPT_fpie;
- (*decoded_options)[j].canonical_option[0]
+ decoded_options[j].opt_index = OPT_fpie;
+ decoded_options[j].canonical_option[0]
= pic_option->value ? "-fpie" : "-fno-pie";
}
else if (!pic_option->value)
- (*decoded_options)[j].canonical_option[0] = "-fno-pie";
- (*decoded_options)[j].value = pic_option->value;
+ decoded_options[j].canonical_option[0] = "-fno-pie";
+ decoded_options[j].value = pic_option->value;
j++;
}
else if (pie_option)
{
- (*decoded_options)[j] = *pie_option;
+ decoded_options[j] = *pie_option;
j++;
}
/* Because we always append pic/PIE options this code path should
not happen unless the LTO object was built by old lto1 which
did not contain that logic yet. */
else
- remove_option (decoded_options, j, decoded_options_count);
+ decoded_options.ordered_remove (j);
}
else if (pie_option->opt_index == OPT_fpie
- && (*decoded_options)[j].opt_index == OPT_fPIE)
+ && decoded_options[j].opt_index == OPT_fPIE)
{
- (*decoded_options)[j] = *pie_option;
+ decoded_options[j] = *pie_option;
j++;
}
else
@@ -553,37 +534,34 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (!xassembler_options_error)
for (i = j = 0; ; i++, j++)
{
- for (; i < *decoded_options_count; i++)
- if ((*decoded_options)[i].opt_index == OPT_Xassembler)
- break;
-
- for (; j < fdecoded_options_count; j++)
- if (fdecoded_options[j].opt_index == OPT_Xassembler)
- break;
+ cl_decoded_option *existing_opt
+ = find_option (decoded_options, OPT_Xassembler);
+ cl_decoded_option *existing_opt2
+ = find_option (fdecoded_options, OPT_Xassembler);
- if (i == *decoded_options_count && j == fdecoded_options_count)
+ if (existing_opt == NULL && existing_opt2 == NULL)
break;
- else if (i < *decoded_options_count && j == fdecoded_options_count)
+ else if (existing_opt != NULL && existing_opt2 == NULL)
{
warning (0, "Extra option to %<-Xassembler%>: %s,"
" dropping all %<-Xassembler%> and %<-Wa%> options.",
- (*decoded_options)[i].arg);
+ existing_opt->arg);
xassembler_options_error = true;
break;
}
- else if (i == *decoded_options_count && j < fdecoded_options_count)
+ else if (existing_opt == NULL && existing_opt2 != NULL)
{
warning (0, "Extra option to %<-Xassembler%>: %s,"
" dropping all %<-Xassembler%> and %<-Wa%> options.",
- fdecoded_options[j].arg);
+ existing_opt2->arg);
xassembler_options_error = true;
break;
}
- else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg))
+ else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
{
warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
" dropping all %<-Xassembler%> and %<-Wa%> options.",
- (*decoded_options)[i].arg, fdecoded_options[j].arg);
+ existing_opt->arg, existing_opt2->arg);
xassembler_options_error = true;
break;
}
@@ -654,13 +632,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append)
/* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
static void
-append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
- unsigned int count)
+append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
{
/* Append compiler driver arguments as far as they were merged. */
- for (unsigned int j = 1; j < count; ++j)
+ for (unsigned int j = 1; j < opts.length (); ++j)
{
- struct cl_decoded_option *option = &opts[j];
+ cl_decoded_option *option = &opts[j];
/* File options have been properly filtered by lto-opts.c. */
switch (option->opt_index)
@@ -721,16 +698,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
}
}
-/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */
+/* Append diag options in OPTS to ARGV_OBSTACK. */
static void
-append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
- unsigned int count)
+append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
{
/* Append compiler driver arguments as far as they were merged. */
- for (unsigned int j = 1; j < count; ++j)
+ for (unsigned int j = 1; j < opts.length (); ++j)
{
- struct cl_decoded_option *option = &opts[j];
+ cl_decoded_option *option = &opts[j];
switch (option->opt_index)
{
@@ -757,14 +733,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
/* Append linker options OPTS to ARGV_OBSTACK. */
static void
-append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
- unsigned int count)
+append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
{
/* Append linker driver arguments. Compiler options from the linker
driver arguments will override / merge with those from the compiler. */
- for (unsigned int j = 1; j < count; ++j)
+ for (unsigned int j = 1; j < opts.length (); ++j)
{
- struct cl_decoded_option *option = &opts[j];
+ cl_decoded_option *option = &opts[j];
/* Do not pass on frontend specific flags not suitable for lto. */
if (!(cl_options[option->opt_index].flags
@@ -802,15 +777,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
static void
append_offload_options (obstack *argv_obstack, const char *target,
- struct cl_decoded_option *options,
- unsigned int options_count)
+ vec<cl_decoded_option> options)
{
- for (unsigned i = 0; i < options_count; i++)
+ for (unsigned i = 0; i < options.length (); i++)
{
const char *cur, *next, *opts;
char **argv;
unsigned argc;
- struct cl_decoded_option *option = &options[i];
+ cl_decoded_option *option = &options[i];
if (option->opt_index != OPT_foffload_)
continue;
@@ -882,10 +856,8 @@ access_check (const char *name, int mode)
static char *
compile_offload_image (const char *target, const char *compiler_path,
unsigned in_argc, char *in_argv[],
- struct cl_decoded_option *compiler_opts,
- unsigned int compiler_opt_count,
- struct cl_decoded_option *linker_opts,
- unsigned int linker_opt_count)
+ vec<cl_decoded_option> compiler_opts,
+ vec<cl_decoded_option> linker_opts)
{
char *filename = NULL;
char *dumpbase;
@@ -935,19 +907,16 @@ compile_offload_image (const char *target, const char *compiler_path,
obstack_ptr_grow (&argv_obstack, in_argv[i]);
/* Append options from offload_lto sections. */
- append_compiler_options (&argv_obstack, compiler_opts,
- compiler_opt_count);
- append_diag_options (&argv_obstack, linker_opts, linker_opt_count);
+ append_compiler_options (&argv_obstack, compiler_opts);
+ append_diag_options (&argv_obstack, linker_opts);
obstack_ptr_grow (&argv_obstack, "-dumpbase");
obstack_ptr_grow (&argv_obstack, dumpbase);
/* Append options specified by -foffload last. In case of conflicting
options we expect offload compiler to choose the latest. */
- append_offload_options (&argv_obstack, target, compiler_opts,
- compiler_opt_count);
- append_offload_options (&argv_obstack, target, linker_opts,
- linker_opt_count);
+ append_offload_options (&argv_obstack, target, compiler_opts);
+ append_offload_options (&argv_obstack, target, linker_opts);
obstack_ptr_grow (&argv_obstack, NULL);
argv = XOBFINISH (&argv_obstack, char **);
@@ -966,10 +935,8 @@ compile_offload_image (const char *target, const char *compiler_path,
static void
compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
- struct cl_decoded_option *compiler_opts,
- unsigned int compiler_opt_count,
- struct cl_decoded_option *linker_opts,
- unsigned int linker_opt_count)
+ vec<cl_decoded_option> compiler_opts,
+ vec<cl_decoded_option> linker_opts)
{
char **names = NULL;
const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
@@ -988,8 +955,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
{
offload_names[i]
= compile_offload_image (names[i], compiler_path, in_argc, in_argv,
- compiler_opts, compiler_opt_count,
- linker_opts, linker_opt_count);
+ compiler_opts, linker_opts);
if (!offload_names[i])
fatal_error (input_location,
"problem with building target image for %s", names[i]);
@@ -1058,25 +1024,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx)
}
/* A subroutine of run_gcc. Examine the open file FD for lto sections with
- name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
- and OPT_COUNT. Return true if we found a matching section, false
+ name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
+ Return true if we found a matching section, false
otherwise. COLLECT_GCC holds the value of the environment variable with
the same name. */
static bool
find_and_merge_options (int fd, off_t file_offset, const char *prefix,
- struct cl_decoded_option *decoded_cl_options,
- unsigned int decoded_cl_options_count,
- struct cl_decoded_option **opts,
- unsigned int *opt_count, const char *collect_gcc)
+ vec<cl_decoded_option> decoded_cl_options,
+ vec<cl_decoded_option> *opts, const char *collect_gcc)
{
off_t offset, length;
char *data;
char *fopts;
const char *errmsg;
int err;
- struct cl_decoded_option *fdecoded_options = *opts;
- unsigned int fdecoded_options_count = *opt_count;
+ vec<cl_decoded_option> fdecoded_options;
simple_object_read *sobj;
sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
@@ -1098,24 +1061,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
data = (char *)xmalloc (length);
read (fd, data, length);
fopts = data;
+ bool first = true;
do
{
- struct cl_decoded_option *f2decoded_options;
- unsigned int f2decoded_options_count;
- get_options_from_collect_gcc_options (collect_gcc, fopts,
- &f2decoded_options,
- &f2decoded_options_count);
- if (!fdecoded_options)
- {
- fdecoded_options = f2decoded_options;
- fdecoded_options_count = f2decoded_options_count;
- }
+ vec<cl_decoded_option> f2decoded_options
+ = get_options_from_collect_gcc_options (collect_gcc, fopts);
+ if (first)
+ {
+ fdecoded_options = f2decoded_options;
+ first = false;
+ }
else
- merge_and_complain (&fdecoded_options,
- &fdecoded_options_count,
- f2decoded_options, f2decoded_options_count,
- decoded_cl_options,
- decoded_cl_options_count);
+ merge_and_complain (fdecoded_options, f2decoded_options,
+ decoded_cl_options);
fopts += strlen (fopts) + 1;
}
@@ -1124,7 +1082,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
free (data);
simple_object_release_read (sobj);
*opts = fdecoded_options;
- *opt_count = fdecoded_options_count;
return true;
}
@@ -1371,12 +1328,9 @@ run_gcc (unsigned argc, char *argv[])
int jobserver = 0;
int auto_parallel = 0;
bool no_partition = false;
- struct cl_decoded_option *fdecoded_options = NULL;
- struct cl_decoded_option *offload_fdecoded_options = NULL;
- unsigned int fdecoded_options_count = 0;
- unsigned int offload_fdecoded_options_count = 0;
- struct cl_decoded_option *decoded_options;
- unsigned int decoded_options_count;
+ vec<cl_decoded_option> fdecoded_options;
+ fdecoded_options.create (16);
+ vec<cl_decoded_option> offload_fdecoded_options = vNULL;
struct obstack argv_obstack;
int new_head_argc;
bool have_lto = false;
@@ -1418,9 +1372,8 @@ run_gcc (unsigned argc, char *argv[])
NULL);
}
- get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
- &decoded_options,
- &decoded_options_count);
+ vec<cl_decoded_option> decoded_options
+ = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
/* Allocate array for input object files with LTO IL,
and for possible preceding arguments. */
@@ -1470,8 +1423,7 @@ run_gcc (unsigned argc, char *argv[])
}
if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
- decoded_options, decoded_options_count,
- &fdecoded_options, &fdecoded_options_count,
+ decoded_options, &fdecoded_options,
collect_gcc))
{
have_lto = true;
@@ -1486,14 +1438,13 @@ run_gcc (unsigned argc, char *argv[])
obstack_ptr_grow (&argv_obstack, "-xlto");
obstack_ptr_grow (&argv_obstack, "-c");
- append_compiler_options (&argv_obstack, fdecoded_options,
- fdecoded_options_count);
- append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
+ append_compiler_options (&argv_obstack, fdecoded_options);
+ append_linker_options (&argv_obstack, decoded_options);
/* Scan linker driver arguments for things that are of relevance to us. */
- for (j = 1; j < decoded_options_count; ++j)
+ for (j = 1; j < decoded_options.length (); ++j)
{
- struct cl_decoded_option *option = &decoded_options[j];
+ cl_decoded_option *option = &decoded_options[j];
switch (option->opt_index)
{
case OPT_o:
@@ -1711,9 +1662,7 @@ cont1:
fatal_error (input_location, "cannot open %s: %m", filename);
if (!find_and_merge_options (fd, file_offset,
OFFLOAD_SECTION_NAME_PREFIX,
- decoded_options, decoded_options_count,
- &offload_fdecoded_options,
- &offload_fdecoded_options_count,
+ decoded_options, &offload_fdecoded_options,
collect_gcc))
fatal_error (input_location, "cannot read %s: %m", filename);
close (fd);
@@ -1722,10 +1671,7 @@ cont1:
}
compile_images_for_offload_targets (num_offload_files, offload_argv,
- offload_fdecoded_options,
- offload_fdecoded_options_count,
- decoded_options,
- decoded_options_count);
+ offload_fdecoded_options, decoded_options);
free_array_of_ptrs ((void **) offload_argv, num_offload_files);
--
2.31.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type.
2021-04-21 8:12 [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type Martin Liška
@ 2021-04-29 12:22 ` Richard Biener
2021-04-29 15:19 ` Martin Sebor
2021-05-12 9:08 ` Martin Liška
0 siblings, 2 replies; 5+ messages in thread
From: Richard Biener @ 2021-04-29 12:22 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
On Wed, Apr 21, 2021 at 11:12 AM Martin Liška <mliska@suse.cz> wrote:
>
> Now living in the 21st century, we don't longer need using the following tuple:
> cl_decoded_option **decoded_options,
> unsigned int *decoded_options_count)
> but we can rather use a standard (our) vector.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?
> Thanks,
> Martin
>
> gcc/ChangeLog:
>
> * lto-wrapper.c (get_options_from_collect_gcc_options): Change
> return type.
> (append_option): Remove.
> (find_option): Rework to use the vector type.
> (remove_option): Remove.
> (merge_and_complain): Use vectors for cl_decoded_option data
> type arguments.
> (append_compiler_options): Likewise.
> (append_diag_options): Likewise.
> (append_linker_options): Likewise.
> (append_offload_options): Likewise.
> (compile_offload_image): Likewise.
> (compile_images_for_offload_targets): Likewise.
> (find_and_merge_options): Likewise.
> (run_gcc): Likewise.
> ---
> gcc/lto-wrapper.c | 384 ++++++++++++++++++++--------------------------
> 1 file changed, 165 insertions(+), 219 deletions(-)
>
> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
> index 03a5922f8ea..5ccf729b249 100644
> --- a/gcc/lto-wrapper.c
> +++ b/gcc/lto-wrapper.c
> @@ -138,12 +138,12 @@ maybe_unlink (const char *file)
> /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
> environment. */
>
> -static void
> +static vec<cl_decoded_option>
bonus points for handling ownership transfer via returning an
auto_vec<> (not sure if possible, but maybe it is).
> get_options_from_collect_gcc_options (const char *collect_gcc,
> - const char *collect_gcc_options,
> - struct cl_decoded_option **decoded_options,
> - unsigned int *decoded_options_count)
> + const char *collect_gcc_options)
> {
> + cl_decoded_option *decoded_options;
> + unsigned int decoded_options_count;
> struct obstack argv_obstack;
> const char **argv;
> int argc;
> @@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
> argv = XOBFINISH (&argv_obstack, const char **);
>
> decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
> - decoded_options, decoded_options_count);
> + &decoded_options, &decoded_options_count);
> + vec<cl_decoded_option> decoded;
> + decoded.create (decoded_options_count);
> + for (unsigned i = 0; i < decoded_options_count; ++i)
> + decoded.quick_push (decoded_options[i]);
> + free (decoded_options);
> +
> obstack_free (&argv_obstack, NULL);
> +
> + return decoded;
> }
>
> -/* Append OPTION to the options array DECODED_OPTIONS with size
> - DECODED_OPTIONS_COUNT. */
> +/* Find option in OPTIONS based on OPT_INDEX. NULL value is returned
> + if the option is not present. */
>
> -static void
> -append_option (struct cl_decoded_option **decoded_options,
> - unsigned int *decoded_options_count,
> - struct cl_decoded_option *option)
> +static cl_decoded_option *
> +find_option (vec<cl_decoded_option> &options, size_t opt_index)
> {
> - ++*decoded_options_count;
> - *decoded_options
> - = (struct cl_decoded_option *)
> - xrealloc (*decoded_options,
> - (*decoded_options_count
> - * sizeof (struct cl_decoded_option)));
> - memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
> - sizeof (struct cl_decoded_option));
> -}
> + for (unsigned i = 0; i < options.length (); ++i)
> + if (options[i].opt_index == opt_index)
> + return &options[i];
You're returning a pointer into the vector here...
> -/* Remove option number INDEX from DECODED_OPTIONS, update
> - DECODED_OPTIONS_COUNT. */
> + return NULL;
> +}
>
> -static void
> -remove_option (struct cl_decoded_option **decoded_options,
> - int index, unsigned int *decoded_options_count)
> +static cl_decoded_option *
> +find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
> {
> - --*decoded_options_count;
> - memmove (&(*decoded_options)[index + 1],
> - &(*decoded_options)[index],
> - sizeof (struct cl_decoded_option)
> - * (*decoded_options_count - index));
> + return find_option (options, option->opt_index);
> }
>
> /* Try to merge and complain about options FDECODED_OPTIONS when applied
> ontop of DECODED_OPTIONS. */
>
> static void
> -merge_and_complain (struct cl_decoded_option **decoded_options,
> - unsigned int *decoded_options_count,
> - struct cl_decoded_option *fdecoded_options,
> - unsigned int fdecoded_options_count,
> - struct cl_decoded_option *decoded_cl_options,
> - unsigned int decoded_cl_options_count)
> +merge_and_complain (vec<cl_decoded_option> decoded_options,
> + vec<cl_decoded_option> fdecoded_options,
> + vec<cl_decoded_option> decoded_cl_options)
> {
> unsigned int i, j;
> - struct cl_decoded_option *pic_option = NULL;
> - struct cl_decoded_option *pie_option = NULL;
> - struct cl_decoded_option *cf_protection_option = NULL;
> + cl_decoded_option *pic_option = NULL;
> + cl_decoded_option *pie_option = NULL;
> + cl_decoded_option *cf_protection_option = NULL;
>
> /* ??? Merge options from files. Most cases can be
> handled by either unioning or intersecting
> @@ -223,9 +215,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>
> /* Look for a -fcf-protection option in the link-time options
> which overrides any -fcf-protection from the lto sections. */
> - for (i = 0; i < decoded_cl_options_count; ++i)
> + for (i = 0; i < decoded_cl_options.length (); ++i)
> {
> - struct cl_decoded_option *foption = &decoded_cl_options[i];
> + cl_decoded_option *foption = &decoded_cl_options[i];
> if (foption->opt_index == OPT_fcf_protection_)
> {
> cf_protection_option = foption;
> @@ -234,9 +226,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>
> /* The following does what the old LTO option code did,
> union all target and a selected set of common options. */
> - for (i = 0; i < fdecoded_options_count; ++i)
> + for (i = 0; i < fdecoded_options.length (); ++i)
> {
> - struct cl_decoded_option *foption = &fdecoded_options[i];
> + cl_decoded_option *foption = &fdecoded_options[i];
> + cl_decoded_option *existing_opt = find_option (decoded_options, foption);
> switch (foption->opt_index)
> {
> case OPT_SPECIAL_unknown:
> @@ -264,11 +257,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> setting per OPT code, we pick the first we encounter.
> ??? This doesn't make too much sense, but when it doesn't
> then we should complain. */
> - for (j = 0; j < *decoded_options_count; ++j)
> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> - break;
> - if (j == *decoded_options_count)
> - append_option (decoded_options, decoded_options_count, foption);
> + if (existing_opt == NULL)
> + decoded_options.safe_push (*foption);
and you end up re-allocating that here. That's an eventually dangerous
pattern ... please consider to instead returning an index from find()
(and -1 for not found or so).
> break;
>
> /* Figure out what PIC/PIE level wins and merge the results. */
> @@ -284,25 +274,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> case OPT_fopenmp:
> case OPT_fopenacc:
> /* For selected options we can merge conservatively. */
> - for (j = 0; j < *decoded_options_count; ++j)
> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> - break;
> - if (j == *decoded_options_count)
> - append_option (decoded_options, decoded_options_count, foption);
> + if (existing_opt == NULL)
> + decoded_options.safe_push (*foption);
> /* -fopenmp > -fno-openmp,
> -fopenacc > -fno-openacc */
> - else if (foption->value > (*decoded_options)[j].value)
> - (*decoded_options)[j] = *foption;
> + else if (foption->value > existing_opt->value)
> + *existing_opt = *foption;
> break;
>
> case OPT_fopenacc_dim_:
> /* Append or check identical. */
> - for (j = 0; j < *decoded_options_count; ++j)
> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> - break;
> - if (j == *decoded_options_count)
> - append_option (decoded_options, decoded_options_count, foption);
> - else if (strcmp ((*decoded_options)[j].arg, foption->arg))
> + if (existing_opt == NULL)
> + decoded_options.safe_push (*foption);
> + else if (strcmp (existing_opt->arg, foption->arg))
> fatal_error (input_location,
> "option %s with different values",
> foption->orig_option_with_args_text);
> @@ -313,12 +297,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> if (!cf_protection_option
> || cf_protection_option->value == CF_CHECK)
> {
> - for (j = 0; j < *decoded_options_count; ++j)
> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> - break;
> - if (j == *decoded_options_count)
> - append_option (decoded_options, decoded_options_count, foption);
> - else if ((*decoded_options)[j].value != foption->value)
> + if (existing_opt == NULL)
> + decoded_options.safe_push (*foption);
> + else if (existing_opt->value != foption->value)
> {
> if (cf_protection_option
> && cf_protection_option->value == CF_CHECK)
> @@ -326,22 +307,21 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> "option %qs with mismatching values"
> " (%s, %s)",
> "-fcf-protection",
> - (*decoded_options)[j].arg, foption->arg);
> + existing_opt->arg, foption->arg);
> else
> {
> /* Merge and update the -fcf-protection option. */
> - (*decoded_options)[j].value &= (foption->value
> - & CF_FULL);
> - switch ((*decoded_options)[j].value)
> + existing_opt->value &= (foption->value & CF_FULL);
> + switch (existing_opt->value)
> {
> case CF_NONE:
> - (*decoded_options)[j].arg = "none";
> + existing_opt->arg = "none";
> break;
> case CF_BRANCH:
> - (*decoded_options)[j].arg = "branch";
> + existing_opt->arg = "branch";
> break;
> case CF_RETURN:
> - (*decoded_options)[j].arg = "return";
> + existing_opt->arg = "return";
> break;
> default:
> gcc_unreachable ();
> @@ -355,15 +335,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> case OPT_Ofast:
> case OPT_Og:
> case OPT_Os:
> - for (j = 0; j < *decoded_options_count; ++j)
> - if ((*decoded_options)[j].opt_index == OPT_O
> - || (*decoded_options)[j].opt_index == OPT_Ofast
> - || (*decoded_options)[j].opt_index == OPT_Og
> - || (*decoded_options)[j].opt_index == OPT_Os)
> - break;
> - if (j == *decoded_options_count)
> - append_option (decoded_options, decoded_options_count, foption);
> - else if ((*decoded_options)[j].opt_index == foption->opt_index
> + existing_opt = NULL;
> + for (j = 0; j < decoded_options.length (); ++j)
> + if (decoded_options[j].opt_index == OPT_O
> + || decoded_options[j].opt_index == OPT_Ofast
> + || decoded_options[j].opt_index == OPT_Og
> + || decoded_options[j].opt_index == OPT_Os)
> + {
> + existing_opt = &decoded_options[j];
> + break;
> + }
> + if (existing_opt == NULL)
> + decoded_options.safe_push (*foption);
> + else if (existing_opt->opt_index == foption->opt_index
> && foption->opt_index != OPT_O)
> /* Exact same options get merged. */
> ;
> @@ -393,13 +377,13 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> default:
> gcc_unreachable ();
> }
> - switch ((*decoded_options)[j].opt_index)
> + switch (existing_opt->opt_index)
> {
> case OPT_O:
> - if ((*decoded_options)[j].arg[0] == '\0')
> + if (existing_opt->arg[0] == '\0')
> level = MAX (level, 1);
> else
> - level = MAX (level, atoi ((*decoded_options)[j].arg));
> + level = MAX (level, atoi (existing_opt->arg));
> break;
> case OPT_Ofast:
> level = MAX (level, 3);
> @@ -413,23 +397,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> default:
> gcc_unreachable ();
> }
> - (*decoded_options)[j].opt_index = OPT_O;
> + existing_opt->opt_index = OPT_O;
> char *tem;
> tem = xasprintf ("-O%d", level);
> - (*decoded_options)[j].arg = &tem[2];
> - (*decoded_options)[j].canonical_option[0] = tem;
> - (*decoded_options)[j].value = 1;
> + existing_opt->arg = &tem[2];
> + existing_opt->canonical_option[0] = tem;
> + existing_opt->value = 1;
> }
> break;
>
>
> case OPT_foffload_abi_:
> - for (j = 0; j < *decoded_options_count; ++j)
> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> - break;
> - if (j == *decoded_options_count)
> - append_option (decoded_options, decoded_options_count, foption);
> - else if (foption->value != (*decoded_options)[j].value)
> + if (existing_opt == NULL)
> + decoded_options.safe_push (*foption);
> + else if (foption->value != existing_opt->value)
> fatal_error (input_location,
> "option %s not used consistently in all LTO input"
> " files", foption->orig_option_with_args_text);
> @@ -437,7 +418,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>
>
> case OPT_foffload_:
> - append_option (decoded_options, decoded_options_count, foption);
> + decoded_options.safe_push (*foption);
> break;
> }
> }
> @@ -457,12 +438,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> It would be good to warn on mismatches, but it is bit hard to do as
> we do not know what nothing translates to. */
>
> - for (unsigned int j = 0; j < *decoded_options_count;)
> - if ((*decoded_options)[j].opt_index == OPT_fPIC
> - || (*decoded_options)[j].opt_index == OPT_fpic)
> + for (unsigned int j = 0; j < decoded_options.length ();)
> + if (decoded_options[j].opt_index == OPT_fPIC
> + || decoded_options[j].opt_index == OPT_fpic)
> {
> /* -fno-pic in one unit implies -fno-pic everywhere. */
> - if ((*decoded_options)[j].value == 0)
> + if (decoded_options[j].value == 0)
> j++;
> /* If we have no pic option or merge in -fno-pic, we still may turn
> existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
> @@ -471,41 +452,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> {
> if (pie_option)
> {
> - bool big = (*decoded_options)[j].opt_index == OPT_fPIC
> + bool big = decoded_options[j].opt_index == OPT_fPIC
> && pie_option->opt_index == OPT_fPIE;
> - (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
> + decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
> if (pie_option->value)
> - (*decoded_options)[j].canonical_option[0]
> + decoded_options[j].canonical_option[0]
> = big ? "-fPIE" : "-fpie";
> else
> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
> - (*decoded_options)[j].value = pie_option->value;
> - j++;
> + decoded_options[j].canonical_option[0] = "-fno-pie";
> + decoded_options[j].value = pie_option->value;
> + j++;
> }
> else if (pic_option)
> {
> - (*decoded_options)[j] = *pic_option;
> - j++;
> + decoded_options[j] = *pic_option;
> + j++;
> }
> /* We do not know if target defaults to pic or not, so just remove
> option if it is missing in one unit but enabled in other. */
> else
> - remove_option (decoded_options, j, decoded_options_count);
> + decoded_options.ordered_remove (j);
> }
> else if (pic_option->opt_index == OPT_fpic
> - && (*decoded_options)[j].opt_index == OPT_fPIC)
> + && decoded_options[j].opt_index == OPT_fPIC)
> {
> - (*decoded_options)[j] = *pic_option;
> + decoded_options[j] = *pic_option;
> j++;
> }
> else
> j++;
> }
> - else if ((*decoded_options)[j].opt_index == OPT_fPIE
> - || (*decoded_options)[j].opt_index == OPT_fpie)
> + else if (decoded_options[j].opt_index == OPT_fPIE
> + || decoded_options[j].opt_index == OPT_fpie)
> {
> /* -fno-pie in one unit implies -fno-pie everywhere. */
> - if ((*decoded_options)[j].value == 0)
> + if (decoded_options[j].value == 0)
> j++;
> /* If we have no pie option or merge in -fno-pie, we still preserve
> PIE/pie if pic/PIC is present. */
> @@ -516,32 +497,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> if (pic_option)
> {
> if (pic_option->opt_index == OPT_fpic
> - && (*decoded_options)[j].opt_index == OPT_fPIE)
> + && decoded_options[j].opt_index == OPT_fPIE)
> {
> - (*decoded_options)[j].opt_index = OPT_fpie;
> - (*decoded_options)[j].canonical_option[0]
> + decoded_options[j].opt_index = OPT_fpie;
> + decoded_options[j].canonical_option[0]
> = pic_option->value ? "-fpie" : "-fno-pie";
> }
> else if (!pic_option->value)
> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
> - (*decoded_options)[j].value = pic_option->value;
> + decoded_options[j].canonical_option[0] = "-fno-pie";
> + decoded_options[j].value = pic_option->value;
> j++;
> }
> else if (pie_option)
> {
> - (*decoded_options)[j] = *pie_option;
> + decoded_options[j] = *pie_option;
> j++;
> }
> /* Because we always append pic/PIE options this code path should
> not happen unless the LTO object was built by old lto1 which
> did not contain that logic yet. */
> else
> - remove_option (decoded_options, j, decoded_options_count);
> + decoded_options.ordered_remove (j);
> }
> else if (pie_option->opt_index == OPT_fpie
> - && (*decoded_options)[j].opt_index == OPT_fPIE)
> + && decoded_options[j].opt_index == OPT_fPIE)
> {
> - (*decoded_options)[j] = *pie_option;
> + decoded_options[j] = *pie_option;
> j++;
> }
> else
> @@ -553,37 +534,34 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> if (!xassembler_options_error)
> for (i = j = 0; ; i++, j++)
> {
> - for (; i < *decoded_options_count; i++)
> - if ((*decoded_options)[i].opt_index == OPT_Xassembler)
> - break;
> -
> - for (; j < fdecoded_options_count; j++)
> - if (fdecoded_options[j].opt_index == OPT_Xassembler)
> - break;
> + cl_decoded_option *existing_opt
> + = find_option (decoded_options, OPT_Xassembler);
> + cl_decoded_option *existing_opt2
> + = find_option (fdecoded_options, OPT_Xassembler);
>
> - if (i == *decoded_options_count && j == fdecoded_options_count)
> + if (existing_opt == NULL && existing_opt2 == NULL)
> break;
> - else if (i < *decoded_options_count && j == fdecoded_options_count)
> + else if (existing_opt != NULL && existing_opt2 == NULL)
> {
> warning (0, "Extra option to %<-Xassembler%>: %s,"
> " dropping all %<-Xassembler%> and %<-Wa%> options.",
> - (*decoded_options)[i].arg);
> + existing_opt->arg);
> xassembler_options_error = true;
> break;
> }
> - else if (i == *decoded_options_count && j < fdecoded_options_count)
> + else if (existing_opt == NULL && existing_opt2 != NULL)
> {
> warning (0, "Extra option to %<-Xassembler%>: %s,"
> " dropping all %<-Xassembler%> and %<-Wa%> options.",
> - fdecoded_options[j].arg);
> + existing_opt2->arg);
> xassembler_options_error = true;
> break;
> }
> - else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg))
> + else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
> {
> warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
> " dropping all %<-Xassembler%> and %<-Wa%> options.",
> - (*decoded_options)[i].arg, fdecoded_options[j].arg);
> + existing_opt->arg, existing_opt2->arg);
> xassembler_options_error = true;
> break;
> }
> @@ -654,13 +632,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append)
> /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
>
> static void
> -append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> - unsigned int count)
> +append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
> {
> /* Append compiler driver arguments as far as they were merged. */
> - for (unsigned int j = 1; j < count; ++j)
> + for (unsigned int j = 1; j < opts.length (); ++j)
> {
> - struct cl_decoded_option *option = &opts[j];
> + cl_decoded_option *option = &opts[j];
>
> /* File options have been properly filtered by lto-opts.c. */
> switch (option->opt_index)
> @@ -721,16 +698,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> }
> }
>
> -/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */
> +/* Append diag options in OPTS to ARGV_OBSTACK. */
>
> static void
> -append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> - unsigned int count)
> +append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
> {
> /* Append compiler driver arguments as far as they were merged. */
> - for (unsigned int j = 1; j < count; ++j)
> + for (unsigned int j = 1; j < opts.length (); ++j)
> {
> - struct cl_decoded_option *option = &opts[j];
> + cl_decoded_option *option = &opts[j];
>
> switch (option->opt_index)
> {
> @@ -757,14 +733,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> /* Append linker options OPTS to ARGV_OBSTACK. */
>
> static void
> -append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> - unsigned int count)
> +append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
> {
> /* Append linker driver arguments. Compiler options from the linker
> driver arguments will override / merge with those from the compiler. */
> - for (unsigned int j = 1; j < count; ++j)
> + for (unsigned int j = 1; j < opts.length (); ++j)
> {
> - struct cl_decoded_option *option = &opts[j];
> + cl_decoded_option *option = &opts[j];
>
> /* Do not pass on frontend specific flags not suitable for lto. */
> if (!(cl_options[option->opt_index].flags
> @@ -802,15 +777,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>
> static void
> append_offload_options (obstack *argv_obstack, const char *target,
> - struct cl_decoded_option *options,
> - unsigned int options_count)
> + vec<cl_decoded_option> options)
> {
> - for (unsigned i = 0; i < options_count; i++)
> + for (unsigned i = 0; i < options.length (); i++)
> {
> const char *cur, *next, *opts;
> char **argv;
> unsigned argc;
> - struct cl_decoded_option *option = &options[i];
> + cl_decoded_option *option = &options[i];
>
> if (option->opt_index != OPT_foffload_)
> continue;
> @@ -882,10 +856,8 @@ access_check (const char *name, int mode)
> static char *
> compile_offload_image (const char *target, const char *compiler_path,
> unsigned in_argc, char *in_argv[],
> - struct cl_decoded_option *compiler_opts,
> - unsigned int compiler_opt_count,
> - struct cl_decoded_option *linker_opts,
> - unsigned int linker_opt_count)
> + vec<cl_decoded_option> compiler_opts,
> + vec<cl_decoded_option> linker_opts)
> {
> char *filename = NULL;
> char *dumpbase;
> @@ -935,19 +907,16 @@ compile_offload_image (const char *target, const char *compiler_path,
> obstack_ptr_grow (&argv_obstack, in_argv[i]);
>
> /* Append options from offload_lto sections. */
> - append_compiler_options (&argv_obstack, compiler_opts,
> - compiler_opt_count);
> - append_diag_options (&argv_obstack, linker_opts, linker_opt_count);
> + append_compiler_options (&argv_obstack, compiler_opts);
> + append_diag_options (&argv_obstack, linker_opts);
>
> obstack_ptr_grow (&argv_obstack, "-dumpbase");
> obstack_ptr_grow (&argv_obstack, dumpbase);
>
> /* Append options specified by -foffload last. In case of conflicting
> options we expect offload compiler to choose the latest. */
> - append_offload_options (&argv_obstack, target, compiler_opts,
> - compiler_opt_count);
> - append_offload_options (&argv_obstack, target, linker_opts,
> - linker_opt_count);
> + append_offload_options (&argv_obstack, target, compiler_opts);
> + append_offload_options (&argv_obstack, target, linker_opts);
>
> obstack_ptr_grow (&argv_obstack, NULL);
> argv = XOBFINISH (&argv_obstack, char **);
> @@ -966,10 +935,8 @@ compile_offload_image (const char *target, const char *compiler_path,
>
> static void
> compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
> - struct cl_decoded_option *compiler_opts,
> - unsigned int compiler_opt_count,
> - struct cl_decoded_option *linker_opts,
> - unsigned int linker_opt_count)
> + vec<cl_decoded_option> compiler_opts,
> + vec<cl_decoded_option> linker_opts)
> {
> char **names = NULL;
> const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
> @@ -988,8 +955,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
> {
> offload_names[i]
> = compile_offload_image (names[i], compiler_path, in_argc, in_argv,
> - compiler_opts, compiler_opt_count,
> - linker_opts, linker_opt_count);
> + compiler_opts, linker_opts);
> if (!offload_names[i])
> fatal_error (input_location,
> "problem with building target image for %s", names[i]);
> @@ -1058,25 +1024,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx)
> }
>
> /* A subroutine of run_gcc. Examine the open file FD for lto sections with
> - name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
> - and OPT_COUNT. Return true if we found a matching section, false
> + name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
> + Return true if we found a matching section, false
> otherwise. COLLECT_GCC holds the value of the environment variable with
> the same name. */
>
> static bool
> find_and_merge_options (int fd, off_t file_offset, const char *prefix,
> - struct cl_decoded_option *decoded_cl_options,
> - unsigned int decoded_cl_options_count,
> - struct cl_decoded_option **opts,
> - unsigned int *opt_count, const char *collect_gcc)
> + vec<cl_decoded_option> decoded_cl_options,
> + vec<cl_decoded_option> *opts, const char *collect_gcc)
> {
> off_t offset, length;
> char *data;
> char *fopts;
> const char *errmsg;
> int err;
> - struct cl_decoded_option *fdecoded_options = *opts;
> - unsigned int fdecoded_options_count = *opt_count;
> + vec<cl_decoded_option> fdecoded_options;
>
> simple_object_read *sobj;
> sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
> @@ -1098,24 +1061,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
> data = (char *)xmalloc (length);
> read (fd, data, length);
> fopts = data;
> + bool first = true;
> do
> {
> - struct cl_decoded_option *f2decoded_options;
> - unsigned int f2decoded_options_count;
> - get_options_from_collect_gcc_options (collect_gcc, fopts,
> - &f2decoded_options,
> - &f2decoded_options_count);
> - if (!fdecoded_options)
> - {
> - fdecoded_options = f2decoded_options;
> - fdecoded_options_count = f2decoded_options_count;
> - }
> + vec<cl_decoded_option> f2decoded_options
> + = get_options_from_collect_gcc_options (collect_gcc, fopts);
> + if (first)
> + {
> + fdecoded_options = f2decoded_options;
> + first = false;
> + }
> else
> - merge_and_complain (&fdecoded_options,
> - &fdecoded_options_count,
> - f2decoded_options, f2decoded_options_count,
> - decoded_cl_options,
> - decoded_cl_options_count);
> + merge_and_complain (fdecoded_options, f2decoded_options,
> + decoded_cl_options);
>
> fopts += strlen (fopts) + 1;
> }
> @@ -1124,7 +1082,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
> free (data);
> simple_object_release_read (sobj);
> *opts = fdecoded_options;
> - *opt_count = fdecoded_options_count;
> return true;
> }
>
> @@ -1371,12 +1328,9 @@ run_gcc (unsigned argc, char *argv[])
> int jobserver = 0;
> int auto_parallel = 0;
> bool no_partition = false;
> - struct cl_decoded_option *fdecoded_options = NULL;
> - struct cl_decoded_option *offload_fdecoded_options = NULL;
> - unsigned int fdecoded_options_count = 0;
> - unsigned int offload_fdecoded_options_count = 0;
> - struct cl_decoded_option *decoded_options;
> - unsigned int decoded_options_count;
> + vec<cl_decoded_option> fdecoded_options;
> + fdecoded_options.create (16);
> + vec<cl_decoded_option> offload_fdecoded_options = vNULL;
> struct obstack argv_obstack;
> int new_head_argc;
> bool have_lto = false;
> @@ -1418,9 +1372,8 @@ run_gcc (unsigned argc, char *argv[])
> NULL);
> }
>
> - get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
> - &decoded_options,
> - &decoded_options_count);
> + vec<cl_decoded_option> decoded_options
> + = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
>
> /* Allocate array for input object files with LTO IL,
> and for possible preceding arguments. */
> @@ -1470,8 +1423,7 @@ run_gcc (unsigned argc, char *argv[])
> }
>
> if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
> - decoded_options, decoded_options_count,
> - &fdecoded_options, &fdecoded_options_count,
> + decoded_options, &fdecoded_options,
> collect_gcc))
> {
> have_lto = true;
> @@ -1486,14 +1438,13 @@ run_gcc (unsigned argc, char *argv[])
> obstack_ptr_grow (&argv_obstack, "-xlto");
> obstack_ptr_grow (&argv_obstack, "-c");
>
> - append_compiler_options (&argv_obstack, fdecoded_options,
> - fdecoded_options_count);
> - append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
> + append_compiler_options (&argv_obstack, fdecoded_options);
> + append_linker_options (&argv_obstack, decoded_options);
>
> /* Scan linker driver arguments for things that are of relevance to us. */
> - for (j = 1; j < decoded_options_count; ++j)
> + for (j = 1; j < decoded_options.length (); ++j)
> {
> - struct cl_decoded_option *option = &decoded_options[j];
> + cl_decoded_option *option = &decoded_options[j];
> switch (option->opt_index)
> {
> case OPT_o:
> @@ -1711,9 +1662,7 @@ cont1:
> fatal_error (input_location, "cannot open %s: %m", filename);
> if (!find_and_merge_options (fd, file_offset,
> OFFLOAD_SECTION_NAME_PREFIX,
> - decoded_options, decoded_options_count,
> - &offload_fdecoded_options,
> - &offload_fdecoded_options_count,
> + decoded_options, &offload_fdecoded_options,
> collect_gcc))
> fatal_error (input_location, "cannot read %s: %m", filename);
> close (fd);
> @@ -1722,10 +1671,7 @@ cont1:
> }
>
> compile_images_for_offload_targets (num_offload_files, offload_argv,
> - offload_fdecoded_options,
> - offload_fdecoded_options_count,
> - decoded_options,
> - decoded_options_count);
> + offload_fdecoded_options, decoded_options);
>
> free_array_of_ptrs ((void **) offload_argv, num_offload_files);
>
> --
> 2.31.1
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type.
2021-04-29 12:22 ` Richard Biener
@ 2021-04-29 15:19 ` Martin Sebor
2021-05-12 9:08 ` Martin Liška
1 sibling, 0 replies; 5+ messages in thread
From: Martin Sebor @ 2021-04-29 15:19 UTC (permalink / raw)
To: Richard Biener, Martin Liška; +Cc: GCC Patches
On 4/29/21 6:22 AM, Richard Biener via Gcc-patches wrote:
> On Wed, Apr 21, 2021 at 11:12 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> Now living in the 21st century, we don't longer need using the following tuple:
>> cl_decoded_option **decoded_options,
>> unsigned int *decoded_options_count)
>> but we can rather use a standard (our) vector.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>> Thanks,
>> Martin
>>
>> gcc/ChangeLog:
>>
>> * lto-wrapper.c (get_options_from_collect_gcc_options): Change
>> return type.
>> (append_option): Remove.
>> (find_option): Rework to use the vector type.
>> (remove_option): Remove.
>> (merge_and_complain): Use vectors for cl_decoded_option data
>> type arguments.
>> (append_compiler_options): Likewise.
>> (append_diag_options): Likewise.
>> (append_linker_options): Likewise.
>> (append_offload_options): Likewise.
>> (compile_offload_image): Likewise.
>> (compile_images_for_offload_targets): Likewise.
>> (find_and_merge_options): Likewise.
>> (run_gcc): Likewise.
>> ---
>> gcc/lto-wrapper.c | 384 ++++++++++++++++++++--------------------------
>> 1 file changed, 165 insertions(+), 219 deletions(-)
>>
>> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
>> index 03a5922f8ea..5ccf729b249 100644
>> --- a/gcc/lto-wrapper.c
>> +++ b/gcc/lto-wrapper.c
>> @@ -138,12 +138,12 @@ maybe_unlink (const char *file)
>> /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
>> environment. */
>>
>> -static void
>> +static vec<cl_decoded_option>
>
> bonus points for handling ownership transfer via returning an
> auto_vec<> (not sure if possible, but maybe it is).
The auto_vec move ctor you added makes it possible. It matches either
a plain vec argument or an auto_vec.
(The copy ctor patch I submitted earlier this week matches in contexts
where the argument cannot be moved.)
Martin
>
>> get_options_from_collect_gcc_options (const char *collect_gcc,
>> - const char *collect_gcc_options,
>> - struct cl_decoded_option **decoded_options,
>> - unsigned int *decoded_options_count)
>> + const char *collect_gcc_options)
>> {
>> + cl_decoded_option *decoded_options;
>> + unsigned int decoded_options_count;
>> struct obstack argv_obstack;
>> const char **argv;
>> int argc;
>> @@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
>> argv = XOBFINISH (&argv_obstack, const char **);
>>
>> decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
>> - decoded_options, decoded_options_count);
>> + &decoded_options, &decoded_options_count);
>> + vec<cl_decoded_option> decoded;
>> + decoded.create (decoded_options_count);
>> + for (unsigned i = 0; i < decoded_options_count; ++i)
>> + decoded.quick_push (decoded_options[i]);
>> + free (decoded_options);
>> +
>> obstack_free (&argv_obstack, NULL);
>> +
>> + return decoded;
>> }
>>
>> -/* Append OPTION to the options array DECODED_OPTIONS with size
>> - DECODED_OPTIONS_COUNT. */
>> +/* Find option in OPTIONS based on OPT_INDEX. NULL value is returned
>> + if the option is not present. */
>>
>> -static void
>> -append_option (struct cl_decoded_option **decoded_options,
>> - unsigned int *decoded_options_count,
>> - struct cl_decoded_option *option)
>> +static cl_decoded_option *
>> +find_option (vec<cl_decoded_option> &options, size_t opt_index)
>> {
>> - ++*decoded_options_count;
>> - *decoded_options
>> - = (struct cl_decoded_option *)
>> - xrealloc (*decoded_options,
>> - (*decoded_options_count
>> - * sizeof (struct cl_decoded_option)));
>> - memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
>> - sizeof (struct cl_decoded_option));
>> -}
>> + for (unsigned i = 0; i < options.length (); ++i)
>> + if (options[i].opt_index == opt_index)
>> + return &options[i];
>
> You're returning a pointer into the vector here...
>
>> -/* Remove option number INDEX from DECODED_OPTIONS, update
>> - DECODED_OPTIONS_COUNT. */
>> + return NULL;
>> +}
>>
>> -static void
>> -remove_option (struct cl_decoded_option **decoded_options,
>> - int index, unsigned int *decoded_options_count)
>> +static cl_decoded_option *
>> +find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
>> {
>> - --*decoded_options_count;
>> - memmove (&(*decoded_options)[index + 1],
>> - &(*decoded_options)[index],
>> - sizeof (struct cl_decoded_option)
>> - * (*decoded_options_count - index));
>> + return find_option (options, option->opt_index);
>> }
>>
>> /* Try to merge and complain about options FDECODED_OPTIONS when applied
>> ontop of DECODED_OPTIONS. */
>>
>> static void
>> -merge_and_complain (struct cl_decoded_option **decoded_options,
>> - unsigned int *decoded_options_count,
>> - struct cl_decoded_option *fdecoded_options,
>> - unsigned int fdecoded_options_count,
>> - struct cl_decoded_option *decoded_cl_options,
>> - unsigned int decoded_cl_options_count)
>> +merge_and_complain (vec<cl_decoded_option> decoded_options,
>> + vec<cl_decoded_option> fdecoded_options,
>> + vec<cl_decoded_option> decoded_cl_options)
>> {
>> unsigned int i, j;
>> - struct cl_decoded_option *pic_option = NULL;
>> - struct cl_decoded_option *pie_option = NULL;
>> - struct cl_decoded_option *cf_protection_option = NULL;
>> + cl_decoded_option *pic_option = NULL;
>> + cl_decoded_option *pie_option = NULL;
>> + cl_decoded_option *cf_protection_option = NULL;
>>
>> /* ??? Merge options from files. Most cases can be
>> handled by either unioning or intersecting
>> @@ -223,9 +215,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>>
>> /* Look for a -fcf-protection option in the link-time options
>> which overrides any -fcf-protection from the lto sections. */
>> - for (i = 0; i < decoded_cl_options_count; ++i)
>> + for (i = 0; i < decoded_cl_options.length (); ++i)
>> {
>> - struct cl_decoded_option *foption = &decoded_cl_options[i];
>> + cl_decoded_option *foption = &decoded_cl_options[i];
>> if (foption->opt_index == OPT_fcf_protection_)
>> {
>> cf_protection_option = foption;
>> @@ -234,9 +226,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>>
>> /* The following does what the old LTO option code did,
>> union all target and a selected set of common options. */
>> - for (i = 0; i < fdecoded_options_count; ++i)
>> + for (i = 0; i < fdecoded_options.length (); ++i)
>> {
>> - struct cl_decoded_option *foption = &fdecoded_options[i];
>> + cl_decoded_option *foption = &fdecoded_options[i];
>> + cl_decoded_option *existing_opt = find_option (decoded_options, foption);
>> switch (foption->opt_index)
>> {
>> case OPT_SPECIAL_unknown:
>> @@ -264,11 +257,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> setting per OPT code, we pick the first we encounter.
>> ??? This doesn't make too much sense, but when it doesn't
>> then we should complain. */
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>
> and you end up re-allocating that here. That's an eventually dangerous
> pattern ... please consider to instead returning an index from find()
> (and -1 for not found or so).
>
>> break;
>>
>> /* Figure out what PIC/PIE level wins and merge the results. */
>> @@ -284,25 +274,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> case OPT_fopenmp:
>> case OPT_fopenacc:
>> /* For selected options we can merge conservatively. */
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> /* -fopenmp > -fno-openmp,
>> -fopenacc > -fno-openacc */
>> - else if (foption->value > (*decoded_options)[j].value)
>> - (*decoded_options)[j] = *foption;
>> + else if (foption->value > existing_opt->value)
>> + *existing_opt = *foption;
>> break;
>>
>> case OPT_fopenacc_dim_:
>> /* Append or check identical. */
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if (strcmp ((*decoded_options)[j].arg, foption->arg))
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (strcmp (existing_opt->arg, foption->arg))
>> fatal_error (input_location,
>> "option %s with different values",
>> foption->orig_option_with_args_text);
>> @@ -313,12 +297,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> if (!cf_protection_option
>> || cf_protection_option->value == CF_CHECK)
>> {
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if ((*decoded_options)[j].value != foption->value)
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (existing_opt->value != foption->value)
>> {
>> if (cf_protection_option
>> && cf_protection_option->value == CF_CHECK)
>> @@ -326,22 +307,21 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> "option %qs with mismatching values"
>> " (%s, %s)",
>> "-fcf-protection",
>> - (*decoded_options)[j].arg, foption->arg);
>> + existing_opt->arg, foption->arg);
>> else
>> {
>> /* Merge and update the -fcf-protection option. */
>> - (*decoded_options)[j].value &= (foption->value
>> - & CF_FULL);
>> - switch ((*decoded_options)[j].value)
>> + existing_opt->value &= (foption->value & CF_FULL);
>> + switch (existing_opt->value)
>> {
>> case CF_NONE:
>> - (*decoded_options)[j].arg = "none";
>> + existing_opt->arg = "none";
>> break;
>> case CF_BRANCH:
>> - (*decoded_options)[j].arg = "branch";
>> + existing_opt->arg = "branch";
>> break;
>> case CF_RETURN:
>> - (*decoded_options)[j].arg = "return";
>> + existing_opt->arg = "return";
>> break;
>> default:
>> gcc_unreachable ();
>> @@ -355,15 +335,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> case OPT_Ofast:
>> case OPT_Og:
>> case OPT_Os:
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == OPT_O
>> - || (*decoded_options)[j].opt_index == OPT_Ofast
>> - || (*decoded_options)[j].opt_index == OPT_Og
>> - || (*decoded_options)[j].opt_index == OPT_Os)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if ((*decoded_options)[j].opt_index == foption->opt_index
>> + existing_opt = NULL;
>> + for (j = 0; j < decoded_options.length (); ++j)
>> + if (decoded_options[j].opt_index == OPT_O
>> + || decoded_options[j].opt_index == OPT_Ofast
>> + || decoded_options[j].opt_index == OPT_Og
>> + || decoded_options[j].opt_index == OPT_Os)
>> + {
>> + existing_opt = &decoded_options[j];
>> + break;
>> + }
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (existing_opt->opt_index == foption->opt_index
>> && foption->opt_index != OPT_O)
>> /* Exact same options get merged. */
>> ;
>> @@ -393,13 +377,13 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> default:
>> gcc_unreachable ();
>> }
>> - switch ((*decoded_options)[j].opt_index)
>> + switch (existing_opt->opt_index)
>> {
>> case OPT_O:
>> - if ((*decoded_options)[j].arg[0] == '\0')
>> + if (existing_opt->arg[0] == '\0')
>> level = MAX (level, 1);
>> else
>> - level = MAX (level, atoi ((*decoded_options)[j].arg));
>> + level = MAX (level, atoi (existing_opt->arg));
>> break;
>> case OPT_Ofast:
>> level = MAX (level, 3);
>> @@ -413,23 +397,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> default:
>> gcc_unreachable ();
>> }
>> - (*decoded_options)[j].opt_index = OPT_O;
>> + existing_opt->opt_index = OPT_O;
>> char *tem;
>> tem = xasprintf ("-O%d", level);
>> - (*decoded_options)[j].arg = &tem[2];
>> - (*decoded_options)[j].canonical_option[0] = tem;
>> - (*decoded_options)[j].value = 1;
>> + existing_opt->arg = &tem[2];
>> + existing_opt->canonical_option[0] = tem;
>> + existing_opt->value = 1;
>> }
>> break;
>>
>>
>> case OPT_foffload_abi_:
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if (foption->value != (*decoded_options)[j].value)
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (foption->value != existing_opt->value)
>> fatal_error (input_location,
>> "option %s not used consistently in all LTO input"
>> " files", foption->orig_option_with_args_text);
>> @@ -437,7 +418,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>>
>>
>> case OPT_foffload_:
>> - append_option (decoded_options, decoded_options_count, foption);
>> + decoded_options.safe_push (*foption);
>> break;
>> }
>> }
>> @@ -457,12 +438,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> It would be good to warn on mismatches, but it is bit hard to do as
>> we do not know what nothing translates to. */
>>
>> - for (unsigned int j = 0; j < *decoded_options_count;)
>> - if ((*decoded_options)[j].opt_index == OPT_fPIC
>> - || (*decoded_options)[j].opt_index == OPT_fpic)
>> + for (unsigned int j = 0; j < decoded_options.length ();)
>> + if (decoded_options[j].opt_index == OPT_fPIC
>> + || decoded_options[j].opt_index == OPT_fpic)
>> {
>> /* -fno-pic in one unit implies -fno-pic everywhere. */
>> - if ((*decoded_options)[j].value == 0)
>> + if (decoded_options[j].value == 0)
>> j++;
>> /* If we have no pic option or merge in -fno-pic, we still may turn
>> existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
>> @@ -471,41 +452,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> {
>> if (pie_option)
>> {
>> - bool big = (*decoded_options)[j].opt_index == OPT_fPIC
>> + bool big = decoded_options[j].opt_index == OPT_fPIC
>> && pie_option->opt_index == OPT_fPIE;
>> - (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
>> + decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
>> if (pie_option->value)
>> - (*decoded_options)[j].canonical_option[0]
>> + decoded_options[j].canonical_option[0]
>> = big ? "-fPIE" : "-fpie";
>> else
>> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
>> - (*decoded_options)[j].value = pie_option->value;
>> - j++;
>> + decoded_options[j].canonical_option[0] = "-fno-pie";
>> + decoded_options[j].value = pie_option->value;
>> + j++;
>> }
>> else if (pic_option)
>> {
>> - (*decoded_options)[j] = *pic_option;
>> - j++;
>> + decoded_options[j] = *pic_option;
>> + j++;
>> }
>> /* We do not know if target defaults to pic or not, so just remove
>> option if it is missing in one unit but enabled in other. */
>> else
>> - remove_option (decoded_options, j, decoded_options_count);
>> + decoded_options.ordered_remove (j);
>> }
>> else if (pic_option->opt_index == OPT_fpic
>> - && (*decoded_options)[j].opt_index == OPT_fPIC)
>> + && decoded_options[j].opt_index == OPT_fPIC)
>> {
>> - (*decoded_options)[j] = *pic_option;
>> + decoded_options[j] = *pic_option;
>> j++;
>> }
>> else
>> j++;
>> }
>> - else if ((*decoded_options)[j].opt_index == OPT_fPIE
>> - || (*decoded_options)[j].opt_index == OPT_fpie)
>> + else if (decoded_options[j].opt_index == OPT_fPIE
>> + || decoded_options[j].opt_index == OPT_fpie)
>> {
>> /* -fno-pie in one unit implies -fno-pie everywhere. */
>> - if ((*decoded_options)[j].value == 0)
>> + if (decoded_options[j].value == 0)
>> j++;
>> /* If we have no pie option or merge in -fno-pie, we still preserve
>> PIE/pie if pic/PIC is present. */
>> @@ -516,32 +497,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> if (pic_option)
>> {
>> if (pic_option->opt_index == OPT_fpic
>> - && (*decoded_options)[j].opt_index == OPT_fPIE)
>> + && decoded_options[j].opt_index == OPT_fPIE)
>> {
>> - (*decoded_options)[j].opt_index = OPT_fpie;
>> - (*decoded_options)[j].canonical_option[0]
>> + decoded_options[j].opt_index = OPT_fpie;
>> + decoded_options[j].canonical_option[0]
>> = pic_option->value ? "-fpie" : "-fno-pie";
>> }
>> else if (!pic_option->value)
>> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
>> - (*decoded_options)[j].value = pic_option->value;
>> + decoded_options[j].canonical_option[0] = "-fno-pie";
>> + decoded_options[j].value = pic_option->value;
>> j++;
>> }
>> else if (pie_option)
>> {
>> - (*decoded_options)[j] = *pie_option;
>> + decoded_options[j] = *pie_option;
>> j++;
>> }
>> /* Because we always append pic/PIE options this code path should
>> not happen unless the LTO object was built by old lto1 which
>> did not contain that logic yet. */
>> else
>> - remove_option (decoded_options, j, decoded_options_count);
>> + decoded_options.ordered_remove (j);
>> }
>> else if (pie_option->opt_index == OPT_fpie
>> - && (*decoded_options)[j].opt_index == OPT_fPIE)
>> + && decoded_options[j].opt_index == OPT_fPIE)
>> {
>> - (*decoded_options)[j] = *pie_option;
>> + decoded_options[j] = *pie_option;
>> j++;
>> }
>> else
>> @@ -553,37 +534,34 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> if (!xassembler_options_error)
>> for (i = j = 0; ; i++, j++)
>> {
>> - for (; i < *decoded_options_count; i++)
>> - if ((*decoded_options)[i].opt_index == OPT_Xassembler)
>> - break;
>> -
>> - for (; j < fdecoded_options_count; j++)
>> - if (fdecoded_options[j].opt_index == OPT_Xassembler)
>> - break;
>> + cl_decoded_option *existing_opt
>> + = find_option (decoded_options, OPT_Xassembler);
>> + cl_decoded_option *existing_opt2
>> + = find_option (fdecoded_options, OPT_Xassembler);
>>
>> - if (i == *decoded_options_count && j == fdecoded_options_count)
>> + if (existing_opt == NULL && existing_opt2 == NULL)
>> break;
>> - else if (i < *decoded_options_count && j == fdecoded_options_count)
>> + else if (existing_opt != NULL && existing_opt2 == NULL)
>> {
>> warning (0, "Extra option to %<-Xassembler%>: %s,"
>> " dropping all %<-Xassembler%> and %<-Wa%> options.",
>> - (*decoded_options)[i].arg);
>> + existing_opt->arg);
>> xassembler_options_error = true;
>> break;
>> }
>> - else if (i == *decoded_options_count && j < fdecoded_options_count)
>> + else if (existing_opt == NULL && existing_opt2 != NULL)
>> {
>> warning (0, "Extra option to %<-Xassembler%>: %s,"
>> " dropping all %<-Xassembler%> and %<-Wa%> options.",
>> - fdecoded_options[j].arg);
>> + existing_opt2->arg);
>> xassembler_options_error = true;
>> break;
>> }
>> - else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg))
>> + else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
>> {
>> warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
>> " dropping all %<-Xassembler%> and %<-Wa%> options.",
>> - (*decoded_options)[i].arg, fdecoded_options[j].arg);
>> + existing_opt->arg, existing_opt2->arg);
>> xassembler_options_error = true;
>> break;
>> }
>> @@ -654,13 +632,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append)
>> /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
>>
>> static void
>> -append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> - unsigned int count)
>> +append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
>> {
>> /* Append compiler driver arguments as far as they were merged. */
>> - for (unsigned int j = 1; j < count; ++j)
>> + for (unsigned int j = 1; j < opts.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &opts[j];
>> + cl_decoded_option *option = &opts[j];
>>
>> /* File options have been properly filtered by lto-opts.c. */
>> switch (option->opt_index)
>> @@ -721,16 +698,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> }
>> }
>>
>> -/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */
>> +/* Append diag options in OPTS to ARGV_OBSTACK. */
>>
>> static void
>> -append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> - unsigned int count)
>> +append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
>> {
>> /* Append compiler driver arguments as far as they were merged. */
>> - for (unsigned int j = 1; j < count; ++j)
>> + for (unsigned int j = 1; j < opts.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &opts[j];
>> + cl_decoded_option *option = &opts[j];
>>
>> switch (option->opt_index)
>> {
>> @@ -757,14 +733,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> /* Append linker options OPTS to ARGV_OBSTACK. */
>>
>> static void
>> -append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> - unsigned int count)
>> +append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
>> {
>> /* Append linker driver arguments. Compiler options from the linker
>> driver arguments will override / merge with those from the compiler. */
>> - for (unsigned int j = 1; j < count; ++j)
>> + for (unsigned int j = 1; j < opts.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &opts[j];
>> + cl_decoded_option *option = &opts[j];
>>
>> /* Do not pass on frontend specific flags not suitable for lto. */
>> if (!(cl_options[option->opt_index].flags
>> @@ -802,15 +777,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>>
>> static void
>> append_offload_options (obstack *argv_obstack, const char *target,
>> - struct cl_decoded_option *options,
>> - unsigned int options_count)
>> + vec<cl_decoded_option> options)
>> {
>> - for (unsigned i = 0; i < options_count; i++)
>> + for (unsigned i = 0; i < options.length (); i++)
>> {
>> const char *cur, *next, *opts;
>> char **argv;
>> unsigned argc;
>> - struct cl_decoded_option *option = &options[i];
>> + cl_decoded_option *option = &options[i];
>>
>> if (option->opt_index != OPT_foffload_)
>> continue;
>> @@ -882,10 +856,8 @@ access_check (const char *name, int mode)
>> static char *
>> compile_offload_image (const char *target, const char *compiler_path,
>> unsigned in_argc, char *in_argv[],
>> - struct cl_decoded_option *compiler_opts,
>> - unsigned int compiler_opt_count,
>> - struct cl_decoded_option *linker_opts,
>> - unsigned int linker_opt_count)
>> + vec<cl_decoded_option> compiler_opts,
>> + vec<cl_decoded_option> linker_opts)
>> {
>> char *filename = NULL;
>> char *dumpbase;
>> @@ -935,19 +907,16 @@ compile_offload_image (const char *target, const char *compiler_path,
>> obstack_ptr_grow (&argv_obstack, in_argv[i]);
>>
>> /* Append options from offload_lto sections. */
>> - append_compiler_options (&argv_obstack, compiler_opts,
>> - compiler_opt_count);
>> - append_diag_options (&argv_obstack, linker_opts, linker_opt_count);
>> + append_compiler_options (&argv_obstack, compiler_opts);
>> + append_diag_options (&argv_obstack, linker_opts);
>>
>> obstack_ptr_grow (&argv_obstack, "-dumpbase");
>> obstack_ptr_grow (&argv_obstack, dumpbase);
>>
>> /* Append options specified by -foffload last. In case of conflicting
>> options we expect offload compiler to choose the latest. */
>> - append_offload_options (&argv_obstack, target, compiler_opts,
>> - compiler_opt_count);
>> - append_offload_options (&argv_obstack, target, linker_opts,
>> - linker_opt_count);
>> + append_offload_options (&argv_obstack, target, compiler_opts);
>> + append_offload_options (&argv_obstack, target, linker_opts);
>>
>> obstack_ptr_grow (&argv_obstack, NULL);
>> argv = XOBFINISH (&argv_obstack, char **);
>> @@ -966,10 +935,8 @@ compile_offload_image (const char *target, const char *compiler_path,
>>
>> static void
>> compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
>> - struct cl_decoded_option *compiler_opts,
>> - unsigned int compiler_opt_count,
>> - struct cl_decoded_option *linker_opts,
>> - unsigned int linker_opt_count)
>> + vec<cl_decoded_option> compiler_opts,
>> + vec<cl_decoded_option> linker_opts)
>> {
>> char **names = NULL;
>> const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
>> @@ -988,8 +955,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
>> {
>> offload_names[i]
>> = compile_offload_image (names[i], compiler_path, in_argc, in_argv,
>> - compiler_opts, compiler_opt_count,
>> - linker_opts, linker_opt_count);
>> + compiler_opts, linker_opts);
>> if (!offload_names[i])
>> fatal_error (input_location,
>> "problem with building target image for %s", names[i]);
>> @@ -1058,25 +1024,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx)
>> }
>>
>> /* A subroutine of run_gcc. Examine the open file FD for lto sections with
>> - name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
>> - and OPT_COUNT. Return true if we found a matching section, false
>> + name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
>> + Return true if we found a matching section, false
>> otherwise. COLLECT_GCC holds the value of the environment variable with
>> the same name. */
>>
>> static bool
>> find_and_merge_options (int fd, off_t file_offset, const char *prefix,
>> - struct cl_decoded_option *decoded_cl_options,
>> - unsigned int decoded_cl_options_count,
>> - struct cl_decoded_option **opts,
>> - unsigned int *opt_count, const char *collect_gcc)
>> + vec<cl_decoded_option> decoded_cl_options,
>> + vec<cl_decoded_option> *opts, const char *collect_gcc)
>> {
>> off_t offset, length;
>> char *data;
>> char *fopts;
>> const char *errmsg;
>> int err;
>> - struct cl_decoded_option *fdecoded_options = *opts;
>> - unsigned int fdecoded_options_count = *opt_count;
>> + vec<cl_decoded_option> fdecoded_options;
>>
>> simple_object_read *sobj;
>> sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
>> @@ -1098,24 +1061,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
>> data = (char *)xmalloc (length);
>> read (fd, data, length);
>> fopts = data;
>> + bool first = true;
>> do
>> {
>> - struct cl_decoded_option *f2decoded_options;
>> - unsigned int f2decoded_options_count;
>> - get_options_from_collect_gcc_options (collect_gcc, fopts,
>> - &f2decoded_options,
>> - &f2decoded_options_count);
>> - if (!fdecoded_options)
>> - {
>> - fdecoded_options = f2decoded_options;
>> - fdecoded_options_count = f2decoded_options_count;
>> - }
>> + vec<cl_decoded_option> f2decoded_options
>> + = get_options_from_collect_gcc_options (collect_gcc, fopts);
>> + if (first)
>> + {
>> + fdecoded_options = f2decoded_options;
>> + first = false;
>> + }
>> else
>> - merge_and_complain (&fdecoded_options,
>> - &fdecoded_options_count,
>> - f2decoded_options, f2decoded_options_count,
>> - decoded_cl_options,
>> - decoded_cl_options_count);
>> + merge_and_complain (fdecoded_options, f2decoded_options,
>> + decoded_cl_options);
>>
>> fopts += strlen (fopts) + 1;
>> }
>> @@ -1124,7 +1082,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
>> free (data);
>> simple_object_release_read (sobj);
>> *opts = fdecoded_options;
>> - *opt_count = fdecoded_options_count;
>> return true;
>> }
>>
>> @@ -1371,12 +1328,9 @@ run_gcc (unsigned argc, char *argv[])
>> int jobserver = 0;
>> int auto_parallel = 0;
>> bool no_partition = false;
>> - struct cl_decoded_option *fdecoded_options = NULL;
>> - struct cl_decoded_option *offload_fdecoded_options = NULL;
>> - unsigned int fdecoded_options_count = 0;
>> - unsigned int offload_fdecoded_options_count = 0;
>> - struct cl_decoded_option *decoded_options;
>> - unsigned int decoded_options_count;
>> + vec<cl_decoded_option> fdecoded_options;
>> + fdecoded_options.create (16);
>> + vec<cl_decoded_option> offload_fdecoded_options = vNULL;
>> struct obstack argv_obstack;
>> int new_head_argc;
>> bool have_lto = false;
>> @@ -1418,9 +1372,8 @@ run_gcc (unsigned argc, char *argv[])
>> NULL);
>> }
>>
>> - get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
>> - &decoded_options,
>> - &decoded_options_count);
>> + vec<cl_decoded_option> decoded_options
>> + = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
>>
>> /* Allocate array for input object files with LTO IL,
>> and for possible preceding arguments. */
>> @@ -1470,8 +1423,7 @@ run_gcc (unsigned argc, char *argv[])
>> }
>>
>> if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
>> - decoded_options, decoded_options_count,
>> - &fdecoded_options, &fdecoded_options_count,
>> + decoded_options, &fdecoded_options,
>> collect_gcc))
>> {
>> have_lto = true;
>> @@ -1486,14 +1438,13 @@ run_gcc (unsigned argc, char *argv[])
>> obstack_ptr_grow (&argv_obstack, "-xlto");
>> obstack_ptr_grow (&argv_obstack, "-c");
>>
>> - append_compiler_options (&argv_obstack, fdecoded_options,
>> - fdecoded_options_count);
>> - append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
>> + append_compiler_options (&argv_obstack, fdecoded_options);
>> + append_linker_options (&argv_obstack, decoded_options);
>>
>> /* Scan linker driver arguments for things that are of relevance to us. */
>> - for (j = 1; j < decoded_options_count; ++j)
>> + for (j = 1; j < decoded_options.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &decoded_options[j];
>> + cl_decoded_option *option = &decoded_options[j];
>> switch (option->opt_index)
>> {
>> case OPT_o:
>> @@ -1711,9 +1662,7 @@ cont1:
>> fatal_error (input_location, "cannot open %s: %m", filename);
>> if (!find_and_merge_options (fd, file_offset,
>> OFFLOAD_SECTION_NAME_PREFIX,
>> - decoded_options, decoded_options_count,
>> - &offload_fdecoded_options,
>> - &offload_fdecoded_options_count,
>> + decoded_options, &offload_fdecoded_options,
>> collect_gcc))
>> fatal_error (input_location, "cannot read %s: %m", filename);
>> close (fd);
>> @@ -1722,10 +1671,7 @@ cont1:
>> }
>>
>> compile_images_for_offload_targets (num_offload_files, offload_argv,
>> - offload_fdecoded_options,
>> - offload_fdecoded_options_count,
>> - decoded_options,
>> - decoded_options_count);
>> + offload_fdecoded_options, decoded_options);
>>
>> free_array_of_ptrs ((void **) offload_argv, num_offload_files);
>>
>> --
>> 2.31.1
>>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type.
2021-04-29 12:22 ` Richard Biener
2021-04-29 15:19 ` Martin Sebor
@ 2021-05-12 9:08 ` Martin Liška
2021-05-12 9:15 ` Richard Biener
1 sibling, 1 reply; 5+ messages in thread
From: Martin Liška @ 2021-05-12 9:08 UTC (permalink / raw)
To: Richard Biener; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 40167 bytes --]
On 4/29/21 2:22 PM, Richard Biener wrote:
> On Wed, Apr 21, 2021 at 11:12 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> Now living in the 21st century, we don't longer need using the following tuple:
>> cl_decoded_option **decoded_options,
>> unsigned int *decoded_options_count)
>> but we can rather use a standard (our) vector.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>> Thanks,
>> Martin
>>
>> gcc/ChangeLog:
>>
>> * lto-wrapper.c (get_options_from_collect_gcc_options): Change
>> return type.
>> (append_option): Remove.
>> (find_option): Rework to use the vector type.
>> (remove_option): Remove.
>> (merge_and_complain): Use vectors for cl_decoded_option data
>> type arguments.
>> (append_compiler_options): Likewise.
>> (append_diag_options): Likewise.
>> (append_linker_options): Likewise.
>> (append_offload_options): Likewise.
>> (compile_offload_image): Likewise.
>> (compile_images_for_offload_targets): Likewise.
>> (find_and_merge_options): Likewise.
>> (run_gcc): Likewise.
>> ---
>> gcc/lto-wrapper.c | 384 ++++++++++++++++++++--------------------------
>> 1 file changed, 165 insertions(+), 219 deletions(-)
>>
>> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
>> index 03a5922f8ea..5ccf729b249 100644
>> --- a/gcc/lto-wrapper.c
>> +++ b/gcc/lto-wrapper.c
>> @@ -138,12 +138,12 @@ maybe_unlink (const char *file)
>> /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
>> environment. */
>>
>> -static void
>> +static vec<cl_decoded_option>
>
> bonus points for handling ownership transfer via returning an
> auto_vec<> (not sure if possible, but maybe it is).
Heh, about the bonus points: changing return type of get_options_from_collect_gcc_options to auto_vec<...>
leads to:
==26737== Invalid read of size 4
==26737== at 0x406969: length (vec.h:589)
==26737== by 0x406969: length (vec.h:1439)
==26737== by 0x406969: append_compiler_options(obstack*, vec<cl_decoded_option, va_heap, vl_ptr>) (lto-wrapper.c:649)
==26737== by 0x408E35: run_gcc(unsigned int, char**) (lto-wrapper.c:1470)
==26737== by 0x406565: main (lto-wrapper.c:2070)
==26737== Address 0x57838a4 is 4 bytes inside a block of size 1,152 free'd
==26737== at 0x483FEC0: free (vg_replace_malloc.c:755)
==26737== by 0x4078B5: release<cl_decoded_option> (vec.h:316)
==26737== by 0x4078B5: release (vec.h:1832)
==26737== by 0x4078B5: ~auto_vec (vec.h:1552)
==26737== by 0x4078B5: find_and_merge_options(int, long, char const*, vec<cl_decoded_option, va_heap, vl_ptr>, vec<cl_decoded_option, va_heap, vl_ptr>*, char const*) (lto-wrapper.c:1100)
==26737== by 0x408D0E: run_gcc(unsigned int, char**) (lto-wrapper.c:1454)
==26737== by 0x406565: main (lto-wrapper.c:2070)
==26737== Block was alloc'd at
==26737== at 0x483D70F: malloc (vg_replace_malloc.c:380)
==26737== by 0x49554F: xrealloc (xmalloc.c:177)
==26737== by 0x4076CC: reserve<cl_decoded_option> (vec.h:290)
==26737== by 0x4076CC: reserve (vec.h:1778)
==26737== by 0x4076CC: reserve_exact (vec.h:1798)
==26737== by 0x4076CC: create (vec.h:1813)
==26737== by 0x4076CC: get_options_from_collect_gcc_options(char const*, char const*) (lto-wrapper.c:162)
==26737== by 0x4078FC: find_and_merge_options(int, long, char const*, vec<cl_decoded_option, va_heap, vl_ptr>, vec<cl_decoded_option, va_heap, vl_ptr>*, char const*) (lto-wrapper.c:1100)
==26737== by 0x408D0E: run_gcc(unsigned int, char**) (lto-wrapper.c:1454)
==26737== by 0x406565: main (lto-wrapper.c:2070)
>
>> get_options_from_collect_gcc_options (const char *collect_gcc,
>> - const char *collect_gcc_options,
>> - struct cl_decoded_option **decoded_options,
>> - unsigned int *decoded_options_count)
>> + const char *collect_gcc_options)
>> {
>> + cl_decoded_option *decoded_options;
>> + unsigned int decoded_options_count;
>> struct obstack argv_obstack;
>> const char **argv;
>> int argc;
>> @@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
>> argv = XOBFINISH (&argv_obstack, const char **);
>>
>> decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
>> - decoded_options, decoded_options_count);
>> + &decoded_options, &decoded_options_count);
>> + vec<cl_decoded_option> decoded;
>> + decoded.create (decoded_options_count);
>> + for (unsigned i = 0; i < decoded_options_count; ++i)
>> + decoded.quick_push (decoded_options[i]);
>> + free (decoded_options);
>> +
>> obstack_free (&argv_obstack, NULL);
>> +
>> + return decoded;
>> }
>>
>> -/* Append OPTION to the options array DECODED_OPTIONS with size
>> - DECODED_OPTIONS_COUNT. */
>> +/* Find option in OPTIONS based on OPT_INDEX. NULL value is returned
>> + if the option is not present. */
>>
>> -static void
>> -append_option (struct cl_decoded_option **decoded_options,
>> - unsigned int *decoded_options_count,
>> - struct cl_decoded_option *option)
>> +static cl_decoded_option *
>> +find_option (vec<cl_decoded_option> &options, size_t opt_index)
>> {
>> - ++*decoded_options_count;
>> - *decoded_options
>> - = (struct cl_decoded_option *)
>> - xrealloc (*decoded_options,
>> - (*decoded_options_count
>> - * sizeof (struct cl_decoded_option)));
>> - memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
>> - sizeof (struct cl_decoded_option));
>> -}
>> + for (unsigned i = 0; i < options.length (); ++i)
>> + if (options[i].opt_index == opt_index)
>> + return &options[i];
>
> You're returning a pointer into the vector here...
>
>> -/* Remove option number INDEX from DECODED_OPTIONS, update
>> - DECODED_OPTIONS_COUNT. */
>> + return NULL;
>> +}
>>
>> -static void
>> -remove_option (struct cl_decoded_option **decoded_options,
>> - int index, unsigned int *decoded_options_count)
>> +static cl_decoded_option *
>> +find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
>> {
>> - --*decoded_options_count;
>> - memmove (&(*decoded_options)[index + 1],
>> - &(*decoded_options)[index],
>> - sizeof (struct cl_decoded_option)
>> - * (*decoded_options_count - index));
>> + return find_option (options, option->opt_index);
>> }
>>
>> /* Try to merge and complain about options FDECODED_OPTIONS when applied
>> ontop of DECODED_OPTIONS. */
>>
>> static void
>> -merge_and_complain (struct cl_decoded_option **decoded_options,
>> - unsigned int *decoded_options_count,
>> - struct cl_decoded_option *fdecoded_options,
>> - unsigned int fdecoded_options_count,
>> - struct cl_decoded_option *decoded_cl_options,
>> - unsigned int decoded_cl_options_count)
>> +merge_and_complain (vec<cl_decoded_option> decoded_options,
>> + vec<cl_decoded_option> fdecoded_options,
>> + vec<cl_decoded_option> decoded_cl_options)
>> {
>> unsigned int i, j;
>> - struct cl_decoded_option *pic_option = NULL;
>> - struct cl_decoded_option *pie_option = NULL;
>> - struct cl_decoded_option *cf_protection_option = NULL;
>> + cl_decoded_option *pic_option = NULL;
>> + cl_decoded_option *pie_option = NULL;
>> + cl_decoded_option *cf_protection_option = NULL;
>>
>> /* ??? Merge options from files. Most cases can be
>> handled by either unioning or intersecting
>> @@ -223,9 +215,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>>
>> /* Look for a -fcf-protection option in the link-time options
>> which overrides any -fcf-protection from the lto sections. */
>> - for (i = 0; i < decoded_cl_options_count; ++i)
>> + for (i = 0; i < decoded_cl_options.length (); ++i)
>> {
>> - struct cl_decoded_option *foption = &decoded_cl_options[i];
>> + cl_decoded_option *foption = &decoded_cl_options[i];
>> if (foption->opt_index == OPT_fcf_protection_)
>> {
>> cf_protection_option = foption;
>> @@ -234,9 +226,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>>
>> /* The following does what the old LTO option code did,
>> union all target and a selected set of common options. */
>> - for (i = 0; i < fdecoded_options_count; ++i)
>> + for (i = 0; i < fdecoded_options.length (); ++i)
>> {
>> - struct cl_decoded_option *foption = &fdecoded_options[i];
>> + cl_decoded_option *foption = &fdecoded_options[i];
>> + cl_decoded_option *existing_opt = find_option (decoded_options, foption);
>> switch (foption->opt_index)
>> {
>> case OPT_SPECIAL_unknown:
>> @@ -264,11 +257,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> setting per OPT code, we pick the first we encounter.
>> ??? This doesn't make too much sense, but when it doesn't
>> then we should complain. */
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>
> and you end up re-allocating that here. That's an eventually dangerous
> pattern ... please consider to instead returning an index from find()
> (and -1 for not found or so).
You are right. I've done that in the patch and it survives regression tests.
May I install it? The auto_vec can be done incrementally I guess.
Martin
>
>> break;
>>
>> /* Figure out what PIC/PIE level wins and merge the results. */
>> @@ -284,25 +274,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> case OPT_fopenmp:
>> case OPT_fopenacc:
>> /* For selected options we can merge conservatively. */
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> /* -fopenmp > -fno-openmp,
>> -fopenacc > -fno-openacc */
>> - else if (foption->value > (*decoded_options)[j].value)
>> - (*decoded_options)[j] = *foption;
>> + else if (foption->value > existing_opt->value)
>> + *existing_opt = *foption;
>> break;
>>
>> case OPT_fopenacc_dim_:
>> /* Append or check identical. */
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if (strcmp ((*decoded_options)[j].arg, foption->arg))
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (strcmp (existing_opt->arg, foption->arg))
>> fatal_error (input_location,
>> "option %s with different values",
>> foption->orig_option_with_args_text);
>> @@ -313,12 +297,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> if (!cf_protection_option
>> || cf_protection_option->value == CF_CHECK)
>> {
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if ((*decoded_options)[j].value != foption->value)
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (existing_opt->value != foption->value)
>> {
>> if (cf_protection_option
>> && cf_protection_option->value == CF_CHECK)
>> @@ -326,22 +307,21 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> "option %qs with mismatching values"
>> " (%s, %s)",
>> "-fcf-protection",
>> - (*decoded_options)[j].arg, foption->arg);
>> + existing_opt->arg, foption->arg);
>> else
>> {
>> /* Merge and update the -fcf-protection option. */
>> - (*decoded_options)[j].value &= (foption->value
>> - & CF_FULL);
>> - switch ((*decoded_options)[j].value)
>> + existing_opt->value &= (foption->value & CF_FULL);
>> + switch (existing_opt->value)
>> {
>> case CF_NONE:
>> - (*decoded_options)[j].arg = "none";
>> + existing_opt->arg = "none";
>> break;
>> case CF_BRANCH:
>> - (*decoded_options)[j].arg = "branch";
>> + existing_opt->arg = "branch";
>> break;
>> case CF_RETURN:
>> - (*decoded_options)[j].arg = "return";
>> + existing_opt->arg = "return";
>> break;
>> default:
>> gcc_unreachable ();
>> @@ -355,15 +335,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> case OPT_Ofast:
>> case OPT_Og:
>> case OPT_Os:
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == OPT_O
>> - || (*decoded_options)[j].opt_index == OPT_Ofast
>> - || (*decoded_options)[j].opt_index == OPT_Og
>> - || (*decoded_options)[j].opt_index == OPT_Os)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if ((*decoded_options)[j].opt_index == foption->opt_index
>> + existing_opt = NULL;
>> + for (j = 0; j < decoded_options.length (); ++j)
>> + if (decoded_options[j].opt_index == OPT_O
>> + || decoded_options[j].opt_index == OPT_Ofast
>> + || decoded_options[j].opt_index == OPT_Og
>> + || decoded_options[j].opt_index == OPT_Os)
>> + {
>> + existing_opt = &decoded_options[j];
>> + break;
>> + }
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (existing_opt->opt_index == foption->opt_index
>> && foption->opt_index != OPT_O)
>> /* Exact same options get merged. */
>> ;
>> @@ -393,13 +377,13 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> default:
>> gcc_unreachable ();
>> }
>> - switch ((*decoded_options)[j].opt_index)
>> + switch (existing_opt->opt_index)
>> {
>> case OPT_O:
>> - if ((*decoded_options)[j].arg[0] == '\0')
>> + if (existing_opt->arg[0] == '\0')
>> level = MAX (level, 1);
>> else
>> - level = MAX (level, atoi ((*decoded_options)[j].arg));
>> + level = MAX (level, atoi (existing_opt->arg));
>> break;
>> case OPT_Ofast:
>> level = MAX (level, 3);
>> @@ -413,23 +397,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> default:
>> gcc_unreachable ();
>> }
>> - (*decoded_options)[j].opt_index = OPT_O;
>> + existing_opt->opt_index = OPT_O;
>> char *tem;
>> tem = xasprintf ("-O%d", level);
>> - (*decoded_options)[j].arg = &tem[2];
>> - (*decoded_options)[j].canonical_option[0] = tem;
>> - (*decoded_options)[j].value = 1;
>> + existing_opt->arg = &tem[2];
>> + existing_opt->canonical_option[0] = tem;
>> + existing_opt->value = 1;
>> }
>> break;
>>
>>
>> case OPT_foffload_abi_:
>> - for (j = 0; j < *decoded_options_count; ++j)
>> - if ((*decoded_options)[j].opt_index == foption->opt_index)
>> - break;
>> - if (j == *decoded_options_count)
>> - append_option (decoded_options, decoded_options_count, foption);
>> - else if (foption->value != (*decoded_options)[j].value)
>> + if (existing_opt == NULL)
>> + decoded_options.safe_push (*foption);
>> + else if (foption->value != existing_opt->value)
>> fatal_error (input_location,
>> "option %s not used consistently in all LTO input"
>> " files", foption->orig_option_with_args_text);
>> @@ -437,7 +418,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>>
>>
>> case OPT_foffload_:
>> - append_option (decoded_options, decoded_options_count, foption);
>> + decoded_options.safe_push (*foption);
>> break;
>> }
>> }
>> @@ -457,12 +438,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> It would be good to warn on mismatches, but it is bit hard to do as
>> we do not know what nothing translates to. */
>>
>> - for (unsigned int j = 0; j < *decoded_options_count;)
>> - if ((*decoded_options)[j].opt_index == OPT_fPIC
>> - || (*decoded_options)[j].opt_index == OPT_fpic)
>> + for (unsigned int j = 0; j < decoded_options.length ();)
>> + if (decoded_options[j].opt_index == OPT_fPIC
>> + || decoded_options[j].opt_index == OPT_fpic)
>> {
>> /* -fno-pic in one unit implies -fno-pic everywhere. */
>> - if ((*decoded_options)[j].value == 0)
>> + if (decoded_options[j].value == 0)
>> j++;
>> /* If we have no pic option or merge in -fno-pic, we still may turn
>> existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
>> @@ -471,41 +452,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> {
>> if (pie_option)
>> {
>> - bool big = (*decoded_options)[j].opt_index == OPT_fPIC
>> + bool big = decoded_options[j].opt_index == OPT_fPIC
>> && pie_option->opt_index == OPT_fPIE;
>> - (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
>> + decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
>> if (pie_option->value)
>> - (*decoded_options)[j].canonical_option[0]
>> + decoded_options[j].canonical_option[0]
>> = big ? "-fPIE" : "-fpie";
>> else
>> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
>> - (*decoded_options)[j].value = pie_option->value;
>> - j++;
>> + decoded_options[j].canonical_option[0] = "-fno-pie";
>> + decoded_options[j].value = pie_option->value;
>> + j++;
>> }
>> else if (pic_option)
>> {
>> - (*decoded_options)[j] = *pic_option;
>> - j++;
>> + decoded_options[j] = *pic_option;
>> + j++;
>> }
>> /* We do not know if target defaults to pic or not, so just remove
>> option if it is missing in one unit but enabled in other. */
>> else
>> - remove_option (decoded_options, j, decoded_options_count);
>> + decoded_options.ordered_remove (j);
>> }
>> else if (pic_option->opt_index == OPT_fpic
>> - && (*decoded_options)[j].opt_index == OPT_fPIC)
>> + && decoded_options[j].opt_index == OPT_fPIC)
>> {
>> - (*decoded_options)[j] = *pic_option;
>> + decoded_options[j] = *pic_option;
>> j++;
>> }
>> else
>> j++;
>> }
>> - else if ((*decoded_options)[j].opt_index == OPT_fPIE
>> - || (*decoded_options)[j].opt_index == OPT_fpie)
>> + else if (decoded_options[j].opt_index == OPT_fPIE
>> + || decoded_options[j].opt_index == OPT_fpie)
>> {
>> /* -fno-pie in one unit implies -fno-pie everywhere. */
>> - if ((*decoded_options)[j].value == 0)
>> + if (decoded_options[j].value == 0)
>> j++;
>> /* If we have no pie option or merge in -fno-pie, we still preserve
>> PIE/pie if pic/PIC is present. */
>> @@ -516,32 +497,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> if (pic_option)
>> {
>> if (pic_option->opt_index == OPT_fpic
>> - && (*decoded_options)[j].opt_index == OPT_fPIE)
>> + && decoded_options[j].opt_index == OPT_fPIE)
>> {
>> - (*decoded_options)[j].opt_index = OPT_fpie;
>> - (*decoded_options)[j].canonical_option[0]
>> + decoded_options[j].opt_index = OPT_fpie;
>> + decoded_options[j].canonical_option[0]
>> = pic_option->value ? "-fpie" : "-fno-pie";
>> }
>> else if (!pic_option->value)
>> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
>> - (*decoded_options)[j].value = pic_option->value;
>> + decoded_options[j].canonical_option[0] = "-fno-pie";
>> + decoded_options[j].value = pic_option->value;
>> j++;
>> }
>> else if (pie_option)
>> {
>> - (*decoded_options)[j] = *pie_option;
>> + decoded_options[j] = *pie_option;
>> j++;
>> }
>> /* Because we always append pic/PIE options this code path should
>> not happen unless the LTO object was built by old lto1 which
>> did not contain that logic yet. */
>> else
>> - remove_option (decoded_options, j, decoded_options_count);
>> + decoded_options.ordered_remove (j);
>> }
>> else if (pie_option->opt_index == OPT_fpie
>> - && (*decoded_options)[j].opt_index == OPT_fPIE)
>> + && decoded_options[j].opt_index == OPT_fPIE)
>> {
>> - (*decoded_options)[j] = *pie_option;
>> + decoded_options[j] = *pie_option;
>> j++;
>> }
>> else
>> @@ -553,37 +534,34 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
>> if (!xassembler_options_error)
>> for (i = j = 0; ; i++, j++)
>> {
>> - for (; i < *decoded_options_count; i++)
>> - if ((*decoded_options)[i].opt_index == OPT_Xassembler)
>> - break;
>> -
>> - for (; j < fdecoded_options_count; j++)
>> - if (fdecoded_options[j].opt_index == OPT_Xassembler)
>> - break;
>> + cl_decoded_option *existing_opt
>> + = find_option (decoded_options, OPT_Xassembler);
>> + cl_decoded_option *existing_opt2
>> + = find_option (fdecoded_options, OPT_Xassembler);
>>
>> - if (i == *decoded_options_count && j == fdecoded_options_count)
>> + if (existing_opt == NULL && existing_opt2 == NULL)
>> break;
>> - else if (i < *decoded_options_count && j == fdecoded_options_count)
>> + else if (existing_opt != NULL && existing_opt2 == NULL)
>> {
>> warning (0, "Extra option to %<-Xassembler%>: %s,"
>> " dropping all %<-Xassembler%> and %<-Wa%> options.",
>> - (*decoded_options)[i].arg);
>> + existing_opt->arg);
>> xassembler_options_error = true;
>> break;
>> }
>> - else if (i == *decoded_options_count && j < fdecoded_options_count)
>> + else if (existing_opt == NULL && existing_opt2 != NULL)
>> {
>> warning (0, "Extra option to %<-Xassembler%>: %s,"
>> " dropping all %<-Xassembler%> and %<-Wa%> options.",
>> - fdecoded_options[j].arg);
>> + existing_opt2->arg);
>> xassembler_options_error = true;
>> break;
>> }
>> - else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg))
>> + else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
>> {
>> warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
>> " dropping all %<-Xassembler%> and %<-Wa%> options.",
>> - (*decoded_options)[i].arg, fdecoded_options[j].arg);
>> + existing_opt->arg, existing_opt2->arg);
>> xassembler_options_error = true;
>> break;
>> }
>> @@ -654,13 +632,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append)
>> /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
>>
>> static void
>> -append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> - unsigned int count)
>> +append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
>> {
>> /* Append compiler driver arguments as far as they were merged. */
>> - for (unsigned int j = 1; j < count; ++j)
>> + for (unsigned int j = 1; j < opts.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &opts[j];
>> + cl_decoded_option *option = &opts[j];
>>
>> /* File options have been properly filtered by lto-opts.c. */
>> switch (option->opt_index)
>> @@ -721,16 +698,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> }
>> }
>>
>> -/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */
>> +/* Append diag options in OPTS to ARGV_OBSTACK. */
>>
>> static void
>> -append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> - unsigned int count)
>> +append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
>> {
>> /* Append compiler driver arguments as far as they were merged. */
>> - for (unsigned int j = 1; j < count; ++j)
>> + for (unsigned int j = 1; j < opts.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &opts[j];
>> + cl_decoded_option *option = &opts[j];
>>
>> switch (option->opt_index)
>> {
>> @@ -757,14 +733,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> /* Append linker options OPTS to ARGV_OBSTACK. */
>>
>> static void
>> -append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>> - unsigned int count)
>> +append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
>> {
>> /* Append linker driver arguments. Compiler options from the linker
>> driver arguments will override / merge with those from the compiler. */
>> - for (unsigned int j = 1; j < count; ++j)
>> + for (unsigned int j = 1; j < opts.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &opts[j];
>> + cl_decoded_option *option = &opts[j];
>>
>> /* Do not pass on frontend specific flags not suitable for lto. */
>> if (!(cl_options[option->opt_index].flags
>> @@ -802,15 +777,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
>>
>> static void
>> append_offload_options (obstack *argv_obstack, const char *target,
>> - struct cl_decoded_option *options,
>> - unsigned int options_count)
>> + vec<cl_decoded_option> options)
>> {
>> - for (unsigned i = 0; i < options_count; i++)
>> + for (unsigned i = 0; i < options.length (); i++)
>> {
>> const char *cur, *next, *opts;
>> char **argv;
>> unsigned argc;
>> - struct cl_decoded_option *option = &options[i];
>> + cl_decoded_option *option = &options[i];
>>
>> if (option->opt_index != OPT_foffload_)
>> continue;
>> @@ -882,10 +856,8 @@ access_check (const char *name, int mode)
>> static char *
>> compile_offload_image (const char *target, const char *compiler_path,
>> unsigned in_argc, char *in_argv[],
>> - struct cl_decoded_option *compiler_opts,
>> - unsigned int compiler_opt_count,
>> - struct cl_decoded_option *linker_opts,
>> - unsigned int linker_opt_count)
>> + vec<cl_decoded_option> compiler_opts,
>> + vec<cl_decoded_option> linker_opts)
>> {
>> char *filename = NULL;
>> char *dumpbase;
>> @@ -935,19 +907,16 @@ compile_offload_image (const char *target, const char *compiler_path,
>> obstack_ptr_grow (&argv_obstack, in_argv[i]);
>>
>> /* Append options from offload_lto sections. */
>> - append_compiler_options (&argv_obstack, compiler_opts,
>> - compiler_opt_count);
>> - append_diag_options (&argv_obstack, linker_opts, linker_opt_count);
>> + append_compiler_options (&argv_obstack, compiler_opts);
>> + append_diag_options (&argv_obstack, linker_opts);
>>
>> obstack_ptr_grow (&argv_obstack, "-dumpbase");
>> obstack_ptr_grow (&argv_obstack, dumpbase);
>>
>> /* Append options specified by -foffload last. In case of conflicting
>> options we expect offload compiler to choose the latest. */
>> - append_offload_options (&argv_obstack, target, compiler_opts,
>> - compiler_opt_count);
>> - append_offload_options (&argv_obstack, target, linker_opts,
>> - linker_opt_count);
>> + append_offload_options (&argv_obstack, target, compiler_opts);
>> + append_offload_options (&argv_obstack, target, linker_opts);
>>
>> obstack_ptr_grow (&argv_obstack, NULL);
>> argv = XOBFINISH (&argv_obstack, char **);
>> @@ -966,10 +935,8 @@ compile_offload_image (const char *target, const char *compiler_path,
>>
>> static void
>> compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
>> - struct cl_decoded_option *compiler_opts,
>> - unsigned int compiler_opt_count,
>> - struct cl_decoded_option *linker_opts,
>> - unsigned int linker_opt_count)
>> + vec<cl_decoded_option> compiler_opts,
>> + vec<cl_decoded_option> linker_opts)
>> {
>> char **names = NULL;
>> const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
>> @@ -988,8 +955,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
>> {
>> offload_names[i]
>> = compile_offload_image (names[i], compiler_path, in_argc, in_argv,
>> - compiler_opts, compiler_opt_count,
>> - linker_opts, linker_opt_count);
>> + compiler_opts, linker_opts);
>> if (!offload_names[i])
>> fatal_error (input_location,
>> "problem with building target image for %s", names[i]);
>> @@ -1058,25 +1024,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx)
>> }
>>
>> /* A subroutine of run_gcc. Examine the open file FD for lto sections with
>> - name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
>> - and OPT_COUNT. Return true if we found a matching section, false
>> + name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
>> + Return true if we found a matching section, false
>> otherwise. COLLECT_GCC holds the value of the environment variable with
>> the same name. */
>>
>> static bool
>> find_and_merge_options (int fd, off_t file_offset, const char *prefix,
>> - struct cl_decoded_option *decoded_cl_options,
>> - unsigned int decoded_cl_options_count,
>> - struct cl_decoded_option **opts,
>> - unsigned int *opt_count, const char *collect_gcc)
>> + vec<cl_decoded_option> decoded_cl_options,
>> + vec<cl_decoded_option> *opts, const char *collect_gcc)
>> {
>> off_t offset, length;
>> char *data;
>> char *fopts;
>> const char *errmsg;
>> int err;
>> - struct cl_decoded_option *fdecoded_options = *opts;
>> - unsigned int fdecoded_options_count = *opt_count;
>> + vec<cl_decoded_option> fdecoded_options;
>>
>> simple_object_read *sobj;
>> sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
>> @@ -1098,24 +1061,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
>> data = (char *)xmalloc (length);
>> read (fd, data, length);
>> fopts = data;
>> + bool first = true;
>> do
>> {
>> - struct cl_decoded_option *f2decoded_options;
>> - unsigned int f2decoded_options_count;
>> - get_options_from_collect_gcc_options (collect_gcc, fopts,
>> - &f2decoded_options,
>> - &f2decoded_options_count);
>> - if (!fdecoded_options)
>> - {
>> - fdecoded_options = f2decoded_options;
>> - fdecoded_options_count = f2decoded_options_count;
>> - }
>> + vec<cl_decoded_option> f2decoded_options
>> + = get_options_from_collect_gcc_options (collect_gcc, fopts);
>> + if (first)
>> + {
>> + fdecoded_options = f2decoded_options;
>> + first = false;
>> + }
>> else
>> - merge_and_complain (&fdecoded_options,
>> - &fdecoded_options_count,
>> - f2decoded_options, f2decoded_options_count,
>> - decoded_cl_options,
>> - decoded_cl_options_count);
>> + merge_and_complain (fdecoded_options, f2decoded_options,
>> + decoded_cl_options);
>>
>> fopts += strlen (fopts) + 1;
>> }
>> @@ -1124,7 +1082,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
>> free (data);
>> simple_object_release_read (sobj);
>> *opts = fdecoded_options;
>> - *opt_count = fdecoded_options_count;
>> return true;
>> }
>>
>> @@ -1371,12 +1328,9 @@ run_gcc (unsigned argc, char *argv[])
>> int jobserver = 0;
>> int auto_parallel = 0;
>> bool no_partition = false;
>> - struct cl_decoded_option *fdecoded_options = NULL;
>> - struct cl_decoded_option *offload_fdecoded_options = NULL;
>> - unsigned int fdecoded_options_count = 0;
>> - unsigned int offload_fdecoded_options_count = 0;
>> - struct cl_decoded_option *decoded_options;
>> - unsigned int decoded_options_count;
>> + vec<cl_decoded_option> fdecoded_options;
>> + fdecoded_options.create (16);
>> + vec<cl_decoded_option> offload_fdecoded_options = vNULL;
>> struct obstack argv_obstack;
>> int new_head_argc;
>> bool have_lto = false;
>> @@ -1418,9 +1372,8 @@ run_gcc (unsigned argc, char *argv[])
>> NULL);
>> }
>>
>> - get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
>> - &decoded_options,
>> - &decoded_options_count);
>> + vec<cl_decoded_option> decoded_options
>> + = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
>>
>> /* Allocate array for input object files with LTO IL,
>> and for possible preceding arguments. */
>> @@ -1470,8 +1423,7 @@ run_gcc (unsigned argc, char *argv[])
>> }
>>
>> if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
>> - decoded_options, decoded_options_count,
>> - &fdecoded_options, &fdecoded_options_count,
>> + decoded_options, &fdecoded_options,
>> collect_gcc))
>> {
>> have_lto = true;
>> @@ -1486,14 +1438,13 @@ run_gcc (unsigned argc, char *argv[])
>> obstack_ptr_grow (&argv_obstack, "-xlto");
>> obstack_ptr_grow (&argv_obstack, "-c");
>>
>> - append_compiler_options (&argv_obstack, fdecoded_options,
>> - fdecoded_options_count);
>> - append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
>> + append_compiler_options (&argv_obstack, fdecoded_options);
>> + append_linker_options (&argv_obstack, decoded_options);
>>
>> /* Scan linker driver arguments for things that are of relevance to us. */
>> - for (j = 1; j < decoded_options_count; ++j)
>> + for (j = 1; j < decoded_options.length (); ++j)
>> {
>> - struct cl_decoded_option *option = &decoded_options[j];
>> + cl_decoded_option *option = &decoded_options[j];
>> switch (option->opt_index)
>> {
>> case OPT_o:
>> @@ -1711,9 +1662,7 @@ cont1:
>> fatal_error (input_location, "cannot open %s: %m", filename);
>> if (!find_and_merge_options (fd, file_offset,
>> OFFLOAD_SECTION_NAME_PREFIX,
>> - decoded_options, decoded_options_count,
>> - &offload_fdecoded_options,
>> - &offload_fdecoded_options_count,
>> + decoded_options, &offload_fdecoded_options,
>> collect_gcc))
>> fatal_error (input_location, "cannot read %s: %m", filename);
>> close (fd);
>> @@ -1722,10 +1671,7 @@ cont1:
>> }
>>
>> compile_images_for_offload_targets (num_offload_files, offload_argv,
>> - offload_fdecoded_options,
>> - offload_fdecoded_options_count,
>> - decoded_options,
>> - decoded_options_count);
>> + offload_fdecoded_options, decoded_options);
>>
>> free_array_of_ptrs ((void **) offload_argv, num_offload_files);
>>
>> --
>> 2.31.1
>>
>
[-- Attachment #2: 0001-lto-wrapper-Use-vec-cl_decoded_option-data-type.patch --]
[-- Type: text/x-patch, Size: 30595 bytes --]
From 6bfa86b423fd8017a80fd12e609dfee15b0befbe Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Fri, 12 Mar 2021 11:53:47 +0100
Subject: [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type.
gcc/ChangeLog:
* lto-wrapper.c (get_options_from_collect_gcc_options): Change
return type.
(append_option): Remove.
(find_option): Rework to use the vector type.
(remove_option): Remove.
(merge_and_complain): Use vectors for cl_decoded_option data
type arguments.
(append_compiler_options): Likewise.
(append_diag_options): Likewise.
(append_linker_options): Likewise.
(append_offload_options): Likewise.
(compile_offload_image): Likewise.
(compile_images_for_offload_targets): Likewise.
(find_and_merge_options): Likewise.
(run_gcc): Likewise.
---
gcc/lto-wrapper.c | 396 +++++++++++++++++++++-------------------------
1 file changed, 176 insertions(+), 220 deletions(-)
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index d6be7f016bf..11d4d20c494 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -139,12 +139,12 @@ maybe_unlink (const char *file)
/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
environment. */
-static void
+static vec<cl_decoded_option>
get_options_from_collect_gcc_options (const char *collect_gcc,
- const char *collect_gcc_options,
- struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count)
+ const char *collect_gcc_options)
{
+ cl_decoded_option *decoded_options;
+ unsigned int decoded_options_count;
struct obstack argv_obstack;
const char **argv;
int argc;
@@ -157,57 +157,49 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
argv = XOBFINISH (&argv_obstack, const char **);
decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
- decoded_options, decoded_options_count);
+ &decoded_options, &decoded_options_count);
+ vec<cl_decoded_option> decoded;
+ decoded.create (decoded_options_count);
+ for (unsigned i = 0; i < decoded_options_count; ++i)
+ decoded.quick_push (decoded_options[i]);
+ free (decoded_options);
+
obstack_free (&argv_obstack, NULL);
+
+ return decoded;
}
-/* Append OPTION to the options array DECODED_OPTIONS with size
- DECODED_OPTIONS_COUNT. */
+/* Find option in OPTIONS based on OPT_INDEX. -1 value is returned
+ if the option is not present. */
-static void
-append_option (struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count,
- struct cl_decoded_option *option)
+static int
+find_option (vec<cl_decoded_option> &options, size_t opt_index)
{
- ++*decoded_options_count;
- *decoded_options
- = (struct cl_decoded_option *)
- xrealloc (*decoded_options,
- (*decoded_options_count
- * sizeof (struct cl_decoded_option)));
- memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
- sizeof (struct cl_decoded_option));
-}
+ for (unsigned i = 0; i < options.length (); ++i)
+ if (options[i].opt_index == opt_index)
+ return i;
-/* Remove option number INDEX from DECODED_OPTIONS, update
- DECODED_OPTIONS_COUNT. */
+ return -1;
+}
-static void
-remove_option (struct cl_decoded_option **decoded_options,
- int index, unsigned int *decoded_options_count)
+static int
+find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
{
- --*decoded_options_count;
- memmove (&(*decoded_options)[index + 1],
- &(*decoded_options)[index],
- sizeof (struct cl_decoded_option)
- * (*decoded_options_count - index));
+ return find_option (options, option->opt_index);
}
/* Try to merge and complain about options FDECODED_OPTIONS when applied
ontop of DECODED_OPTIONS. */
static void
-merge_and_complain (struct cl_decoded_option **decoded_options,
- unsigned int *decoded_options_count,
- struct cl_decoded_option *fdecoded_options,
- unsigned int fdecoded_options_count,
- struct cl_decoded_option *decoded_cl_options,
- unsigned int decoded_cl_options_count)
+merge_and_complain (vec<cl_decoded_option> decoded_options,
+ vec<cl_decoded_option> fdecoded_options,
+ vec<cl_decoded_option> decoded_cl_options)
{
unsigned int i, j;
- struct cl_decoded_option *pic_option = NULL;
- struct cl_decoded_option *pie_option = NULL;
- struct cl_decoded_option *cf_protection_option = NULL;
+ cl_decoded_option *pic_option = NULL;
+ cl_decoded_option *pie_option = NULL;
+ cl_decoded_option *cf_protection_option = NULL;
/* ??? Merge options from files. Most cases can be
handled by either unioning or intersecting
@@ -224,9 +216,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
/* Look for a -fcf-protection option in the link-time options
which overrides any -fcf-protection from the lto sections. */
- for (i = 0; i < decoded_cl_options_count; ++i)
+ for (i = 0; i < decoded_cl_options.length (); ++i)
{
- struct cl_decoded_option *foption = &decoded_cl_options[i];
+ cl_decoded_option *foption = &decoded_cl_options[i];
if (foption->opt_index == OPT_fcf_protection_)
{
cf_protection_option = foption;
@@ -235,9 +227,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
/* The following does what the old LTO option code did,
union all target and a selected set of common options. */
- for (i = 0; i < fdecoded_options_count; ++i)
+ for (i = 0; i < fdecoded_options.length (); ++i)
{
- struct cl_decoded_option *foption = &fdecoded_options[i];
+ cl_decoded_option *foption = &fdecoded_options[i];
+ int existing_opt = find_option (decoded_options, foption);
switch (foption->opt_index)
{
case OPT_SPECIAL_unknown:
@@ -265,11 +258,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
setting per OPT code, we pick the first we encounter.
??? This doesn't make too much sense, but when it doesn't
then we should complain. */
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
+ if (existing_opt == -1)
+ decoded_options.safe_push (*foption);
break;
/* Figure out what PIC/PIE level wins and merge the results. */
@@ -285,25 +275,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_fopenmp:
case OPT_fopenacc:
/* For selected options we can merge conservatively. */
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
+ if (existing_opt == -1)
+ decoded_options.safe_push (*foption);
/* -fopenmp > -fno-openmp,
-fopenacc > -fno-openacc */
- else if (foption->value > (*decoded_options)[j].value)
- (*decoded_options)[j] = *foption;
+ else if (foption->value > decoded_options[existing_opt].value)
+ decoded_options[existing_opt] = *foption;
break;
case OPT_fopenacc_dim_:
/* Append or check identical. */
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if (strcmp ((*decoded_options)[j].arg, foption->arg))
+ if (existing_opt == -1)
+ decoded_options.safe_push (*foption);
+ else if (strcmp (decoded_options[existing_opt].arg, foption->arg))
fatal_error (input_location,
"option %s with different values",
foption->orig_option_with_args_text);
@@ -314,12 +298,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (!cf_protection_option
|| cf_protection_option->value == CF_CHECK)
{
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if ((*decoded_options)[j].value != foption->value)
+ if (existing_opt == -1)
+ decoded_options.safe_push (*foption);
+ else if (decoded_options[existing_opt].value != foption->value)
{
if (cf_protection_option
&& cf_protection_option->value == CF_CHECK)
@@ -327,22 +308,23 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
"option %qs with mismatching values"
" (%s, %s)",
"-fcf-protection",
- (*decoded_options)[j].arg, foption->arg);
+ decoded_options[existing_opt].arg,
+ foption->arg);
else
{
/* Merge and update the -fcf-protection option. */
- (*decoded_options)[j].value &= (foption->value
- & CF_FULL);
- switch ((*decoded_options)[j].value)
+ decoded_options[existing_opt].value
+ &= (foption->value & CF_FULL);
+ switch (decoded_options[existing_opt].value)
{
case CF_NONE:
- (*decoded_options)[j].arg = "none";
+ decoded_options[existing_opt].arg = "none";
break;
case CF_BRANCH:
- (*decoded_options)[j].arg = "branch";
+ decoded_options[existing_opt].arg = "branch";
break;
case CF_RETURN:
- (*decoded_options)[j].arg = "return";
+ decoded_options[existing_opt].arg = "return";
break;
default:
gcc_unreachable ();
@@ -356,15 +338,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_Ofast:
case OPT_Og:
case OPT_Os:
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == OPT_O
- || (*decoded_options)[j].opt_index == OPT_Ofast
- || (*decoded_options)[j].opt_index == OPT_Og
- || (*decoded_options)[j].opt_index == OPT_Os)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if ((*decoded_options)[j].opt_index == foption->opt_index
+ existing_opt = -1;
+ for (j = 0; j < decoded_options.length (); ++j)
+ if (decoded_options[j].opt_index == OPT_O
+ || decoded_options[j].opt_index == OPT_Ofast
+ || decoded_options[j].opt_index == OPT_Og
+ || decoded_options[j].opt_index == OPT_Os)
+ {
+ existing_opt = j;
+ break;
+ }
+ if (existing_opt == -1)
+ decoded_options.safe_push (*foption);
+ else if (decoded_options[existing_opt].opt_index == foption->opt_index
&& foption->opt_index != OPT_O)
/* Exact same options get merged. */
;
@@ -394,13 +380,14 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
default:
gcc_unreachable ();
}
- switch ((*decoded_options)[j].opt_index)
+ switch (decoded_options[existing_opt].opt_index)
{
case OPT_O:
- if ((*decoded_options)[j].arg[0] == '\0')
+ if (decoded_options[existing_opt].arg[0] == '\0')
level = MAX (level, 1);
else
- level = MAX (level, atoi ((*decoded_options)[j].arg));
+ level = MAX (level,
+ atoi (decoded_options[existing_opt].arg));
break;
case OPT_Ofast:
level = MAX (level, 3);
@@ -414,23 +401,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
default:
gcc_unreachable ();
}
- (*decoded_options)[j].opt_index = OPT_O;
+ decoded_options[existing_opt].opt_index = OPT_O;
char *tem;
tem = xasprintf ("-O%d", level);
- (*decoded_options)[j].arg = &tem[2];
- (*decoded_options)[j].canonical_option[0] = tem;
- (*decoded_options)[j].value = 1;
+ decoded_options[existing_opt].arg = &tem[2];
+ decoded_options[existing_opt].canonical_option[0] = tem;
+ decoded_options[existing_opt].value = 1;
}
break;
case OPT_foffload_abi_:
- for (j = 0; j < *decoded_options_count; ++j)
- if ((*decoded_options)[j].opt_index == foption->opt_index)
- break;
- if (j == *decoded_options_count)
- append_option (decoded_options, decoded_options_count, foption);
- else if (foption->value != (*decoded_options)[j].value)
+ if (existing_opt == -1)
+ decoded_options.safe_push (*foption);
+ else if (foption->value != decoded_options[existing_opt].value)
fatal_error (input_location,
"option %s not used consistently in all LTO input"
" files", foption->orig_option_with_args_text);
@@ -438,7 +422,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_foffload_:
- append_option (decoded_options, decoded_options_count, foption);
+ decoded_options.safe_push (*foption);
break;
}
}
@@ -458,12 +442,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
It would be good to warn on mismatches, but it is bit hard to do as
we do not know what nothing translates to. */
- for (unsigned int j = 0; j < *decoded_options_count;)
- if ((*decoded_options)[j].opt_index == OPT_fPIC
- || (*decoded_options)[j].opt_index == OPT_fpic)
+ for (unsigned int j = 0; j < decoded_options.length ();)
+ if (decoded_options[j].opt_index == OPT_fPIC
+ || decoded_options[j].opt_index == OPT_fpic)
{
/* -fno-pic in one unit implies -fno-pic everywhere. */
- if ((*decoded_options)[j].value == 0)
+ if (decoded_options[j].value == 0)
j++;
/* If we have no pic option or merge in -fno-pic, we still may turn
existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
@@ -472,41 +456,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
{
if (pie_option)
{
- bool big = (*decoded_options)[j].opt_index == OPT_fPIC
+ bool big = decoded_options[j].opt_index == OPT_fPIC
&& pie_option->opt_index == OPT_fPIE;
- (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
+ decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
if (pie_option->value)
- (*decoded_options)[j].canonical_option[0]
+ decoded_options[j].canonical_option[0]
= big ? "-fPIE" : "-fpie";
else
- (*decoded_options)[j].canonical_option[0] = "-fno-pie";
- (*decoded_options)[j].value = pie_option->value;
- j++;
+ decoded_options[j].canonical_option[0] = "-fno-pie";
+ decoded_options[j].value = pie_option->value;
+ j++;
}
else if (pic_option)
{
- (*decoded_options)[j] = *pic_option;
- j++;
+ decoded_options[j] = *pic_option;
+ j++;
}
/* We do not know if target defaults to pic or not, so just remove
option if it is missing in one unit but enabled in other. */
else
- remove_option (decoded_options, j, decoded_options_count);
+ decoded_options.ordered_remove (j);
}
else if (pic_option->opt_index == OPT_fpic
- && (*decoded_options)[j].opt_index == OPT_fPIC)
+ && decoded_options[j].opt_index == OPT_fPIC)
{
- (*decoded_options)[j] = *pic_option;
+ decoded_options[j] = *pic_option;
j++;
}
else
j++;
}
- else if ((*decoded_options)[j].opt_index == OPT_fPIE
- || (*decoded_options)[j].opt_index == OPT_fpie)
+ else if (decoded_options[j].opt_index == OPT_fPIE
+ || decoded_options[j].opt_index == OPT_fpie)
{
/* -fno-pie in one unit implies -fno-pie everywhere. */
- if ((*decoded_options)[j].value == 0)
+ if (decoded_options[j].value == 0)
j++;
/* If we have no pie option or merge in -fno-pie, we still preserve
PIE/pie if pic/PIC is present. */
@@ -517,32 +501,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (pic_option)
{
if (pic_option->opt_index == OPT_fpic
- && (*decoded_options)[j].opt_index == OPT_fPIE)
+ && decoded_options[j].opt_index == OPT_fPIE)
{
- (*decoded_options)[j].opt_index = OPT_fpie;
- (*decoded_options)[j].canonical_option[0]
+ decoded_options[j].opt_index = OPT_fpie;
+ decoded_options[j].canonical_option[0]
= pic_option->value ? "-fpie" : "-fno-pie";
}
else if (!pic_option->value)
- (*decoded_options)[j].canonical_option[0] = "-fno-pie";
- (*decoded_options)[j].value = pic_option->value;
+ decoded_options[j].canonical_option[0] = "-fno-pie";
+ decoded_options[j].value = pic_option->value;
j++;
}
else if (pie_option)
{
- (*decoded_options)[j] = *pie_option;
+ decoded_options[j] = *pie_option;
j++;
}
/* Because we always append pic/PIE options this code path should
not happen unless the LTO object was built by old lto1 which
did not contain that logic yet. */
else
- remove_option (decoded_options, j, decoded_options_count);
+ decoded_options.ordered_remove (j);
}
else if (pie_option->opt_index == OPT_fpie
- && (*decoded_options)[j].opt_index == OPT_fPIE)
+ && decoded_options[j].opt_index == OPT_fPIE)
{
- (*decoded_options)[j] = *pie_option;
+ decoded_options[j] = *pie_option;
j++;
}
else
@@ -554,37 +538,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (!xassembler_options_error)
for (i = j = 0; ; i++, j++)
{
- for (; i < *decoded_options_count; i++)
- if ((*decoded_options)[i].opt_index == OPT_Xassembler)
- break;
-
- for (; j < fdecoded_options_count; j++)
- if (fdecoded_options[j].opt_index == OPT_Xassembler)
- break;
-
- if (i == *decoded_options_count && j == fdecoded_options_count)
+ int existing_opt_index
+ = find_option (decoded_options, OPT_Xassembler);
+ int existing_opt2_index
+ = find_option (fdecoded_options, OPT_Xassembler);
+
+ cl_decoded_option *existing_opt = NULL;
+ cl_decoded_option *existing_opt2 = NULL;
+ if (existing_opt_index != -1)
+ existing_opt = &decoded_options[existing_opt_index];
+ if (existing_opt2_index != -1)
+ existing_opt2 = &fdecoded_options[existing_opt2_index];
+
+ if (existing_opt == NULL && existing_opt2 == NULL)
break;
- else if (i < *decoded_options_count && j == fdecoded_options_count)
+ else if (existing_opt != NULL && existing_opt2 == NULL)
{
warning (0, "Extra option to %<-Xassembler%>: %s,"
" dropping all %<-Xassembler%> and %<-Wa%> options.",
- (*decoded_options)[i].arg);
+ existing_opt->arg);
xassembler_options_error = true;
break;
}
- else if (i == *decoded_options_count && j < fdecoded_options_count)
+ else if (existing_opt == NULL && existing_opt2 != NULL)
{
warning (0, "Extra option to %<-Xassembler%>: %s,"
" dropping all %<-Xassembler%> and %<-Wa%> options.",
- fdecoded_options[j].arg);
+ existing_opt2->arg);
xassembler_options_error = true;
break;
}
- else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg))
+ else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
{
warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
" dropping all %<-Xassembler%> and %<-Wa%> options.",
- (*decoded_options)[i].arg, fdecoded_options[j].arg);
+ existing_opt->arg, existing_opt2->arg);
xassembler_options_error = true;
break;
}
@@ -655,13 +643,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append)
/* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
static void
-append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
- unsigned int count)
+append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
{
/* Append compiler driver arguments as far as they were merged. */
- for (unsigned int j = 1; j < count; ++j)
+ for (unsigned int j = 1; j < opts.length (); ++j)
{
- struct cl_decoded_option *option = &opts[j];
+ cl_decoded_option *option = &opts[j];
/* File options have been properly filtered by lto-opts.c. */
switch (option->opt_index)
@@ -722,16 +709,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
}
}
-/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */
+/* Append diag options in OPTS to ARGV_OBSTACK. */
static void
-append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
- unsigned int count)
+append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
{
/* Append compiler driver arguments as far as they were merged. */
- for (unsigned int j = 1; j < count; ++j)
+ for (unsigned int j = 1; j < opts.length (); ++j)
{
- struct cl_decoded_option *option = &opts[j];
+ cl_decoded_option *option = &opts[j];
switch (option->opt_index)
{
@@ -758,14 +744,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
/* Append linker options OPTS to ARGV_OBSTACK. */
static void
-append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
- unsigned int count)
+append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
{
/* Append linker driver arguments. Compiler options from the linker
driver arguments will override / merge with those from the compiler. */
- for (unsigned int j = 1; j < count; ++j)
+ for (unsigned int j = 1; j < opts.length (); ++j)
{
- struct cl_decoded_option *option = &opts[j];
+ cl_decoded_option *option = &opts[j];
/* Do not pass on frontend specific flags not suitable for lto. */
if (!(cl_options[option->opt_index].flags
@@ -803,15 +788,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
static void
append_offload_options (obstack *argv_obstack, const char *target,
- struct cl_decoded_option *options,
- unsigned int options_count)
+ vec<cl_decoded_option> options)
{
- for (unsigned i = 0; i < options_count; i++)
+ for (unsigned i = 0; i < options.length (); i++)
{
const char *cur, *next, *opts;
char **argv;
unsigned argc;
- struct cl_decoded_option *option = &options[i];
+ cl_decoded_option *option = &options[i];
if (option->opt_index != OPT_foffload_)
continue;
@@ -883,10 +867,8 @@ access_check (const char *name, int mode)
static char *
compile_offload_image (const char *target, const char *compiler_path,
unsigned in_argc, char *in_argv[],
- struct cl_decoded_option *compiler_opts,
- unsigned int compiler_opt_count,
- struct cl_decoded_option *linker_opts,
- unsigned int linker_opt_count)
+ vec<cl_decoded_option> compiler_opts,
+ vec<cl_decoded_option> linker_opts)
{
char *filename = NULL;
char *dumpbase;
@@ -943,19 +925,16 @@ compile_offload_image (const char *target, const char *compiler_path,
obstack_ptr_grow (&argv_obstack, in_argv[i]);
/* Append options from offload_lto sections. */
- append_compiler_options (&argv_obstack, compiler_opts,
- compiler_opt_count);
- append_diag_options (&argv_obstack, linker_opts, linker_opt_count);
+ append_compiler_options (&argv_obstack, compiler_opts);
+ append_diag_options (&argv_obstack, linker_opts);
obstack_ptr_grow (&argv_obstack, "-dumpbase");
obstack_ptr_grow (&argv_obstack, dumpbase);
/* Append options specified by -foffload last. In case of conflicting
options we expect offload compiler to choose the latest. */
- append_offload_options (&argv_obstack, target, compiler_opts,
- compiler_opt_count);
- append_offload_options (&argv_obstack, target, linker_opts,
- linker_opt_count);
+ append_offload_options (&argv_obstack, target, compiler_opts);
+ append_offload_options (&argv_obstack, target, linker_opts);
obstack_ptr_grow (&argv_obstack, NULL);
argv = XOBFINISH (&argv_obstack, char **);
@@ -974,10 +953,8 @@ compile_offload_image (const char *target, const char *compiler_path,
static void
compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
- struct cl_decoded_option *compiler_opts,
- unsigned int compiler_opt_count,
- struct cl_decoded_option *linker_opts,
- unsigned int linker_opt_count)
+ vec<cl_decoded_option> compiler_opts,
+ vec<cl_decoded_option> linker_opts)
{
char **names = NULL;
const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
@@ -997,8 +974,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
{
offload_names[next_name_entry]
= compile_offload_image (names[i], compiler_path, in_argc, in_argv,
- compiler_opts, compiler_opt_count,
- linker_opts, linker_opt_count);
+ compiler_opts, linker_opts);
if (!offload_names[next_name_entry])
#if OFFLOAD_DEFAULTED
continue;
@@ -1080,25 +1056,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx)
}
/* A subroutine of run_gcc. Examine the open file FD for lto sections with
- name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
- and OPT_COUNT. Return true if we found a matching section, false
+ name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
+ Return true if we found a matching section, false
otherwise. COLLECT_GCC holds the value of the environment variable with
the same name. */
static bool
find_and_merge_options (int fd, off_t file_offset, const char *prefix,
- struct cl_decoded_option *decoded_cl_options,
- unsigned int decoded_cl_options_count,
- struct cl_decoded_option **opts,
- unsigned int *opt_count, const char *collect_gcc)
+ vec<cl_decoded_option> decoded_cl_options,
+ vec<cl_decoded_option> *opts, const char *collect_gcc)
{
off_t offset, length;
char *data;
char *fopts;
const char *errmsg;
int err;
- struct cl_decoded_option *fdecoded_options = *opts;
- unsigned int fdecoded_options_count = *opt_count;
+ vec<cl_decoded_option> fdecoded_options;
simple_object_read *sobj;
sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
@@ -1120,24 +1093,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
data = (char *)xmalloc (length);
read (fd, data, length);
fopts = data;
+ bool first = true;
do
{
- struct cl_decoded_option *f2decoded_options;
- unsigned int f2decoded_options_count;
- get_options_from_collect_gcc_options (collect_gcc, fopts,
- &f2decoded_options,
- &f2decoded_options_count);
- if (!fdecoded_options)
- {
- fdecoded_options = f2decoded_options;
- fdecoded_options_count = f2decoded_options_count;
- }
+ vec<cl_decoded_option> f2decoded_options
+ = get_options_from_collect_gcc_options (collect_gcc, fopts);
+ if (first)
+ {
+ fdecoded_options = f2decoded_options;
+ first = false;
+ }
else
- merge_and_complain (&fdecoded_options,
- &fdecoded_options_count,
- f2decoded_options, f2decoded_options_count,
- decoded_cl_options,
- decoded_cl_options_count);
+ merge_and_complain (fdecoded_options, f2decoded_options,
+ decoded_cl_options);
fopts += strlen (fopts) + 1;
}
@@ -1146,7 +1114,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
free (data);
simple_object_release_read (sobj);
*opts = fdecoded_options;
- *opt_count = fdecoded_options_count;
return true;
}
@@ -1391,12 +1358,9 @@ run_gcc (unsigned argc, char *argv[])
int jobserver = 0;
int auto_parallel = 0;
bool no_partition = false;
- struct cl_decoded_option *fdecoded_options = NULL;
- struct cl_decoded_option *offload_fdecoded_options = NULL;
- unsigned int fdecoded_options_count = 0;
- unsigned int offload_fdecoded_options_count = 0;
- struct cl_decoded_option *decoded_options;
- unsigned int decoded_options_count;
+ vec<cl_decoded_option> fdecoded_options;
+ fdecoded_options.create (16);
+ vec<cl_decoded_option> offload_fdecoded_options = vNULL;
struct obstack argv_obstack;
int new_head_argc;
bool have_lto = false;
@@ -1438,9 +1402,8 @@ run_gcc (unsigned argc, char *argv[])
NULL);
}
- get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
- &decoded_options,
- &decoded_options_count);
+ vec<cl_decoded_option> decoded_options
+ = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
/* Allocate array for input object files with LTO IL,
and for possible preceding arguments. */
@@ -1489,8 +1452,7 @@ run_gcc (unsigned argc, char *argv[])
}
if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
- decoded_options, decoded_options_count,
- &fdecoded_options, &fdecoded_options_count,
+ decoded_options, &fdecoded_options,
collect_gcc))
{
have_lto = true;
@@ -1505,14 +1467,13 @@ run_gcc (unsigned argc, char *argv[])
obstack_ptr_grow (&argv_obstack, "-xlto");
obstack_ptr_grow (&argv_obstack, "-c");
- append_compiler_options (&argv_obstack, fdecoded_options,
- fdecoded_options_count);
- append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
+ append_compiler_options (&argv_obstack, fdecoded_options);
+ append_linker_options (&argv_obstack, decoded_options);
/* Scan linker driver arguments for things that are of relevance to us. */
- for (j = 1; j < decoded_options_count; ++j)
+ for (j = 1; j < decoded_options.length (); ++j)
{
- struct cl_decoded_option *option = &decoded_options[j];
+ cl_decoded_option *option = &decoded_options[j];
switch (option->opt_index)
{
case OPT_o:
@@ -1731,9 +1692,7 @@ cont1:
fatal_error (input_location, "cannot open %s: %m", filename);
if (!find_and_merge_options (fd, file_offset,
OFFLOAD_SECTION_NAME_PREFIX,
- decoded_options, decoded_options_count,
- &offload_fdecoded_options,
- &offload_fdecoded_options_count,
+ decoded_options, &offload_fdecoded_options,
collect_gcc))
fatal_error (input_location, "cannot read %s: %m", filename);
close (fd);
@@ -1742,10 +1701,7 @@ cont1:
}
compile_images_for_offload_targets (num_offload_files, offload_argv,
- offload_fdecoded_options,
- offload_fdecoded_options_count,
- decoded_options,
- decoded_options_count);
+ offload_fdecoded_options, decoded_options);
free_array_of_ptrs ((void **) offload_argv, num_offload_files);
--
2.31.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type.
2021-05-12 9:08 ` Martin Liška
@ 2021-05-12 9:15 ` Richard Biener
0 siblings, 0 replies; 5+ messages in thread
From: Richard Biener @ 2021-05-12 9:15 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
On Wed, May 12, 2021 at 11:08 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 4/29/21 2:22 PM, Richard Biener wrote:
> > On Wed, Apr 21, 2021 at 11:12 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> Now living in the 21st century, we don't longer need using the following tuple:
> >> cl_decoded_option **decoded_options,
> >> unsigned int *decoded_options_count)
> >> but we can rather use a standard (our) vector.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> >> Thanks,
> >> Martin
> >>
> >> gcc/ChangeLog:
> >>
> >> * lto-wrapper.c (get_options_from_collect_gcc_options): Change
> >> return type.
> >> (append_option): Remove.
> >> (find_option): Rework to use the vector type.
> >> (remove_option): Remove.
> >> (merge_and_complain): Use vectors for cl_decoded_option data
> >> type arguments.
> >> (append_compiler_options): Likewise.
> >> (append_diag_options): Likewise.
> >> (append_linker_options): Likewise.
> >> (append_offload_options): Likewise.
> >> (compile_offload_image): Likewise.
> >> (compile_images_for_offload_targets): Likewise.
> >> (find_and_merge_options): Likewise.
> >> (run_gcc): Likewise.
> >> ---
> >> gcc/lto-wrapper.c | 384 ++++++++++++++++++++--------------------------
> >> 1 file changed, 165 insertions(+), 219 deletions(-)
> >>
> >> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
> >> index 03a5922f8ea..5ccf729b249 100644
> >> --- a/gcc/lto-wrapper.c
> >> +++ b/gcc/lto-wrapper.c
> >> @@ -138,12 +138,12 @@ maybe_unlink (const char *file)
> >> /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
> >> environment. */
> >>
> >> -static void
> >> +static vec<cl_decoded_option>
> >
> > bonus points for handling ownership transfer via returning an
> > auto_vec<> (not sure if possible, but maybe it is).
>
> Heh, about the bonus points: changing return type of get_options_from_collect_gcc_options to auto_vec<...>
> leads to:
>
> ==26737== Invalid read of size 4
>
> ==26737== at 0x406969: length (vec.h:589)
>
> ==26737== by 0x406969: length (vec.h:1439)
>
> ==26737== by 0x406969: append_compiler_options(obstack*, vec<cl_decoded_option, va_heap, vl_ptr>) (lto-wrapper.c:649)
>
> ==26737== by 0x408E35: run_gcc(unsigned int, char**) (lto-wrapper.c:1470)
>
> ==26737== by 0x406565: main (lto-wrapper.c:2070)
>
> ==26737== Address 0x57838a4 is 4 bytes inside a block of size 1,152 free'd
>
> ==26737== at 0x483FEC0: free (vg_replace_malloc.c:755)
>
> ==26737== by 0x4078B5: release<cl_decoded_option> (vec.h:316)
>
> ==26737== by 0x4078B5: release (vec.h:1832)
>
> ==26737== by 0x4078B5: ~auto_vec (vec.h:1552)
>
> ==26737== by 0x4078B5: find_and_merge_options(int, long, char const*, vec<cl_decoded_option, va_heap, vl_ptr>, vec<cl_decoded_option, va_heap, vl_ptr>*, char const*) (lto-wrapper.c:1100)
>
> ==26737== by 0x408D0E: run_gcc(unsigned int, char**) (lto-wrapper.c:1454)
>
> ==26737== by 0x406565: main (lto-wrapper.c:2070)
>
> ==26737== Block was alloc'd at
>
> ==26737== at 0x483D70F: malloc (vg_replace_malloc.c:380)
>
> ==26737== by 0x49554F: xrealloc (xmalloc.c:177)
>
> ==26737== by 0x4076CC: reserve<cl_decoded_option> (vec.h:290)
>
> ==26737== by 0x4076CC: reserve (vec.h:1778)
>
> ==26737== by 0x4076CC: reserve_exact (vec.h:1798)
>
> ==26737== by 0x4076CC: create (vec.h:1813)
>
> ==26737== by 0x4076CC: get_options_from_collect_gcc_options(char const*, char const*) (lto-wrapper.c:162)
>
> ==26737== by 0x4078FC: find_and_merge_options(int, long, char const*, vec<cl_decoded_option, va_heap, vl_ptr>, vec<cl_decoded_option, va_heap, vl_ptr>*, char const*) (lto-wrapper.c:1100)
>
> ==26737== by 0x408D0E: run_gcc(unsigned int, char**) (lto-wrapper.c:1454)
>
> ==26737== by 0x406565: main (lto-wrapper.c:2070)
Well, you of course have to be more "careful" then where to
free/forward it. The auto_vec
serves as a smart pointer then.
OK.
Thanks
Richard.
>
> >
> >> get_options_from_collect_gcc_options (const char *collect_gcc,
> >> - const char *collect_gcc_options,
> >> - struct cl_decoded_option **decoded_options,
> >> - unsigned int *decoded_options_count)
> >> + const char *collect_gcc_options)
> >> {
> >> + cl_decoded_option *decoded_options;
> >> + unsigned int decoded_options_count;
> >> struct obstack argv_obstack;
> >> const char **argv;
> >> int argc;
> >> @@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
> >> argv = XOBFINISH (&argv_obstack, const char **);
> >>
> >> decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
> >> - decoded_options, decoded_options_count);
> >> + &decoded_options, &decoded_options_count);
> >> + vec<cl_decoded_option> decoded;
> >> + decoded.create (decoded_options_count);
> >> + for (unsigned i = 0; i < decoded_options_count; ++i)
> >> + decoded.quick_push (decoded_options[i]);
> >> + free (decoded_options);
> >> +
> >> obstack_free (&argv_obstack, NULL);
> >> +
> >> + return decoded;
> >> }
> >>
> >> -/* Append OPTION to the options array DECODED_OPTIONS with size
> >> - DECODED_OPTIONS_COUNT. */
> >> +/* Find option in OPTIONS based on OPT_INDEX. NULL value is returned
> >> + if the option is not present. */
> >>
> >> -static void
> >> -append_option (struct cl_decoded_option **decoded_options,
> >> - unsigned int *decoded_options_count,
> >> - struct cl_decoded_option *option)
> >> +static cl_decoded_option *
> >> +find_option (vec<cl_decoded_option> &options, size_t opt_index)
> >> {
> >> - ++*decoded_options_count;
> >> - *decoded_options
> >> - = (struct cl_decoded_option *)
> >> - xrealloc (*decoded_options,
> >> - (*decoded_options_count
> >> - * sizeof (struct cl_decoded_option)));
> >> - memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
> >> - sizeof (struct cl_decoded_option));
> >> -}
> >> + for (unsigned i = 0; i < options.length (); ++i)
> >> + if (options[i].opt_index == opt_index)
> >> + return &options[i];
> >
> > You're returning a pointer into the vector here...
> >
> >> -/* Remove option number INDEX from DECODED_OPTIONS, update
> >> - DECODED_OPTIONS_COUNT. */
> >> + return NULL;
> >> +}
> >>
> >> -static void
> >> -remove_option (struct cl_decoded_option **decoded_options,
> >> - int index, unsigned int *decoded_options_count)
> >> +static cl_decoded_option *
> >> +find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
> >> {
> >> - --*decoded_options_count;
> >> - memmove (&(*decoded_options)[index + 1],
> >> - &(*decoded_options)[index],
> >> - sizeof (struct cl_decoded_option)
> >> - * (*decoded_options_count - index));
> >> + return find_option (options, option->opt_index);
> >> }
> >>
> >> /* Try to merge and complain about options FDECODED_OPTIONS when applied
> >> ontop of DECODED_OPTIONS. */
> >>
> >> static void
> >> -merge_and_complain (struct cl_decoded_option **decoded_options,
> >> - unsigned int *decoded_options_count,
> >> - struct cl_decoded_option *fdecoded_options,
> >> - unsigned int fdecoded_options_count,
> >> - struct cl_decoded_option *decoded_cl_options,
> >> - unsigned int decoded_cl_options_count)
> >> +merge_and_complain (vec<cl_decoded_option> decoded_options,
> >> + vec<cl_decoded_option> fdecoded_options,
> >> + vec<cl_decoded_option> decoded_cl_options)
> >> {
> >> unsigned int i, j;
> >> - struct cl_decoded_option *pic_option = NULL;
> >> - struct cl_decoded_option *pie_option = NULL;
> >> - struct cl_decoded_option *cf_protection_option = NULL;
> >> + cl_decoded_option *pic_option = NULL;
> >> + cl_decoded_option *pie_option = NULL;
> >> + cl_decoded_option *cf_protection_option = NULL;
> >>
> >> /* ??? Merge options from files. Most cases can be
> >> handled by either unioning or intersecting
> >> @@ -223,9 +215,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >>
> >> /* Look for a -fcf-protection option in the link-time options
> >> which overrides any -fcf-protection from the lto sections. */
> >> - for (i = 0; i < decoded_cl_options_count; ++i)
> >> + for (i = 0; i < decoded_cl_options.length (); ++i)
> >> {
> >> - struct cl_decoded_option *foption = &decoded_cl_options[i];
> >> + cl_decoded_option *foption = &decoded_cl_options[i];
> >> if (foption->opt_index == OPT_fcf_protection_)
> >> {
> >> cf_protection_option = foption;
> >> @@ -234,9 +226,10 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >>
> >> /* The following does what the old LTO option code did,
> >> union all target and a selected set of common options. */
> >> - for (i = 0; i < fdecoded_options_count; ++i)
> >> + for (i = 0; i < fdecoded_options.length (); ++i)
> >> {
> >> - struct cl_decoded_option *foption = &fdecoded_options[i];
> >> + cl_decoded_option *foption = &fdecoded_options[i];
> >> + cl_decoded_option *existing_opt = find_option (decoded_options, foption);
> >> switch (foption->opt_index)
> >> {
> >> case OPT_SPECIAL_unknown:
> >> @@ -264,11 +257,8 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> setting per OPT code, we pick the first we encounter.
> >> ??? This doesn't make too much sense, but when it doesn't
> >> then we should complain. */
> >> - for (j = 0; j < *decoded_options_count; ++j)
> >> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> >> - break;
> >> - if (j == *decoded_options_count)
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> + if (existing_opt == NULL)
> >> + decoded_options.safe_push (*foption);
> >
> > and you end up re-allocating that here. That's an eventually dangerous
> > pattern ... please consider to instead returning an index from find()
> > (and -1 for not found or so).
>
> You are right. I've done that in the patch and it survives regression tests.
> May I install it? The auto_vec can be done incrementally I guess.
>
> Martin
>
> >
> >> break;
> >>
> >> /* Figure out what PIC/PIE level wins and merge the results. */
> >> @@ -284,25 +274,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> case OPT_fopenmp:
> >> case OPT_fopenacc:
> >> /* For selected options we can merge conservatively. */
> >> - for (j = 0; j < *decoded_options_count; ++j)
> >> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> >> - break;
> >> - if (j == *decoded_options_count)
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> + if (existing_opt == NULL)
> >> + decoded_options.safe_push (*foption);
> >> /* -fopenmp > -fno-openmp,
> >> -fopenacc > -fno-openacc */
> >> - else if (foption->value > (*decoded_options)[j].value)
> >> - (*decoded_options)[j] = *foption;
> >> + else if (foption->value > existing_opt->value)
> >> + *existing_opt = *foption;
> >> break;
> >>
> >> case OPT_fopenacc_dim_:
> >> /* Append or check identical. */
> >> - for (j = 0; j < *decoded_options_count; ++j)
> >> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> >> - break;
> >> - if (j == *decoded_options_count)
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> - else if (strcmp ((*decoded_options)[j].arg, foption->arg))
> >> + if (existing_opt == NULL)
> >> + decoded_options.safe_push (*foption);
> >> + else if (strcmp (existing_opt->arg, foption->arg))
> >> fatal_error (input_location,
> >> "option %s with different values",
> >> foption->orig_option_with_args_text);
> >> @@ -313,12 +297,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> if (!cf_protection_option
> >> || cf_protection_option->value == CF_CHECK)
> >> {
> >> - for (j = 0; j < *decoded_options_count; ++j)
> >> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> >> - break;
> >> - if (j == *decoded_options_count)
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> - else if ((*decoded_options)[j].value != foption->value)
> >> + if (existing_opt == NULL)
> >> + decoded_options.safe_push (*foption);
> >> + else if (existing_opt->value != foption->value)
> >> {
> >> if (cf_protection_option
> >> && cf_protection_option->value == CF_CHECK)
> >> @@ -326,22 +307,21 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> "option %qs with mismatching values"
> >> " (%s, %s)",
> >> "-fcf-protection",
> >> - (*decoded_options)[j].arg, foption->arg);
> >> + existing_opt->arg, foption->arg);
> >> else
> >> {
> >> /* Merge and update the -fcf-protection option. */
> >> - (*decoded_options)[j].value &= (foption->value
> >> - & CF_FULL);
> >> - switch ((*decoded_options)[j].value)
> >> + existing_opt->value &= (foption->value & CF_FULL);
> >> + switch (existing_opt->value)
> >> {
> >> case CF_NONE:
> >> - (*decoded_options)[j].arg = "none";
> >> + existing_opt->arg = "none";
> >> break;
> >> case CF_BRANCH:
> >> - (*decoded_options)[j].arg = "branch";
> >> + existing_opt->arg = "branch";
> >> break;
> >> case CF_RETURN:
> >> - (*decoded_options)[j].arg = "return";
> >> + existing_opt->arg = "return";
> >> break;
> >> default:
> >> gcc_unreachable ();
> >> @@ -355,15 +335,19 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> case OPT_Ofast:
> >> case OPT_Og:
> >> case OPT_Os:
> >> - for (j = 0; j < *decoded_options_count; ++j)
> >> - if ((*decoded_options)[j].opt_index == OPT_O
> >> - || (*decoded_options)[j].opt_index == OPT_Ofast
> >> - || (*decoded_options)[j].opt_index == OPT_Og
> >> - || (*decoded_options)[j].opt_index == OPT_Os)
> >> - break;
> >> - if (j == *decoded_options_count)
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> - else if ((*decoded_options)[j].opt_index == foption->opt_index
> >> + existing_opt = NULL;
> >> + for (j = 0; j < decoded_options.length (); ++j)
> >> + if (decoded_options[j].opt_index == OPT_O
> >> + || decoded_options[j].opt_index == OPT_Ofast
> >> + || decoded_options[j].opt_index == OPT_Og
> >> + || decoded_options[j].opt_index == OPT_Os)
> >> + {
> >> + existing_opt = &decoded_options[j];
> >> + break;
> >> + }
> >> + if (existing_opt == NULL)
> >> + decoded_options.safe_push (*foption);
> >> + else if (existing_opt->opt_index == foption->opt_index
> >> && foption->opt_index != OPT_O)
> >> /* Exact same options get merged. */
> >> ;
> >> @@ -393,13 +377,13 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> default:
> >> gcc_unreachable ();
> >> }
> >> - switch ((*decoded_options)[j].opt_index)
> >> + switch (existing_opt->opt_index)
> >> {
> >> case OPT_O:
> >> - if ((*decoded_options)[j].arg[0] == '\0')
> >> + if (existing_opt->arg[0] == '\0')
> >> level = MAX (level, 1);
> >> else
> >> - level = MAX (level, atoi ((*decoded_options)[j].arg));
> >> + level = MAX (level, atoi (existing_opt->arg));
> >> break;
> >> case OPT_Ofast:
> >> level = MAX (level, 3);
> >> @@ -413,23 +397,20 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> default:
> >> gcc_unreachable ();
> >> }
> >> - (*decoded_options)[j].opt_index = OPT_O;
> >> + existing_opt->opt_index = OPT_O;
> >> char *tem;
> >> tem = xasprintf ("-O%d", level);
> >> - (*decoded_options)[j].arg = &tem[2];
> >> - (*decoded_options)[j].canonical_option[0] = tem;
> >> - (*decoded_options)[j].value = 1;
> >> + existing_opt->arg = &tem[2];
> >> + existing_opt->canonical_option[0] = tem;
> >> + existing_opt->value = 1;
> >> }
> >> break;
> >>
> >>
> >> case OPT_foffload_abi_:
> >> - for (j = 0; j < *decoded_options_count; ++j)
> >> - if ((*decoded_options)[j].opt_index == foption->opt_index)
> >> - break;
> >> - if (j == *decoded_options_count)
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> - else if (foption->value != (*decoded_options)[j].value)
> >> + if (existing_opt == NULL)
> >> + decoded_options.safe_push (*foption);
> >> + else if (foption->value != existing_opt->value)
> >> fatal_error (input_location,
> >> "option %s not used consistently in all LTO input"
> >> " files", foption->orig_option_with_args_text);
> >> @@ -437,7 +418,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >>
> >>
> >> case OPT_foffload_:
> >> - append_option (decoded_options, decoded_options_count, foption);
> >> + decoded_options.safe_push (*foption);
> >> break;
> >> }
> >> }
> >> @@ -457,12 +438,12 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> It would be good to warn on mismatches, but it is bit hard to do as
> >> we do not know what nothing translates to. */
> >>
> >> - for (unsigned int j = 0; j < *decoded_options_count;)
> >> - if ((*decoded_options)[j].opt_index == OPT_fPIC
> >> - || (*decoded_options)[j].opt_index == OPT_fpic)
> >> + for (unsigned int j = 0; j < decoded_options.length ();)
> >> + if (decoded_options[j].opt_index == OPT_fPIC
> >> + || decoded_options[j].opt_index == OPT_fpic)
> >> {
> >> /* -fno-pic in one unit implies -fno-pic everywhere. */
> >> - if ((*decoded_options)[j].value == 0)
> >> + if (decoded_options[j].value == 0)
> >> j++;
> >> /* If we have no pic option or merge in -fno-pic, we still may turn
> >> existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
> >> @@ -471,41 +452,41 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> {
> >> if (pie_option)
> >> {
> >> - bool big = (*decoded_options)[j].opt_index == OPT_fPIC
> >> + bool big = decoded_options[j].opt_index == OPT_fPIC
> >> && pie_option->opt_index == OPT_fPIE;
> >> - (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
> >> + decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
> >> if (pie_option->value)
> >> - (*decoded_options)[j].canonical_option[0]
> >> + decoded_options[j].canonical_option[0]
> >> = big ? "-fPIE" : "-fpie";
> >> else
> >> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
> >> - (*decoded_options)[j].value = pie_option->value;
> >> - j++;
> >> + decoded_options[j].canonical_option[0] = "-fno-pie";
> >> + decoded_options[j].value = pie_option->value;
> >> + j++;
> >> }
> >> else if (pic_option)
> >> {
> >> - (*decoded_options)[j] = *pic_option;
> >> - j++;
> >> + decoded_options[j] = *pic_option;
> >> + j++;
> >> }
> >> /* We do not know if target defaults to pic or not, so just remove
> >> option if it is missing in one unit but enabled in other. */
> >> else
> >> - remove_option (decoded_options, j, decoded_options_count);
> >> + decoded_options.ordered_remove (j);
> >> }
> >> else if (pic_option->opt_index == OPT_fpic
> >> - && (*decoded_options)[j].opt_index == OPT_fPIC)
> >> + && decoded_options[j].opt_index == OPT_fPIC)
> >> {
> >> - (*decoded_options)[j] = *pic_option;
> >> + decoded_options[j] = *pic_option;
> >> j++;
> >> }
> >> else
> >> j++;
> >> }
> >> - else if ((*decoded_options)[j].opt_index == OPT_fPIE
> >> - || (*decoded_options)[j].opt_index == OPT_fpie)
> >> + else if (decoded_options[j].opt_index == OPT_fPIE
> >> + || decoded_options[j].opt_index == OPT_fpie)
> >> {
> >> /* -fno-pie in one unit implies -fno-pie everywhere. */
> >> - if ((*decoded_options)[j].value == 0)
> >> + if (decoded_options[j].value == 0)
> >> j++;
> >> /* If we have no pie option or merge in -fno-pie, we still preserve
> >> PIE/pie if pic/PIC is present. */
> >> @@ -516,32 +497,32 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> if (pic_option)
> >> {
> >> if (pic_option->opt_index == OPT_fpic
> >> - && (*decoded_options)[j].opt_index == OPT_fPIE)
> >> + && decoded_options[j].opt_index == OPT_fPIE)
> >> {
> >> - (*decoded_options)[j].opt_index = OPT_fpie;
> >> - (*decoded_options)[j].canonical_option[0]
> >> + decoded_options[j].opt_index = OPT_fpie;
> >> + decoded_options[j].canonical_option[0]
> >> = pic_option->value ? "-fpie" : "-fno-pie";
> >> }
> >> else if (!pic_option->value)
> >> - (*decoded_options)[j].canonical_option[0] = "-fno-pie";
> >> - (*decoded_options)[j].value = pic_option->value;
> >> + decoded_options[j].canonical_option[0] = "-fno-pie";
> >> + decoded_options[j].value = pic_option->value;
> >> j++;
> >> }
> >> else if (pie_option)
> >> {
> >> - (*decoded_options)[j] = *pie_option;
> >> + decoded_options[j] = *pie_option;
> >> j++;
> >> }
> >> /* Because we always append pic/PIE options this code path should
> >> not happen unless the LTO object was built by old lto1 which
> >> did not contain that logic yet. */
> >> else
> >> - remove_option (decoded_options, j, decoded_options_count);
> >> + decoded_options.ordered_remove (j);
> >> }
> >> else if (pie_option->opt_index == OPT_fpie
> >> - && (*decoded_options)[j].opt_index == OPT_fPIE)
> >> + && decoded_options[j].opt_index == OPT_fPIE)
> >> {
> >> - (*decoded_options)[j] = *pie_option;
> >> + decoded_options[j] = *pie_option;
> >> j++;
> >> }
> >> else
> >> @@ -553,37 +534,34 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
> >> if (!xassembler_options_error)
> >> for (i = j = 0; ; i++, j++)
> >> {
> >> - for (; i < *decoded_options_count; i++)
> >> - if ((*decoded_options)[i].opt_index == OPT_Xassembler)
> >> - break;
> >> -
> >> - for (; j < fdecoded_options_count; j++)
> >> - if (fdecoded_options[j].opt_index == OPT_Xassembler)
> >> - break;
> >> + cl_decoded_option *existing_opt
> >> + = find_option (decoded_options, OPT_Xassembler);
> >> + cl_decoded_option *existing_opt2
> >> + = find_option (fdecoded_options, OPT_Xassembler);
> >>
> >> - if (i == *decoded_options_count && j == fdecoded_options_count)
> >> + if (existing_opt == NULL && existing_opt2 == NULL)
> >> break;
> >> - else if (i < *decoded_options_count && j == fdecoded_options_count)
> >> + else if (existing_opt != NULL && existing_opt2 == NULL)
> >> {
> >> warning (0, "Extra option to %<-Xassembler%>: %s,"
> >> " dropping all %<-Xassembler%> and %<-Wa%> options.",
> >> - (*decoded_options)[i].arg);
> >> + existing_opt->arg);
> >> xassembler_options_error = true;
> >> break;
> >> }
> >> - else if (i == *decoded_options_count && j < fdecoded_options_count)
> >> + else if (existing_opt == NULL && existing_opt2 != NULL)
> >> {
> >> warning (0, "Extra option to %<-Xassembler%>: %s,"
> >> " dropping all %<-Xassembler%> and %<-Wa%> options.",
> >> - fdecoded_options[j].arg);
> >> + existing_opt2->arg);
> >> xassembler_options_error = true;
> >> break;
> >> }
> >> - else if (strcmp ((*decoded_options)[i].arg, fdecoded_options[j].arg))
> >> + else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
> >> {
> >> warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
> >> " dropping all %<-Xassembler%> and %<-Wa%> options.",
> >> - (*decoded_options)[i].arg, fdecoded_options[j].arg);
> >> + existing_opt->arg, existing_opt2->arg);
> >> xassembler_options_error = true;
> >> break;
> >> }
> >> @@ -654,13 +632,12 @@ parse_env_var (const char *str, char ***pvalues, const char *append)
> >> /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
> >>
> >> static void
> >> -append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> >> - unsigned int count)
> >> +append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
> >> {
> >> /* Append compiler driver arguments as far as they were merged. */
> >> - for (unsigned int j = 1; j < count; ++j)
> >> + for (unsigned int j = 1; j < opts.length (); ++j)
> >> {
> >> - struct cl_decoded_option *option = &opts[j];
> >> + cl_decoded_option *option = &opts[j];
> >>
> >> /* File options have been properly filtered by lto-opts.c. */
> >> switch (option->opt_index)
> >> @@ -721,16 +698,15 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> >> }
> >> }
> >>
> >> -/* Append diag options in OPTS with length COUNT to ARGV_OBSTACK. */
> >> +/* Append diag options in OPTS to ARGV_OBSTACK. */
> >>
> >> static void
> >> -append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> >> - unsigned int count)
> >> +append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
> >> {
> >> /* Append compiler driver arguments as far as they were merged. */
> >> - for (unsigned int j = 1; j < count; ++j)
> >> + for (unsigned int j = 1; j < opts.length (); ++j)
> >> {
> >> - struct cl_decoded_option *option = &opts[j];
> >> + cl_decoded_option *option = &opts[j];
> >>
> >> switch (option->opt_index)
> >> {
> >> @@ -757,14 +733,13 @@ append_diag_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> >> /* Append linker options OPTS to ARGV_OBSTACK. */
> >>
> >> static void
> >> -append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> >> - unsigned int count)
> >> +append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
> >> {
> >> /* Append linker driver arguments. Compiler options from the linker
> >> driver arguments will override / merge with those from the compiler. */
> >> - for (unsigned int j = 1; j < count; ++j)
> >> + for (unsigned int j = 1; j < opts.length (); ++j)
> >> {
> >> - struct cl_decoded_option *option = &opts[j];
> >> + cl_decoded_option *option = &opts[j];
> >>
> >> /* Do not pass on frontend specific flags not suitable for lto. */
> >> if (!(cl_options[option->opt_index].flags
> >> @@ -802,15 +777,14 @@ append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
> >>
> >> static void
> >> append_offload_options (obstack *argv_obstack, const char *target,
> >> - struct cl_decoded_option *options,
> >> - unsigned int options_count)
> >> + vec<cl_decoded_option> options)
> >> {
> >> - for (unsigned i = 0; i < options_count; i++)
> >> + for (unsigned i = 0; i < options.length (); i++)
> >> {
> >> const char *cur, *next, *opts;
> >> char **argv;
> >> unsigned argc;
> >> - struct cl_decoded_option *option = &options[i];
> >> + cl_decoded_option *option = &options[i];
> >>
> >> if (option->opt_index != OPT_foffload_)
> >> continue;
> >> @@ -882,10 +856,8 @@ access_check (const char *name, int mode)
> >> static char *
> >> compile_offload_image (const char *target, const char *compiler_path,
> >> unsigned in_argc, char *in_argv[],
> >> - struct cl_decoded_option *compiler_opts,
> >> - unsigned int compiler_opt_count,
> >> - struct cl_decoded_option *linker_opts,
> >> - unsigned int linker_opt_count)
> >> + vec<cl_decoded_option> compiler_opts,
> >> + vec<cl_decoded_option> linker_opts)
> >> {
> >> char *filename = NULL;
> >> char *dumpbase;
> >> @@ -935,19 +907,16 @@ compile_offload_image (const char *target, const char *compiler_path,
> >> obstack_ptr_grow (&argv_obstack, in_argv[i]);
> >>
> >> /* Append options from offload_lto sections. */
> >> - append_compiler_options (&argv_obstack, compiler_opts,
> >> - compiler_opt_count);
> >> - append_diag_options (&argv_obstack, linker_opts, linker_opt_count);
> >> + append_compiler_options (&argv_obstack, compiler_opts);
> >> + append_diag_options (&argv_obstack, linker_opts);
> >>
> >> obstack_ptr_grow (&argv_obstack, "-dumpbase");
> >> obstack_ptr_grow (&argv_obstack, dumpbase);
> >>
> >> /* Append options specified by -foffload last. In case of conflicting
> >> options we expect offload compiler to choose the latest. */
> >> - append_offload_options (&argv_obstack, target, compiler_opts,
> >> - compiler_opt_count);
> >> - append_offload_options (&argv_obstack, target, linker_opts,
> >> - linker_opt_count);
> >> + append_offload_options (&argv_obstack, target, compiler_opts);
> >> + append_offload_options (&argv_obstack, target, linker_opts);
> >>
> >> obstack_ptr_grow (&argv_obstack, NULL);
> >> argv = XOBFINISH (&argv_obstack, char **);
> >> @@ -966,10 +935,8 @@ compile_offload_image (const char *target, const char *compiler_path,
> >>
> >> static void
> >> compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
> >> - struct cl_decoded_option *compiler_opts,
> >> - unsigned int compiler_opt_count,
> >> - struct cl_decoded_option *linker_opts,
> >> - unsigned int linker_opt_count)
> >> + vec<cl_decoded_option> compiler_opts,
> >> + vec<cl_decoded_option> linker_opts)
> >> {
> >> char **names = NULL;
> >> const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
> >> @@ -988,8 +955,7 @@ compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
> >> {
> >> offload_names[i]
> >> = compile_offload_image (names[i], compiler_path, in_argc, in_argv,
> >> - compiler_opts, compiler_opt_count,
> >> - linker_opts, linker_opt_count);
> >> + compiler_opts, linker_opts);
> >> if (!offload_names[i])
> >> fatal_error (input_location,
> >> "problem with building target image for %s", names[i]);
> >> @@ -1058,25 +1024,22 @@ find_crtoffloadtable (int save_temps, const char *dumppfx)
> >> }
> >>
> >> /* A subroutine of run_gcc. Examine the open file FD for lto sections with
> >> - name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
> >> - and OPT_COUNT. Return true if we found a matching section, false
> >> + name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
> >> + Return true if we found a matching section, false
> >> otherwise. COLLECT_GCC holds the value of the environment variable with
> >> the same name. */
> >>
> >> static bool
> >> find_and_merge_options (int fd, off_t file_offset, const char *prefix,
> >> - struct cl_decoded_option *decoded_cl_options,
> >> - unsigned int decoded_cl_options_count,
> >> - struct cl_decoded_option **opts,
> >> - unsigned int *opt_count, const char *collect_gcc)
> >> + vec<cl_decoded_option> decoded_cl_options,
> >> + vec<cl_decoded_option> *opts, const char *collect_gcc)
> >> {
> >> off_t offset, length;
> >> char *data;
> >> char *fopts;
> >> const char *errmsg;
> >> int err;
> >> - struct cl_decoded_option *fdecoded_options = *opts;
> >> - unsigned int fdecoded_options_count = *opt_count;
> >> + vec<cl_decoded_option> fdecoded_options;
> >>
> >> simple_object_read *sobj;
> >> sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
> >> @@ -1098,24 +1061,19 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
> >> data = (char *)xmalloc (length);
> >> read (fd, data, length);
> >> fopts = data;
> >> + bool first = true;
> >> do
> >> {
> >> - struct cl_decoded_option *f2decoded_options;
> >> - unsigned int f2decoded_options_count;
> >> - get_options_from_collect_gcc_options (collect_gcc, fopts,
> >> - &f2decoded_options,
> >> - &f2decoded_options_count);
> >> - if (!fdecoded_options)
> >> - {
> >> - fdecoded_options = f2decoded_options;
> >> - fdecoded_options_count = f2decoded_options_count;
> >> - }
> >> + vec<cl_decoded_option> f2decoded_options
> >> + = get_options_from_collect_gcc_options (collect_gcc, fopts);
> >> + if (first)
> >> + {
> >> + fdecoded_options = f2decoded_options;
> >> + first = false;
> >> + }
> >> else
> >> - merge_and_complain (&fdecoded_options,
> >> - &fdecoded_options_count,
> >> - f2decoded_options, f2decoded_options_count,
> >> - decoded_cl_options,
> >> - decoded_cl_options_count);
> >> + merge_and_complain (fdecoded_options, f2decoded_options,
> >> + decoded_cl_options);
> >>
> >> fopts += strlen (fopts) + 1;
> >> }
> >> @@ -1124,7 +1082,6 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
> >> free (data);
> >> simple_object_release_read (sobj);
> >> *opts = fdecoded_options;
> >> - *opt_count = fdecoded_options_count;
> >> return true;
> >> }
> >>
> >> @@ -1371,12 +1328,9 @@ run_gcc (unsigned argc, char *argv[])
> >> int jobserver = 0;
> >> int auto_parallel = 0;
> >> bool no_partition = false;
> >> - struct cl_decoded_option *fdecoded_options = NULL;
> >> - struct cl_decoded_option *offload_fdecoded_options = NULL;
> >> - unsigned int fdecoded_options_count = 0;
> >> - unsigned int offload_fdecoded_options_count = 0;
> >> - struct cl_decoded_option *decoded_options;
> >> - unsigned int decoded_options_count;
> >> + vec<cl_decoded_option> fdecoded_options;
> >> + fdecoded_options.create (16);
> >> + vec<cl_decoded_option> offload_fdecoded_options = vNULL;
> >> struct obstack argv_obstack;
> >> int new_head_argc;
> >> bool have_lto = false;
> >> @@ -1418,9 +1372,8 @@ run_gcc (unsigned argc, char *argv[])
> >> NULL);
> >> }
> >>
> >> - get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
> >> - &decoded_options,
> >> - &decoded_options_count);
> >> + vec<cl_decoded_option> decoded_options
> >> + = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
> >>
> >> /* Allocate array for input object files with LTO IL,
> >> and for possible preceding arguments. */
> >> @@ -1470,8 +1423,7 @@ run_gcc (unsigned argc, char *argv[])
> >> }
> >>
> >> if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
> >> - decoded_options, decoded_options_count,
> >> - &fdecoded_options, &fdecoded_options_count,
> >> + decoded_options, &fdecoded_options,
> >> collect_gcc))
> >> {
> >> have_lto = true;
> >> @@ -1486,14 +1438,13 @@ run_gcc (unsigned argc, char *argv[])
> >> obstack_ptr_grow (&argv_obstack, "-xlto");
> >> obstack_ptr_grow (&argv_obstack, "-c");
> >>
> >> - append_compiler_options (&argv_obstack, fdecoded_options,
> >> - fdecoded_options_count);
> >> - append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
> >> + append_compiler_options (&argv_obstack, fdecoded_options);
> >> + append_linker_options (&argv_obstack, decoded_options);
> >>
> >> /* Scan linker driver arguments for things that are of relevance to us. */
> >> - for (j = 1; j < decoded_options_count; ++j)
> >> + for (j = 1; j < decoded_options.length (); ++j)
> >> {
> >> - struct cl_decoded_option *option = &decoded_options[j];
> >> + cl_decoded_option *option = &decoded_options[j];
> >> switch (option->opt_index)
> >> {
> >> case OPT_o:
> >> @@ -1711,9 +1662,7 @@ cont1:
> >> fatal_error (input_location, "cannot open %s: %m", filename);
> >> if (!find_and_merge_options (fd, file_offset,
> >> OFFLOAD_SECTION_NAME_PREFIX,
> >> - decoded_options, decoded_options_count,
> >> - &offload_fdecoded_options,
> >> - &offload_fdecoded_options_count,
> >> + decoded_options, &offload_fdecoded_options,
> >> collect_gcc))
> >> fatal_error (input_location, "cannot read %s: %m", filename);
> >> close (fd);
> >> @@ -1722,10 +1671,7 @@ cont1:
> >> }
> >>
> >> compile_images_for_offload_targets (num_offload_files, offload_argv,
> >> - offload_fdecoded_options,
> >> - offload_fdecoded_options_count,
> >> - decoded_options,
> >> - decoded_options_count);
> >> + offload_fdecoded_options, decoded_options);
> >>
> >> free_array_of_ptrs ((void **) offload_argv, num_offload_files);
> >>
> >> --
> >> 2.31.1
> >>
> >
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-05-12 9:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-21 8:12 [PATCH] lto-wrapper: Use vec<cl_decoded_option> data type Martin Liška
2021-04-29 12:22 ` Richard Biener
2021-04-29 15:19 ` Martin Sebor
2021-05-12 9:08 ` Martin Liška
2021-05-12 9:15 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).