Commit 8dec06f2 by James Greenhalgh Committed by James Greenhalgh

[Patch AArch64 4/4] Add -moverride tuning command, and wire it up for

 control of fusion and fma-steering

gcc/

	* config/aarch64/aarch64.opt: (override): New.
	* doc/invoke.texi (override): Document.
	* config/aarch64/aarch64.c (aarch64_flag_desc): New
	(aarch64_fusible_pairs): Likewise.
	(aarch64_tuning_flags): Likewise.
	(aarch64_tuning_override_function): Likewise.
	(aarch64_tuning_override_functions): Likewise.
	(aarch64_parse_one_option_token): Likewise.
	(aarch64_parse_boolean_options): Likewise.
	(aarch64_parse_fuse_string): Likewise.
	(aarch64_parse_tune_string): Likewise.
	(aarch64_parse_one_override_token): Likewise.
	(aarch64_parse_override_string): Likewise.
	(aarch64_override_options): Parse the -override string if it
	is present.

From-SVN: r225018
parent 1b1e81f8
2015-06-26 James Greenhalgh <james.greenhalgh@arm.com>
* config/aarch64/aarch64.opt: (override): New.
* doc/invoke.texi (override): Document.
* config/aarch64/aarch64.c (aarch64_flag_desc): New
(aarch64_fusible_pairs): Likewise.
(aarch64_tuning_flags): Likewise.
(aarch64_tuning_override_function): Likewise.
(aarch64_tuning_override_functions): Likewise.
(aarch64_parse_one_option_token): Likewise.
(aarch64_parse_boolean_options): Likewise.
(aarch64_parse_fuse_string): Likewise.
(aarch64_parse_tune_string): Likewise.
(aarch64_parse_one_override_token): Likewise.
(aarch64_parse_override_string): Likewise.
(aarch64_override_options): Parse the -override string if it
is present.
2015-06-26 James Greenhalgh <james.greenhalgh@arm.com>
* config/aarch64/aarch64-protos.h (tune_params): Remove
const from members.
(aarch64_tune_params): Remove const, change to no longer be
......
......@@ -172,6 +172,36 @@ unsigned long aarch64_isa_flags = 0;
/* Mask to specify which instruction scheduling options should be used. */
unsigned long aarch64_tune_flags = 0;
/* Support for command line parsing of boolean flags in the tuning
structures. */
struct aarch64_flag_desc
{
const char* name;
unsigned int flag;
};
#define AARCH64_FUSION_PAIR(name, internal_name, y) \
{ name, AARCH64_FUSE_##internal_name },
static const struct aarch64_flag_desc aarch64_fusible_pairs[] =
{
{ "none", AARCH64_FUSE_NOTHING },
#include "aarch64-fusion-pairs.def"
{ "all", AARCH64_FUSE_ALL },
{ NULL, AARCH64_FUSE_NOTHING }
};
#undef AARCH64_FUION_PAIR
#define AARCH64_EXTRA_TUNING_OPTION(name, internal_name, y) \
{ name, AARCH64_EXTRA_TUNE_##internal_name },
static const struct aarch64_flag_desc aarch64_tuning_flags[] =
{
{ "none", AARCH64_EXTRA_TUNE_NONE },
#include "aarch64-tuning-flags.def"
{ "all", AARCH64_EXTRA_TUNE_ALL },
{ NULL, AARCH64_EXTRA_TUNE_NONE }
};
#undef AARCH64_EXTRA_TUNING_OPTION
/* Tuning parameters. */
static const struct cpu_addrcost_table generic_addrcost_table =
......@@ -454,6 +484,24 @@ static const struct tune_params xgene1_tunings =
(AARCH64_EXTRA_TUNE_NONE) /* tune_flags. */
};
/* Support for fine-grained override of the tuning structures. */
struct aarch64_tuning_override_function
{
const char* name;
void (*parse_override)(const char*, struct tune_params*);
};
static void aarch64_parse_fuse_string (const char*, struct tune_params*);
static void aarch64_parse_tune_string (const char*, struct tune_params*);
static const struct aarch64_tuning_override_function
aarch64_tuning_override_functions[] =
{
{ "fuse", aarch64_parse_fuse_string },
{ "tune", aarch64_parse_tune_string },
{ NULL, NULL }
};
/* A processor implementing AArch64. */
struct processor
{
......@@ -7230,6 +7278,178 @@ aarch64_parse_tune (void)
return;
}
/* Parse TOKEN, which has length LENGTH to see if it is an option
described in FLAG. If it is, return the index bit for that fusion type.
If not, error (printing OPTION_NAME) and return zero. */
static unsigned int
aarch64_parse_one_option_token (const char *token,
size_t length,
const struct aarch64_flag_desc *flag,
const char *option_name)
{
for (; flag->name != NULL; flag++)
{
if (length == strlen (flag->name)
&& !strncmp (flag->name, token, length))
return flag->flag;
}
error ("unknown flag passed in -moverride=%s (%s)", option_name, token);
return 0;
}
/* Parse OPTION which is a comma-separated list of flags to enable.
FLAGS gives the list of flags we understand, INITIAL_STATE gives any
default state we inherit from the CPU tuning structures. OPTION_NAME
gives the top-level option we are parsing in the -moverride string,
for use in error messages. */
static unsigned int
aarch64_parse_boolean_options (const char *option,
const struct aarch64_flag_desc *flags,
unsigned int initial_state,
const char *option_name)
{
const char separator = '.';
const char* specs = option;
const char* ntoken = option;
unsigned int found_flags = initial_state;
while ((ntoken = strchr (specs, separator)))
{
size_t token_length = ntoken - specs;
unsigned token_ops = aarch64_parse_one_option_token (specs,
token_length,
flags,
option_name);
/* If we find "none" (or, for simplicity's sake, an error) anywhere
in the token stream, reset the supported operations. So:
adrp+add.cmp+branch.none.adrp+add
would have the result of turning on only adrp+add fusion. */
if (!token_ops)
found_flags = 0;
found_flags |= token_ops;
specs = ++ntoken;
}
/* We ended with a comma, print something. */
if (!(*specs))
{
error ("%s string ill-formed\n", option_name);
return 0;
}
/* We still have one more token to parse. */
size_t token_length = strlen (specs);
unsigned token_ops = aarch64_parse_one_option_token (specs,
token_length,
flags,
option_name);
if (!token_ops)
found_flags = 0;
found_flags |= token_ops;
return found_flags;
}
/* Support for overriding instruction fusion. */
static void
aarch64_parse_fuse_string (const char *fuse_string,
struct tune_params *tune)
{
tune->fusible_ops = aarch64_parse_boolean_options (fuse_string,
aarch64_fusible_pairs,
tune->fusible_ops,
"fuse=");
}
/* Support for overriding other tuning flags. */
static void
aarch64_parse_tune_string (const char *tune_string,
struct tune_params *tune)
{
tune->extra_tuning_flags
= aarch64_parse_boolean_options (tune_string,
aarch64_tuning_flags,
tune->extra_tuning_flags,
"tune=");
}
/* Parse TOKEN, which has length LENGTH to see if it is a tuning option
we understand. If it is, extract the option string and handoff to
the appropriate function. */
void
aarch64_parse_one_override_token (const char* token,
size_t length,
struct tune_params *tune)
{
const struct aarch64_tuning_override_function *fn
= aarch64_tuning_override_functions;
const char *option_part = strchr (token, '=');
if (!option_part)
{
error ("tuning string missing in option (%s)", token);
return;
}
/* Get the length of the option name. */
length = option_part - token;
/* Skip the '=' to get to the option string. */
option_part++;
for (; fn->name != NULL; fn++)
{
if (!strncmp (fn->name, token, length))
{
fn->parse_override (option_part, tune);
return;
}
}
error ("unknown tuning option (%s)",token);
return;
}
/* Parse STRING looking for options in the format:
string :: option:string
option :: name=substring
name :: {a-z}
substring :: defined by option. */
static void
aarch64_parse_override_string (const char* input_string,
struct tune_params* tune)
{
const char separator = ':';
size_t string_length = strlen (input_string) + 1;
char *string_root = (char *) xmalloc (sizeof (*string_root) * string_length);
char *string = string_root;
strncpy (string, input_string, string_length);
string[string_length - 1] = '\0';
char* ntoken = string;
while ((ntoken = strchr (string, separator)))
{
size_t token_length = ntoken - string;
/* Make this substring look like a string. */
*ntoken = '\0';
aarch64_parse_one_override_token (string, token_length, tune);
string = ++ntoken;
}
/* One last option to parse. */
aarch64_parse_one_override_token (string, strlen (string), tune);
free (string_root);
}
/* Implement TARGET_OPTION_OVERRIDE. */
......@@ -7294,6 +7514,10 @@ aarch64_override_options (void)
aarch64_tune_params = *(selected_tune->tune);
aarch64_architecture_version = selected_cpu->architecture_version;
if (aarch64_override_tune_string)
aarch64_parse_override_string (aarch64_override_tune_string,
&aarch64_tune_params);
if (aarch64_fix_a53_err835769 == 2)
{
#ifdef TARGET_FIX_ERR_A53_835769_DEFAULT
......
......@@ -111,6 +111,10 @@ mabi=
Target RejectNegative Joined Enum(aarch64_abi) Var(aarch64_abi) Init(AARCH64_ABI_DEFAULT)
-mabi=ABI Generate code that conforms to the specified ABI
moverride=
Target RejectNegative ToLower Joined Var(aarch64_override_tune_string)
-moverride=STRING Power users only! Override CPU optimization parameters
Enum
Name(aarch64_abi) Type(int)
Known AArch64 ABIs (for use with the -mabi= option):
......
......@@ -12525,6 +12525,15 @@ Enable Privileged Access Never support.
Enable Limited Ordering Regions support.
@item rdma
Enable ARMv8.1 Advanced SIMD instructions.
@item -moverride=@var{string}
@opindex master
Override tuning decisions made by the back-end in response to a
@option{-mtune=} switch. The syntax, semantics, and accepted values
for @var{string} in this option are not guaranteed to be consistent
across releases.
This option is only intended to be useful when developing GCC.
@end table
That is, @option{crypto} implies @option{simd} implies @option{fp}.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment