From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 83710 invoked by alias); 24 Jul 2015 08:22:02 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 83695 invoked by uid 89); 24 Jul 2015 08:22:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 24 Jul 2015 08:21:52 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-26-vXm9iEt5TimNHDcdg0JsbA-1; Fri, 24 Jul 2015 09:21:47 +0100 Received: from [10.2.207.50] ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 24 Jul 2015 09:21:46 +0100 Message-ID: <55B1F59A.9010309@arm.com> Date: Fri, 24 Jul 2015 08:30:00 -0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: James Greenhalgh CC: GCC Patches , Marcus Shawcroft , Richard Earnshaw Subject: Re: [PATCH][AArch64][3/14] Refactor option override code References: <55A7CBC5.3030201@arm.com> <20150720164426.GA20088@arm.com> In-Reply-To: <20150720164426.GA20088@arm.com> X-MC-Unique: vXm9iEt5TimNHDcdg0JsbA-1 Content-Type: multipart/mixed; boundary="------------050905000506060102030009" X-IsSubscribed: yes X-SW-Source: 2015-07/txt/msg02010.txt.bz2 This is a multi-part message in MIME format. --------------050905000506060102030009 Content-Type: text/plain; charset=WINDOWS-1252; format=flowed Content-Transfer-Encoding: quoted-printable Content-length: 10851 On 20/07/15 17:44, James Greenhalgh wrote: > On Thu, Jul 16, 2015 at 04:20:37PM +0100, Kyrill Tkachov wrote: >> Hi all, >> >> This one is more meaty than the previous ones. It buffs up the parsing f= unctions for >> the mcpu, march, mtune options, decouples them and makes them return an = enum describing >> the errors that may occur. This will allow us to use these functions in= other contexts >> beyond aarch64_override_options. >> >> aarch64_override_options itself gets an overhaul and is split up into co= de that must run >> only once after the command line option have been processed, and code th= at has to be run >> every time the backend-specific state changes (after SWITCHABLE_TARGET i= s implemented). >> >> The stuff that must be run every time the backend state changes is put i= nto >> aarch64_override_options_internal. >> >> Also, this patch deletes the declarations of aarch64_{arch,cpu,tune}_str= ing from aarch64.opt >> as they are superfluous since the march, mtune and mcpu option specifica= tion implicitly >> declares these variables. >> >> This patch looks large, but a lot of it is moving code around... >> >> Bootstrapped and tested as part of the series on aarch64. >> >> Ok for trunk? > I'm a bit hazy on the logic of one part, that is the refactoring of > aarch64_override_options_after_change in to > aarch64_override_options_after_change_1. > > It seems like if we have this hunk: > >> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c >> index 32b974a..5ea65e3 100644 >> --- a/gcc/config/aarch64/aarch64.c >> +++ b/gcc/config/aarch64/aarch64.c >> @@ -7473,85 +7507,253 @@ aarch64_parse_override_string (const char* inpu= t_string, >> free (string_root); >> } >>=20=20=20 >> -/* Implement TARGET_OPTION_OVERRIDE. */ >>=20=20=20 >> static void >> -aarch64_override_options (void) >> +aarch64_override_options_after_change_1 (struct gcc_options *opts) >> { >> - /* -mcpu=3DCPU is shorthand for -march=3DARCH_FOR_CPU, -mtune=3DCPU. >> - If either of -march or -mtune is given, they override their >> - respective component of -mcpu. >> + if (opts->x_flag_omit_frame_pointer) >> + opts->x_flag_omit_leaf_frame_pointer =3D false; >> + else if (opts->x_flag_omit_leaf_frame_pointer) >> + opts->x_flag_omit_frame_pointer =3D true; >>=20=20=20 >> - So, first parse AARCH64_CPU_STRING, then the others, be careful >> - with -march as, if -mcpu is not present on the command line, march >> - must set a sensible default CPU. */ >> - if (aarch64_cpu_string) >> + /* If not opzimizing for size, set the default >> + alignment to what the target wants. */ >> + if (!opts->x_optimize_size) >> { >> - aarch64_parse_cpu (); >> + if (opts->x_align_loops <=3D 0) >> + opts->x_align_loops =3D aarch64_tune_params.loop_align; >> + if (opts->x_align_jumps <=3D 0) >> + opts->x_align_jumps =3D aarch64_tune_params.jump_align; >> + if (opts->x_align_functions <=3D 0) >> + opts->x_align_functions =3D aarch64_tune_params.function_align; >> } >> +} > Then this code left behind in aarch64_override_options_after_change : >> if (flag_omit_frame_pointer) >> flag_omit_leaf_frame_pointer =3D false; >> else if (flag_omit_leaf_frame_pointer) >> flag_omit_frame_pointer =3D true; >> >> /* If not optimizing for size, set the default >> alignment to what the target wants */ >> if (!optimize_size) >> { >> if (align_loops <=3D 0) >> align_loops =3D aarch64_tune_params.loop_align; >> if (align_jumps <=3D 0) >> align_jumps =3D aarch64_tune_params.jump_align; >> if (align_functions <=3D 0) >> align_functions =3D aarch64_tune_params.function_align; >> } > is redundant/misleading. Yes, this is redundant. > >> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c >> index 32b974a..5ea65e3 100644 >> --- a/gcc/config/aarch64/aarch64.c >> +++ b/gcc/config/aarch64/aarch64.c >> @@ -7101,12 +7101,27 @@ aarch64_add_stmt_cost (void *data, int count, en= um vect_cost_for_stmt kind, >> return retval; >> } >>=20=20=20 >> -static void initialize_aarch64_code_model (void); >> +static void initialize_aarch64_code_model (struct gcc_options *); >>=20=20=20 >> -/* Parse the architecture extension string. */ >> +/* Enum describing the various ways that the >> + aarch64_parse_{arch,tune,cpu,extension} functions can fail. >> + This way their callers can choose what kind of error to give. */ >>=20=20=20 >> -static void >> -aarch64_parse_extension (char *str) >> +enum aarch64_parse_opt_result >> +{ >> + AARCH64_PARSE_OK, /* Parsing was successful. */ >> + AARCH64_PARSE_MISSING_ARG, /* Missing argument. */ >> + AARCH64_PARSE_INVALID_FEATURE, /* Invalid feature modifier. */ >> + AARCH64_PARSE_INVALID_ARG /* Invalid arch, tune, cpu arg. */ >> +}; >> + >> + > Extra newline here. > >> -/* Parse the ARCH string. */ >> +/* Parse the TO_PARSE string and put the architecture struct that it >> + selects into RES and the architectural features into ISA_FLAGS. >> + Return an aarch64_parse_opt_result describing the parse result. >> + If there is an error parsing, RES and ISA_FLAGS are left unchanged. = */ >>=20=20=20 >> -static void >> -aarch64_parse_arch (void) >> +static enum aarch64_parse_opt_result >> +aarch64_parse_arch (const char *to_parse, const struct processor **res, >> + unsigned long *isa_flags) >> { >> char *ext; >> const struct processor *arch; >> - char *str =3D (char *) alloca (strlen (aarch64_arch_string) + 1); >> + char *str =3D xstrdup (to_parse); >> size_t len; >>=20=20=20 >> - strcpy (str, aarch64_arch_string); >> + strcpy (str, to_parse); > Is this really needed after the xstrdup you used above? > >> -/* Parse the CPU string. */ >> +/* Parse the TO_PARSE string and put the result tuning in RES and the >> + architecture flags in ISA_FLAGS. Return an aarch64_parse_opt_result >> + describing the parse result. If there is an error parsing, RES and >> + ISA_FLAGS are left unchanged. */ >>=20=20=20 >> -static void >> -aarch64_parse_cpu (void) >> +static enum aarch64_parse_opt_result >> +aarch64_parse_cpu (const char *to_parse, const struct processor **res, >> + unsigned long *isa_flags) >> { >> char *ext; >> const struct processor *cpu; >> - char *str =3D (char *) alloca (strlen (aarch64_cpu_string) + 1); >> + char *str =3D xstrdup (to_parse); >> size_t len; >>=20=20=20 >> - strcpy (str, aarch64_cpu_string); >> + strcpy (str, to_parse); > As above, is this needed after the xstrdup? > >> -/* Parse the TUNE string. */ >> +/* Parse the TO_PARSE string and put the cpu it selects into RES. >> + Return an aarch64_parse_opt_result describing the parse result. >> + If the parsing fails the RES does not change. */ >>=20=20=20 >> -static void >> -aarch64_parse_tune (void) >> +static enum aarch64_parse_opt_result >> +aarch64_parse_tune (const char *to_parse, const struct processor **res) >> { >> const struct processor *cpu; >> - char *str =3D (char *) alloca (strlen (aarch64_tune_string) + 1); >> - strcpy (str, aarch64_tune_string); >> + char *str =3D xstrdup (to_parse); >> + strcpy (str, to_parse); > Likewise. > >> +/* 'Unpack' up the internal tuning structs and update the options >> + in OPTS. The caller must have set up selected_tune and selected_ar= ch >> + as all the other target-specific codegen decisions are >> + derived from them. */ >> + >> +static void >> +aarch64_override_options_internal (struct gcc_options *opts) >> +{ >> + aarch64_tune_flags =3D selected_tune->flags; >> + aarch64_tune =3D selected_tune->sched_core; >> + /* Make a copy of the tuning parameters attached to the core, which >> + we may later overwrite. */ >> + aarch64_tune_params =3D *(selected_tune->tune); >> + aarch64_architecture_version =3D selected_arch->architecture_version; >> + >> + if (opts->x_aarch64_override_tune_string) >> + aarch64_parse_override_string (opts->x_aarch64_override_tune_string, >> + &aarch64_tune_params); >> + >> + /* This target defaults to strict volatile bitfields. */ >> + if (opts->x_flag_strict_volatile_bitfields < 0 && abi_version_at_leas= t (2)) >> + opts->x_flag_strict_volatile_bitfields =3D 1; >> + >> + if (opts->x_aarch64_fix_a53_err835769 =3D=3D 2) >> { >> - aarch64_parse_arch (); >> +#ifdef TARGET_FIX_ERR_A53_835769_DEFAULT >> + opts->x_aarch64_fix_a53_err835769 =3D 1; >> +#else >> + opts->x_aarch64_fix_a53_err835769 =3D 0; >> +#endif >> } >>=20=20=20 >> - if (aarch64_tune_string) >> + /* -mgeneral-regs-only sets a mask in target_flags, make sure that >> + aarch64_isa_flags does not contain the FP/SIMD/Crypto feature flags >> + in case some code tries reading aarch64_isa_flags directly to chec= k if >> + FP is available. Reuse the aarch64_parse_extension machinery sinc= e it >> + knows how to disable any other flags that fp implies. */ >> + if (TARGET_GENERAL_REGS_ONLY_P (opts->x_target_flags)) >> { >> - aarch64_parse_tune (); >> + /* aarch64_parse_extension takes char* rather than const char* be= cause >> + it is usually called from within other parsing functions. */ >> + char tmp_str[6]; >> + strcpy (tmp_str, "+nofp"); > Just: > > char tmp_str[] =3D "+nofp"; > > ? Thanks for the review, here's an updated version. In the end, I chose to retain the use alloca (other patches in the series are reworked to use it too). How's this? Thanks, Kyrill 2015-07-24 Kyrylo Tkachov * config/aarch64/aarch64.opt (aarch64_arch_string): Delete. (aarch64_cpu_string): Likewise. (aarch64_tune_string): Likewise. * config/aarch64/aarch64.c (aarch64_parse_opt_result): New enum. (aarch64_parse_extension): Return aarch64_parse_opt_result. Add extra argument to put result into. (aarch64_parse_arch): Likewise. Do not set selected_cpu. (aarch64_parse_cpu): Add arguments to put results into. Return aarch64_parse_opt_result. (aarch64_parse_tune): Likewise. (aarch64_override_options_after_change_1): New function. (aarch64_override_options_internal): New function. (aarch64_validate_mcpu): Likewise. (aarch64_validate_march): Likewise. (aarch64_validate_mtune): Likewise. (aarch64_override_options): Update to reflect above changes. Move some logic into aarch64_override_options_internal. Initialize target_option_default_node and target_option_current_node. (aarch64_override_options_after_change): Move logic into aarch64_override_options_after_change_1 and call it with global_optio= ns. (initialize_aarch64_code_model): Take a gcc_options pointer and use t= he flag values from that. > > Thanks, > James > --------------050905000506060102030009 Content-Type: text/x-patch; name=aarch64-attrs-3.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="aarch64-attrs-3.patch" Content-length: 21418 commit 243a6567f976508332dcdf3623952a0f5d5bf123 Author: Kyrylo Tkachov Date: Wed May 6 16:27:00 2015 +0100 [AArch64][3/N] Refactor option override code diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 32b974a..2ed8505 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -7101,12 +7101,26 @@ aarch64_add_stmt_cost (void *data, int count, enum = vect_cost_for_stmt kind, return retval; } =20 -static void initialize_aarch64_code_model (void); +static void initialize_aarch64_code_model (struct gcc_options *); =20 -/* Parse the architecture extension string. */ +/* Enum describing the various ways that the + aarch64_parse_{arch,tune,cpu,extension} functions can fail. + This way their callers can choose what kind of error to give. */ =20 -static void -aarch64_parse_extension (char *str) +enum aarch64_parse_opt_result +{ + AARCH64_PARSE_OK, /* Parsing was successful. */ + AARCH64_PARSE_MISSING_ARG, /* Missing argument. */ + AARCH64_PARSE_INVALID_FEATURE, /* Invalid feature modifier. */ + AARCH64_PARSE_INVALID_ARG /* Invalid arch, tune, cpu arg. */ +}; + +/* Parse the architecture extension string STR and update ISA_FLAGS + with the architecture features turned on or off. Return a + aarch64_parse_opt_result describing the result. */ + +static enum aarch64_parse_opt_result +aarch64_parse_extension (char *str, unsigned long *isa_flags) { /* The extension string is parsed left to right. */ const struct aarch64_option_extension *opt =3D NULL; @@ -7137,11 +7151,8 @@ aarch64_parse_extension (char *str) adding_ext =3D 1; =20 if (len =3D=3D 0) - { - error ("missing feature modifier after %qs", adding_ext ? "+" - : "+no"); - return; - } + return AARCH64_PARSE_MISSING_ARG; + =20 /* Scan over the extensions table trying to find an exact match. */ for (opt =3D all_extensions; opt->name !=3D NULL; opt++) @@ -7150,9 +7161,9 @@ aarch64_parse_extension (char *str) { /* Add or remove the extension. */ if (adding_ext) - aarch64_isa_flags |=3D opt->flags_on; + *isa_flags |=3D opt->flags_on; else - aarch64_isa_flags &=3D ~(opt->flags_off); + *isa_flags &=3D ~(opt->flags_off); break; } } @@ -7160,27 +7171,30 @@ aarch64_parse_extension (char *str) if (opt->name =3D=3D NULL) { /* Extension not found in list. */ - error ("unknown feature modifier %qs", str); - return; + return AARCH64_PARSE_INVALID_FEATURE; } =20 str =3D ext; }; =20 - return; + return AARCH64_PARSE_OK; } =20 -/* Parse the ARCH string. */ +/* Parse the TO_PARSE string and put the architecture struct that it + selects into RES and the architectural features into ISA_FLAGS. + Return an aarch64_parse_opt_result describing the parse result. + If there is an error parsing, RES and ISA_FLAGS are left unchanged. */ =20 -static void -aarch64_parse_arch (void) +static enum aarch64_parse_opt_result +aarch64_parse_arch (const char *to_parse, const struct processor **res, + unsigned long *isa_flags) { char *ext; const struct processor *arch; - char *str =3D (char *) alloca (strlen (aarch64_arch_string) + 1); + char *str =3D (char *) alloca (strlen (to_parse) + 1); size_t len; =20 - strcpy (str, aarch64_arch_string); + strcpy (str, to_parse); =20 ext =3D strchr (str, '+'); =20 @@ -7190,55 +7204,52 @@ aarch64_parse_arch (void) len =3D strlen (str); =20 if (len =3D=3D 0) - { - error ("missing arch name in -march=3D%qs", str); - return; - } + return AARCH64_PARSE_MISSING_ARG; =20 - /* Loop through the list of supported ARCHs to find a match. */ + + /* Loop through the list of supported ARCHes to find a match. */ for (arch =3D all_architectures; arch->name !=3D NULL; arch++) { if (strlen (arch->name) =3D=3D len && strncmp (arch->name, str, len)= =3D=3D 0) { - selected_arch =3D arch; - aarch64_isa_flags =3D selected_arch->flags; - - if (!selected_cpu) - selected_cpu =3D &all_cores[selected_arch->ident]; + unsigned long isa_temp =3D arch->flags; =20 if (ext !=3D NULL) { - /* ARCH string contains at least one extension. */ - aarch64_parse_extension (ext); - } + /* TO_PARSE string contains at least one extension. */ + enum aarch64_parse_opt_result ext_res + =3D aarch64_parse_extension (ext, &isa_temp); =20 - if (selected_arch->arch !=3D selected_cpu->arch) - { - warning (0, "switch -mcpu=3D%s conflicts with -march=3D%s switch", - all_architectures[selected_cpu->arch].name, - selected_arch->name); + if (ext_res !=3D AARCH64_PARSE_OK) + return ext_res; } - - return; + /* Extension parsing was successful. Confirm the result + arch and ISA flags. */ + *res =3D arch; + *isa_flags =3D isa_temp; + return AARCH64_PARSE_OK; } } =20 /* ARCH name not found in list. */ - error ("unknown value %qs for -march", str); - return; + return AARCH64_PARSE_INVALID_ARG; } =20 -/* Parse the CPU string. */ +/* Parse the TO_PARSE string and put the result tuning in RES and the + architecture flags in ISA_FLAGS. Return an aarch64_parse_opt_result + describing the parse result. If there is an error parsing, RES and + ISA_FLAGS are left unchanged. */ =20 -static void -aarch64_parse_cpu (void) +static enum aarch64_parse_opt_result +aarch64_parse_cpu (const char *to_parse, const struct processor **res, + unsigned long *isa_flags) { char *ext; const struct processor *cpu; - char *str =3D (char *) alloca (strlen (aarch64_cpu_string) + 1); + char *str =3D (char *) alloca (strlen (to_parse) + 1); size_t len; =20 - strcpy (str, aarch64_cpu_string); + strcpy (str, to_parse); =20 ext =3D strchr (str, '+'); =20 @@ -7248,56 +7259,62 @@ aarch64_parse_cpu (void) len =3D strlen (str); =20 if (len =3D=3D 0) - { - error ("missing cpu name in -mcpu=3D%qs", str); - return; - } + return AARCH64_PARSE_MISSING_ARG; + =20 /* Loop through the list of supported CPUs to find a match. */ for (cpu =3D all_cores; cpu->name !=3D NULL; cpu++) { if (strlen (cpu->name) =3D=3D len && strncmp (cpu->name, str, len) = =3D=3D 0) { - selected_cpu =3D cpu; - aarch64_isa_flags =3D selected_cpu->flags; + unsigned long isa_temp =3D cpu->flags; + =20 if (ext !=3D NULL) { - /* CPU string contains at least one extension. */ - aarch64_parse_extension (ext); - } + /* TO_PARSE string contains at least one extension. */ + enum aarch64_parse_opt_result ext_res + =3D aarch64_parse_extension (ext, &isa_temp); =20 - return; + if (ext_res !=3D AARCH64_PARSE_OK) + return ext_res; + } + /* Extension parsing was successfull. Confirm the result + cpu and ISA flags. */ + *res =3D cpu; + *isa_flags =3D isa_temp; + return AARCH64_PARSE_OK; } } =20 /* CPU name not found in list. */ - error ("unknown value %qs for -mcpu", str); - return; + return AARCH64_PARSE_INVALID_ARG; } =20 -/* Parse the TUNE string. */ +/* Parse the TO_PARSE string and put the cpu it selects into RES. + Return an aarch64_parse_opt_result describing the parse result. + If the parsing fails the RES does not change. */ =20 -static void -aarch64_parse_tune (void) +static enum aarch64_parse_opt_result +aarch64_parse_tune (const char *to_parse, const struct processor **res) { const struct processor *cpu; - char *str =3D (char *) alloca (strlen (aarch64_tune_string) + 1); - strcpy (str, aarch64_tune_string); + char *str =3D (char *) alloca (strlen (to_parse) + 1); + + strcpy (str, to_parse); =20 /* Loop through the list of supported CPUs to find a match. */ for (cpu =3D all_cores; cpu->name !=3D NULL; cpu++) { if (strcmp (cpu->name, str) =3D=3D 0) { - selected_tune =3D cpu; - return; + *res =3D cpu; + return AARCH64_PARSE_OK; } } =20 /* CPU name not found in list. */ - error ("unknown value %qs for -mtune", str); - return; + return AARCH64_PARSE_INVALID_ARG; } =20 /* Parse TOKEN, which has length LENGTH to see if it is an option @@ -7473,85 +7490,254 @@ aarch64_parse_override_string (const char* input_s= tring, free (string_root); } =20 -/* Implement TARGET_OPTION_OVERRIDE. */ =20 static void -aarch64_override_options (void) +aarch64_override_options_after_change_1 (struct gcc_options *opts) { - /* -mcpu=3DCPU is shorthand for -march=3DARCH_FOR_CPU, -mtune=3DCPU. - If either of -march or -mtune is given, they override their - respective component of -mcpu. + if (opts->x_flag_omit_frame_pointer) + opts->x_flag_omit_leaf_frame_pointer =3D false; + else if (opts->x_flag_omit_leaf_frame_pointer) + opts->x_flag_omit_frame_pointer =3D true; =20 - So, first parse AARCH64_CPU_STRING, then the others, be careful - with -march as, if -mcpu is not present on the command line, march - must set a sensible default CPU. */ - if (aarch64_cpu_string) + /* If not opzimizing for size, set the default + alignment to what the target wants. */ + if (!opts->x_optimize_size) { - aarch64_parse_cpu (); + if (opts->x_align_loops <=3D 0) + opts->x_align_loops =3D aarch64_tune_params.loop_align; + if (opts->x_align_jumps <=3D 0) + opts->x_align_jumps =3D aarch64_tune_params.jump_align; + if (opts->x_align_functions <=3D 0) + opts->x_align_functions =3D aarch64_tune_params.function_align; } +} =20 - if (aarch64_arch_string) +/* 'Unpack' up the internal tuning structs and update the options + in OPTS. The caller must have set up selected_tune and selected_arch + as all the other target-specific codegen decisions are + derived from them. */ + +static void +aarch64_override_options_internal (struct gcc_options *opts) +{ + aarch64_tune_flags =3D selected_tune->flags; + aarch64_tune =3D selected_tune->sched_core; + /* Make a copy of the tuning parameters attached to the core, which + we may later overwrite. */ + aarch64_tune_params =3D *(selected_tune->tune); + aarch64_architecture_version =3D selected_arch->architecture_version; + + if (opts->x_aarch64_override_tune_string) + aarch64_parse_override_string (opts->x_aarch64_override_tune_string, + &aarch64_tune_params); + + /* This target defaults to strict volatile bitfields. */ + if (opts->x_flag_strict_volatile_bitfields < 0 && abi_version_at_least (= 2)) + opts->x_flag_strict_volatile_bitfields =3D 1; + + if (opts->x_aarch64_fix_a53_err835769 =3D=3D 2) { - aarch64_parse_arch (); +#ifdef TARGET_FIX_ERR_A53_835769_DEFAULT + opts->x_aarch64_fix_a53_err835769 =3D 1; +#else + opts->x_aarch64_fix_a53_err835769 =3D 0; +#endif } =20 - if (aarch64_tune_string) + /* -mgeneral-regs-only sets a mask in target_flags, make sure that + aarch64_isa_flags does not contain the FP/SIMD/Crypto feature flags + in case some code tries reading aarch64_isa_flags directly to check if + FP is available. Reuse the aarch64_parse_extension machinery since it + knows how to disable any other flags that fp implies. */ + if (TARGET_GENERAL_REGS_ONLY_P (opts->x_target_flags)) { - aarch64_parse_tune (); + /* aarch64_parse_extension takes char* rather than const char* becau= se + it is usually called from within other parsing functions. */ + char tmp_str[] =3D "+nofp"; + aarch64_parse_extension (tmp_str, &aarch64_isa_flags); } =20 -#ifndef HAVE_AS_MABI_OPTION - /* The compiler may have been configured with 2.23.* binutils, which does - not have support for ILP32. */ - if (TARGET_ILP32) - error ("Assembler does not support -mabi=3Dilp32"); -#endif + initialize_aarch64_code_model (opts); =20 - initialize_aarch64_code_model (); + aarch64_override_options_after_change_1 (opts); +} =20 - aarch64_build_bitmask_table (); +/* Validate a command-line -mcpu option. Parse the cpu and extensions (if= any) + specified in STR and throw errors if appropriate. Put the results if + they are valid in RES and ISA_FLAGS. */ +static void +aarch64_validate_mcpu (const char *str, const struct processor **res, + unsigned long *isa_flags) +{ + enum aarch64_parse_opt_result parse_res + =3D aarch64_parse_cpu (str, res, isa_flags); =20 - /* This target defaults to strict volatile bitfields. */ - if (flag_strict_volatile_bitfields < 0 && abi_version_at_least (2)) - flag_strict_volatile_bitfields =3D 1; + if (parse_res =3D=3D AARCH64_PARSE_OK) + return; + + switch (parse_res) + { + case AARCH64_PARSE_MISSING_ARG: + error ("missing cpu name in -mcpu=3D%qs", str); + break; + case AARCH64_PARSE_INVALID_ARG: + error ("unknown value %qs for -mcpu", str); + break; + case AARCH64_PARSE_INVALID_FEATURE: + error ("invalid feature modifier in -mcpu=3D%qs", str); + break; + default: + gcc_unreachable (); + } +} + +/* Validate a command-line -march option. Parse the arch and extensions + (if any) specified in STR and throw errors if appropriate. Put the + results, if they are valid, in RES and ISA_FLAGS. */ +static void +aarch64_validate_march (const char *str, const struct processor **res, + unsigned long *isa_flags) +{ + enum aarch64_parse_opt_result parse_res + =3D aarch64_parse_arch (str, res, isa_flags); + + if (parse_res =3D=3D AARCH64_PARSE_OK) + return; + + switch (parse_res) + { + case AARCH64_PARSE_MISSING_ARG: + error ("missing arch name in -march=3D%qs", str); + break; + case AARCH64_PARSE_INVALID_ARG: + error ("unknown value %qs for -march", str); + break; + case AARCH64_PARSE_INVALID_FEATURE: + error ("invalid feature modifier in -march=3D%qs", str); + break; + default: + gcc_unreachable (); + } +} + +/* Validate a command-line -mtune option. Parse the cpu + specified in STR and throw errors if appropriate. Put the + result, if it is valid, in RES. */ +static void +aarch64_validate_mtune (const char *str, const struct processor **res) +{ + enum aarch64_parse_opt_result parse_res + =3D aarch64_parse_tune (str, res); + + if (parse_res =3D=3D AARCH64_PARSE_OK) + return; + + switch (parse_res) + { + case AARCH64_PARSE_MISSING_ARG: + error ("missing cpu name in -mtune=3D%qs", str); + break; + case AARCH64_PARSE_INVALID_ARG: + error ("unknown value %qs for -mtune", str); + break; + default: + gcc_unreachable (); + } +} + +/* Implement TARGET_OPTION_OVERRIDE. This is called once in the beginning + and is used to parse the -m{cpu,tune,arch} strings and setup the initial + tuning structs. In particular it must set selected_tune and + aarch64_isa_flags that define the available ISA features and tuning + decisions. It must also set selected_arch as this will be used to + output the .arch asm tags for each function. */ + +static void +aarch64_override_options (void) +{ + unsigned long cpu_isa =3D 0; + unsigned long arch_isa =3D 0; + aarch64_isa_flags =3D 0; + + selected_cpu =3D NULL; + selected_arch =3D NULL; + selected_tune =3D NULL; + + /* -mcpu=3DCPU is shorthand for -march=3DARCH_FOR_CPU, -mtune=3DCPU. + If either of -march or -mtune is given, they override their + respective component of -mcpu. */ + if (aarch64_cpu_string) + aarch64_validate_mcpu (aarch64_cpu_string, &selected_cpu, &cpu_isa); + + if (aarch64_arch_string) + aarch64_validate_march (aarch64_arch_string, &selected_arch, &arch_isa= ); + + if (aarch64_tune_string) + aarch64_validate_mtune (aarch64_tune_string, &selected_tune); =20 /* If the user did not specify a processor, choose the default one for them. This will be the CPU set during configuration using --with-cpu, otherwise it is "generic". */ if (!selected_cpu) { - selected_cpu =3D &all_cores[TARGET_CPU_DEFAULT & 0x3f]; - aarch64_isa_flags =3D TARGET_CPU_DEFAULT >> 6; + if (selected_arch) + { + selected_cpu =3D &all_cores[selected_arch->ident]; + aarch64_isa_flags =3D arch_isa; + } + else + { + selected_cpu =3D &all_cores[TARGET_CPU_DEFAULT & 0x3f]; + aarch64_isa_flags =3D TARGET_CPU_DEFAULT >> 6; + } + } + /* If both -mcpu and -march are specified check that they are architectu= rally + compatible, warn if they're not and prefer the -march ISA flags. */ + else if (selected_arch) + { + if (selected_arch->arch !=3D selected_cpu->arch) + { + warning (0, "switch -mcpu=3D%s conflicts with -march=3D%s switch", + all_architectures[selected_cpu->arch].name, + selected_arch->name); + } + aarch64_isa_flags =3D arch_isa; + } + else + { + /* -mcpu but no -march. */ + aarch64_isa_flags =3D cpu_isa; } =20 - gcc_assert (selected_cpu); + /* Set the arch as well as we will need it when outputing + the .arch directive in assembly. */ + if (!selected_arch) + { + gcc_assert (selected_cpu); + selected_arch =3D &all_architectures[selected_cpu->arch]; + } =20 if (!selected_tune) selected_tune =3D selected_cpu; =20 - aarch64_tune_flags =3D selected_tune->flags; - aarch64_tune =3D selected_tune->sched_core; - /* Make a copy of the tuning parameters attached to the core, which - we may later overwrite. */ - aarch64_tune_params =3D *(selected_tune->tune); - aarch64_architecture_version =3D selected_cpu->architecture_version; +#ifndef HAVE_AS_MABI_OPTION + /* The compiler may have been configured with 2.23.* binutils, which does + not have support for ILP32. */ + if (TARGET_ILP32) + error ("Assembler does not support -mabi=3Dilp32"); +#endif =20 - if (aarch64_override_tune_string) - aarch64_parse_override_string (aarch64_override_tune_string, - &aarch64_tune_params); + aarch64_build_bitmask_table (); =20 - if (aarch64_fix_a53_err835769 =3D=3D 2) - { -#ifdef TARGET_FIX_ERR_A53_835769_DEFAULT - aarch64_fix_a53_err835769 =3D 1; -#else - aarch64_fix_a53_err835769 =3D 0; -#endif - } + aarch64_override_options_internal (&global_options); + + /* Save these options as the default ones in case we push and pop them l= ater + while processing functions with potential target attributes. */ + target_option_default_node =3D target_option_current_node + =3D build_target_option_node (&global_options); =20 aarch64_register_fma_steering (); =20 - aarch64_override_options_after_change (); } =20 /* Implement targetm.override_options_after_change. */ @@ -7559,22 +7745,7 @@ aarch64_override_options (void) static void aarch64_override_options_after_change (void) { - if (flag_omit_frame_pointer) - flag_omit_leaf_frame_pointer =3D false; - else if (flag_omit_leaf_frame_pointer) - flag_omit_frame_pointer =3D true; - - /* If not optimizing for size, set the default - alignment to what the target wants */ - if (!optimize_size) - { - if (align_loops <=3D 0) - align_loops =3D aarch64_tune_params.loop_align; - if (align_jumps <=3D 0) - align_jumps =3D aarch64_tune_params.jump_align; - if (align_functions <=3D 0) - align_functions =3D aarch64_tune_params.function_align; - } + aarch64_override_options_after_change_1 (&global_options); } =20 static struct machine_function * @@ -7593,11 +7764,11 @@ aarch64_init_expanders (void) =20 /* A checking mechanism for the implementation of the various code models.= */ static void -initialize_aarch64_code_model (void) +initialize_aarch64_code_model (struct gcc_options *opts) { - if (flag_pic) + if (opts->x_flag_pic) { - switch (aarch64_cmodel_var) + switch (opts->x_aarch64_cmodel_var) { case AARCH64_CMODEL_TINY: aarch64_cmodel =3D AARCH64_CMODEL_TINY_PIC; @@ -7613,13 +7784,13 @@ initialize_aarch64_code_model (void) break; case AARCH64_CMODEL_LARGE: sorry ("code model %qs with -f%s", "large", - flag_pic > 1 ? "PIC" : "pic"); + opts->x_flag_pic > 1 ? "PIC" : "pic"); default: gcc_unreachable (); } } else - aarch64_cmodel =3D aarch64_cmodel_var; + aarch64_cmodel =3D opts->x_aarch64_cmodel_var; } =20 /* Return true if SYMBOL_REF X binds locally. */ diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index 98ef9f6..c9c0aff 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -48,17 +48,6 @@ Enum(cmodel) String(small) Value(AARCH64_CMODEL_SMALL) EnumValue Enum(cmodel) String(large) Value(AARCH64_CMODEL_LARGE) =20 -; The cpu/arch option names to use in cpu/arch selection. - -Variable -const char *aarch64_arch_string - -Variable -const char *aarch64_cpu_string - -Variable -const char *aarch64_tune_string - mbig-endian Target Report RejectNegative Mask(BIG_END) Assume target CPU is configured as big endian diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c b/gcc/tes= tsuite/gcc.target/aarch64/cpu-diagnostics-3.c index 155def0..807e325 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c +++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c @@ -1,4 +1,4 @@ -/* { dg-error "unknown" "" {target "aarch64*-*-*" } } */ +/* { dg-error "invalid feature" "" {target "aarch64*-*-*" } } */ /* { dg-options "-O2 -mcpu=3Dcortex-a53+dummy" } */ =20 void f () --------------050905000506060102030009--