aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-05-15 12:33:47 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-05-15 12:33:47 -0300
commit25fe3462fc2a3187be9af71b89bfffeaa690dc7e (patch)
tree845fd3dea7ff98766de3cd822330095e82fdfe25 /gcc
parentdc1ede0455cfb5906dbf3865f2cc784c6709be52 (diff)
downloadgcc-25fe3462fc2a3187be9af71b89bfffeaa690dc7e.zip
gcc-25fe3462fc2a3187be9af71b89bfffeaa690dc7e.tar.gz
gcc-25fe3462fc2a3187be9af71b89bfffeaa690dc7e.tar.bz2
Handle `as' calls when splitting asm output.
Read the temporary additional asm file provided by cc1*, and call the assembler for each of them. gcc/ChangeLog 2020-05-14 Giuliano Belinassi <giuliano.belinassi@usp.br> * gcc.c (extra_arg_storer): New function store. (extra_args): Move to execute. (get_file_by_lines): New function. (identify_asm_files): New function. (struct infile): Move up. (current_infile): New variable. (append_list_outputs): Handle the `as' case. (execute): Use XNEWVEC instead of alloca. * toplev.c (init_additional_asm_names_file): Break file list with newline. (lang_dependent_init): Provide correct asm filename.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/gcc.c249
-rw-r--r--gcc/toplev.c4
3 files changed, 213 insertions, 54 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index af340b4..ef793ff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2020-05-14 Giuliano Belinassi <giuliano.belinassi@usp.br>
+
+ * gcc.c (extra_arg_storer): New function store.
+ (extra_args): Move to execute.
+ (get_file_by_lines): New function.
+ (identify_asm_files): New function.
+ (struct infile): Move up.
+ (current_infile): New variable.
+ (append_list_outputs): Handle the `as' case.
+ (execute): Use XNEWVEC instead of alloca.
+ * toplev.c (init_additional_asm_names_file): Break file list with
+ newline.
+ (lang_dependent_init): Provide correct asm filename.
+
2020-05-12 Giuliano Belinassi <giuliano.belinassi@usp.br>
* gcc.c (extra_arg_storer): New variable extra_args.
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 8f530a9..16a11a2 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -349,6 +349,11 @@ class extra_arg_storer
return ret;
}
+ void store (char *str)
+ {
+ string_vec.safe_push (str);
+ }
+
~extra_arg_storer ()
{
release_extra_args ();
@@ -382,9 +387,6 @@ class extra_arg_storer
vec<char *> string_vec;
};
-/* Store additional strings for further release. */
-static extra_arg_storer extra_args;
-
/* Forward declaration for prototypes. */
struct path_prefix;
struct prefix_list;
@@ -3161,39 +3163,197 @@ static int get_number_of_args (const char *argv[])
static const char *fsplit_arg (extra_arg_storer *);
+/* Accumulate each line in lines vec. */
+
+void
+get_file_by_lines (extra_arg_storer *storer, vec<char *> *lines, FILE* file)
+{
+ int buf_size = 32, len = 0;
+ char *buf = XNEWVEC (char, buf_size);
+
+ while (1)
+ {
+ if (!fgets (buf + len, buf_size, file))
+ break;
+
+ len = strlen (buf);
+ if (buf[len - 1] == '\n') /* Check if we indeed read the entire line. */
+ {
+ buf[len - 1] = '\0';
+ /* Yes. Insert into the lines vector. */
+ lines->safe_push (buf);
+ len = 0;
+
+ /* Store the created string for future release. */
+ storer->store (buf);
+ }
+ else
+ {
+ /* No. Increase the buffer size and read again. */
+ buf = XRESIZEVEC (char, buf, buf_size * 2);
+ }
+ }
+}
+
+static void identify_asm_file (int argc, const char *argv[],
+ int *infile_pos, int *outfile_pos)
+{
+ int i;
+
+ static const char *asm_extension[] = {"s", "S"};
+ static const char *obj_extension[] = {"o", "O"};
+
+ bool infile_found = false;
+ bool outfile_found = false;
+
+ for (i = 0; i < argc; i++)
+ {
+ const char *arg = argv[i];
+ const char *ext = argv[i];
+ unsigned j;
+
+ /* Jump to last '.' of string. */
+ while (*arg)
+ if (*arg++ == '.')
+ ext = arg;
+
+ if (!infile_found)
+ for (j = 0; j < ARRAY_SIZE (asm_extension); ++j)
+ if (!strcmp (ext, asm_extension[j]))
+ {
+ infile_found = true;
+ *infile_pos = i;
+ break;
+ }
+
+ if (!outfile_found)
+ for (j = 0; j < ARRAY_SIZE (asm_extension); ++j)
+ if (!strcmp (ext, obj_extension[j]))
+ {
+ outfile_found = true;
+ *outfile_pos = i;
+ break;
+ }
+
+ if (infile_found && outfile_found)
+ return;
+ }
+
+ gcc_assert (infile_found && outfile_found);
+
+}
+
+/* Language is one of three things:
+
+ 1) The name of a real programming language.
+ 2) NULL, indicating that no one has figured out
+ what it is yet.
+ 3) '*', indicating that the file should be passed
+ to the linker. */
+struct infile
+{
+ const char *name;
+ const char *language;
+ const char *temp_additional_asm;
+ struct compiler *incompiler;
+ bool compiled;
+ bool preprocessed;
+};
+
+/* Also a vector of input files specified. */
+
+static struct infile *infiles;
+static struct infile *current_infile = NULL;
+
+int n_infiles;
+
+static int n_infiles_alloc;
+
+
/* Append -fsplit-output=<tempfile> to all calls to compilers. */
static void append_split_outputs (extra_arg_storer *storer,
- struct command *commands, int n_commands)
+ struct command **_commands, int *_n_commands)
{
int i;
- for (i = 0; i < n_commands; i++)
+ struct command *commands = *_commands;
+ int n_commands = *_n_commands;
+
+ const char **argv;
+ int argc;
+
+ const char *extra_argument;
+
+ if (is_compiler (commands[0].prog))
{
- const char **argv;
- int argc;
+ extra_argument = fsplit_arg (storer);
- const char *extra_argument;
+ argc = get_number_of_args (commands[0].argv);
+ argv = storer->create_new (argc + 2);
- if (is_compiler (commands[i].prog))
- {
- extra_argument = fsplit_arg (storer);
+ memcpy (argv, commands[0].argv, argc * sizeof (const char *));
+ argv[argc++] = extra_argument;
+ argv[argc] = NULL;
- argc = get_number_of_args (commands[i].argv);
- argv = storer->create_new (argc + 2);
+ commands[0].argv = argv;
+ }
- memcpy (argv, commands[i].argv, argc * sizeof (const char *));
- argv[argc++] = extra_argument;
- argv[argc] = NULL;
+ else if (is_assembler (commands[0].prog))
+ {
+ vec<char *> additional_asm_files;
- commands[i].argv = argv;
- }
- else if (is_assembler (commands[i].prog))
+ FILE *temp_asm_file;
+
+ struct command orig;
+ const char **orig_argv;
+ int orig_argc;
+
+ int infile_pos;
+ int outfile_pos;
+
+ if (n_commands != 1)
+ fatal_error (input_location, "Auto parallelism is unsupported when piping commands");
+
+ temp_asm_file = fopen (current_infile->temp_additional_asm, "r");
+
+ if (!temp_asm_file)
+ fatal_error (input_location, "Temporary file containing additional asm files not found");
+
+ get_file_by_lines (storer, &additional_asm_files, temp_asm_file);
+ fclose (temp_asm_file);
+
+ /* Get original command. */
+ orig = commands[0];
+ orig_argv = commands[0].argv;
+ orig_argc = get_number_of_args (orig.argv);
+
+
+ /* Update commands array to include the extra `as' calls. */
+ *_n_commands = additional_asm_files.length ();
+ n_commands = *_n_commands;
+
+ gcc_assert (n_commands > 0);
+
+ *_commands = XRESIZEVEC (struct command, *_commands, n_commands);
+ commands = *_commands;
+
+ identify_asm_file (orig_argc, orig_argv, &infile_pos, &outfile_pos);
+
+ for (i = 0; i < n_commands; i++)
{
+ const char **argv = storer->create_new (orig_argc + 1);
+ memcpy (argv, orig_argv, (orig_argc + 1) * sizeof (const char *));
+
+ argv[infile_pos] = additional_asm_files[i];
+ /* argv[outfile_pos] ?? do what? */
+ commands[i].prog = orig.prog;
+ commands[i].argv = argv;
}
}
+
}
DEBUG_FUNCTION void
@@ -3241,9 +3401,13 @@ execute (void)
char *string;
struct pex_obj *pex;
const char *arg;
+ int ret_code;
struct command *commands; /* each command buffer with above info. */
+ /* Store additional strings for further release. */
+ extra_arg_storer extra_args;
+
gcc_assert (!processing_spec_function);
if (wrapper_string)
@@ -3261,7 +3425,7 @@ execute (void)
n_commands++;
/* Get storage for each command. */
- commands = (struct command *) alloca (n_commands * sizeof (struct command));
+ commands = (struct command *) XNEWVEC (struct command, n_commands);
/* Split argbuf into its separate piped processes,
and record info about each one.
@@ -3357,7 +3521,8 @@ execute (void)
returning. This prevents spurious warnings about
unused linker input files, etc. */
execution_count++;
- return 0;
+ ret_code = 0;
+ goto cleanup;
}
#ifdef DEBUG
fnotice (stderr, "\nGo ahead? (y or n) ");
@@ -3368,7 +3533,10 @@ execute (void)
;
if (i != 'y' && i != 'Y')
- return 0;
+ {
+ ret_code = 0;
+ goto cleanup;
+ }
#endif /* DEBUG */
}
@@ -3400,7 +3568,7 @@ execute (void)
#endif
if (!have_S)
- append_split_outputs (&extra_args, commands, n_commands);
+ append_split_outputs (&extra_args, &commands, &n_commands);
/* Run each piped subprocess. */
@@ -3441,7 +3609,7 @@ execute (void)
{
int *statuses;
struct pex_time *times = NULL;
- int ret_code = 0;
+ ret_code = 0;
statuses = (int *) alloca (n_commands * sizeof (int));
if (!pex_get_status (pex, n_commands, statuses))
@@ -3577,9 +3745,12 @@ execute (void)
if (commands[0].argv[0] != commands[0].prog)
free (CONST_CAST (char *, commands[0].argv[0]));
-
- return ret_code;
+ goto cleanup;
}
+
+cleanup:
+ free (commands);
+ return ret_code;
}
/* Find all the switches given to us
@@ -3649,32 +3820,6 @@ static int n_switches_alloc_debug_check[2];
static char *debug_check_temp_file[2];
-/* Language is one of three things:
-
- 1) The name of a real programming language.
- 2) NULL, indicating that no one has figured out
- what it is yet.
- 3) '*', indicating that the file should be passed
- to the linker. */
-struct infile
-{
- const char *name;
- const char *language;
- const char *temp_additional_asm;
- struct compiler *incompiler;
- bool compiled;
- bool preprocessed;
-};
-
-/* Also a vector of input files specified. */
-
-static struct infile *infiles;
-static struct infile *current_infile = NULL;
-
-int n_infiles;
-
-static int n_infiles_alloc;
-
static const char *fsplit_arg (extra_arg_storer *storer)
{
const char *tempname = make_temp_file ("additional-asm");
diff --git a/gcc/toplev.c b/gcc/toplev.c
index acd1ba7..f50dd8f 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -914,7 +914,7 @@ init_additional_asm_names_file (int n, const char *names[])
error ("Unable to create a temporary write-only file.");
for (i = 0; i < n; ++i)
- fputs(names[i], additional_asm_filenames);
+ fprintf(additional_asm_filenames, "%s\n", names[i]);
}
@@ -1993,7 +1993,7 @@ lang_dependent_init (const char *name)
if (!flag_wpa)
{
init_asm_output (name);
- init_additional_asm_names_file (1, &name);
+ init_additional_asm_names_file (1, &asm_file_name);
/* If stack usage information is desired, open the output file. */
if (flag_stack_usage && !flag_generate_lto)