diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-05-15 12:33:47 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-05-15 12:33:47 -0300 |
commit | 25fe3462fc2a3187be9af71b89bfffeaa690dc7e (patch) | |
tree | 845fd3dea7ff98766de3cd822330095e82fdfe25 /gcc | |
parent | dc1ede0455cfb5906dbf3865f2cc784c6709be52 (diff) | |
download | gcc-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/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/gcc.c | 249 | ||||
-rw-r--r-- | gcc/toplev.c | 4 |
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. @@ -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) |