Skip to content

Commit

Permalink
Add TARGET_COMPUTE_MULTILIB hook to override multi-lib result.
Browse files Browse the repository at this point in the history
Create a new hook to let target could override the multi-lib result,
the motivation is RISC-V might have very complicated multi-lib re-use
rule*, which is hard to maintain and use current multi-lib scripts,
we even hit the "argument list too long" error when we tried to add more
multi-lib reuse rule.

So I think it would be great to have a target specific way to determine
the multi-lib re-use rule, then we could write those rule in C, instead
of expand every possible case in MULTILIB_REUSE.

* Here is an example for RISC-V multi-lib rules:
https://gist.github.com/kito-cheng/0289cd42d9a756382e5afeb77b42b73b

gcc/ChangeLog:

	* common/common-target.def (compute_multilib): New.
	* common/common-targhooks.h (default_compute_multilib): New.
	* common/common-targhooks.cc (default_compute_multilib): New.
	* doc/tm.texi.in (TARGET_COMPUTE_MULTILIB): New.
	* doc/tm.texi: Regen.
	* gcc.cc: Include common/common-target.h.
	(set_multilib_dir) Call targetm_common.compute_multilib.
	(SWITCH_LIVE): Move to opts.h.
	(SWITCH_FALSE): Ditto.
	(SWITCH_IGNORE): Ditto.
	(SWITCH_IGNORE_PERMANENTLY): Ditto.
	(SWITCH_KEEP_FOR_GCC): Ditto.
	(struct switchstr): Ditto.
	* opts.h (SWITCH_LIVE): Move from gcc.c.
	(SWITCH_FALSE): Ditto.
	(SWITCH_IGNORE): Ditto.
	(SWITCH_IGNORE_PERMANENTLY): Ditto.
	(SWITCH_KEEP_FOR_GCC): Ditto.
	(struct switchstr): Ditto.
  • Loading branch information
kito-cheng committed Sep 2, 2022
1 parent 347dec1 commit 5ca9980
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 36 deletions.
25 changes: 25 additions & 0 deletions gcc/common/common-target.def
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,31 @@ The result will be pruned to cases with PREFIX if not NULL.",
vec<const char *>, (int option_code, const char *prefix),
default_get_valid_option_values)

DEFHOOK
(compute_multilib,
"Some targets like RISC-V might have complicated multilib reuse rules which\n\
are hard to implement with the current multilib scheme. This hook allows\n\
targets to override the result from the built-in multilib mechanism.\n\
@var{switches} is the raw option list with @var{n_switches} items;\n\
@var{multilib_dir} is the multi-lib result which is computed by the built-in\n\
multi-lib mechanism;\n\
@var{multilib_defaults} is the default options list for multi-lib;\n\
@var{multilib_select} is the string containing the list of supported\n\
multi-libs, and the option checking list.\n\
@var{multilib_matches}, @var{multilib_exclusions}, and @var{multilib_reuse}\n\
are corresponding to @var{MULTILIB_MATCHES}, @var{MULTILIB_EXCLUSIONS},\n\
and @var{MULTILIB_REUSE}.\n\
The default definition does nothing but return @var{multilib_dir} directly.",
const char *, (const struct switchstr *switches,
int n_switches,
const char *multilib_dir,
const char *multilib_defaults,
const char *multilib_select,
const char *multilib_matches,
const char *multilib_exclusions,
const char *multilib_reuse),
default_compute_multilib)

/* Leave the boolean fields at the end. */

/* True if unwinding tables should be generated by default. */
Expand Down
15 changes: 15 additions & 0 deletions gcc/common/common-targhooks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,18 @@ const struct default_options empty_optimization_table[] =
{
{ OPT_LEVELS_NONE, 0, NULL, 0 }
};

/* Default version of TARGET_COMPUTE_MULTILIB. */
const char *
default_compute_multilib(
const struct switchstr *,
int,
const char *multilib,
const char *,
const char *,
const char *,
const char *,
const char *)
{
return multilib;
}
11 changes: 11 additions & 0 deletions gcc/common/common-targhooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,15 @@ extern vec<const char *> default_get_valid_option_values (int, const char *);

extern const struct default_options empty_optimization_table[];

const char *
default_compute_multilib(
const struct switchstr *,
int,
const char *multilib,
const char *,
const char *,
const char *,
const char *,
const char *);

#endif
17 changes: 17 additions & 0 deletions gcc/doc/tm.texi
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,23 @@ options are changed via @code{#pragma GCC optimize} or by using the
Set target-dependent initial values of fields in @var{opts}.
@end deftypefn

@deftypefn {Common Target Hook} {const char *} TARGET_COMPUTE_MULTILIB (const struct switchstr *@var{switches}, int @var{n_switches}, const char *@var{multilib_dir}, const char *@var{multilib_defaults}, const char *@var{multilib_select}, const char *@var{multilib_matches}, const char *@var{multilib_exclusions}, const char *@var{multilib_reuse})
Some targets like RISC-V might have complicated multilib reuse rules which
are hard to implement with the current multilib scheme. This hook allows
targets to override the result from the built-in multilib mechanism.
@var{switches} is the raw option list with @var{n_switches} items;
@var{multilib_dir} is the multi-lib result which is computed by the built-in
multi-lib mechanism;
@var{multilib_defaults} is the default options list for multi-lib;
@var{multilib_select} is the string containing the list of supported
multi-libs, and the option checking list.
@var{multilib_matches}, @var{multilib_exclusions}, and @var{multilib_reuse}
are corresponding to @var{MULTILIB_MATCHES}, @var{MULTILIB_EXCLUSIONS},
and @var{MULTILIB_REUSE}.
The default definition does nothing but return @var{multilib_dir} directly.
@end deftypefn


@defmac SWITCHABLE_TARGET
Some targets need to switch between substantially different subtargets
during compilation. For example, the MIPS target has one subtarget for
Expand Down
3 changes: 3 additions & 0 deletions gcc/doc/tm.texi.in
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,9 @@ options are changed via @code{#pragma GCC optimize} or by using the

@hook TARGET_OPTION_INIT_STRUCT

@hook TARGET_COMPUTE_MULTILIB


@defmac SWITCHABLE_TARGET
Some targets need to switch between substantially different subtargets
during compilation. For example, the MIPS target has one subtarget for
Expand Down
48 changes: 12 additions & 36 deletions gcc/gcc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ compilation is specified by a string called a "spec". */
#include "filenames.h"
#include "spellcheck.h"
#include "opts-jobserver.h"
#include "common/common-target.h"



Expand Down Expand Up @@ -3563,42 +3564,6 @@ execute (void)
}
}

/* Find all the switches given to us
and make a vector describing them.
The elements of the vector are strings, one per switch given.
If a switch uses following arguments, then the `part1' field
is the switch itself and the `args' field
is a null-terminated vector containing the following arguments.
Bits in the `live_cond' field are:
SWITCH_LIVE to indicate this switch is true in a conditional spec.
SWITCH_FALSE to indicate this switch is overridden by a later switch.
SWITCH_IGNORE to indicate this switch should be ignored (used in %<S).
SWITCH_IGNORE_PERMANENTLY to indicate this switch should be ignored.
SWITCH_KEEP_FOR_GCC to indicate that this switch, otherwise ignored,
should be included in COLLECT_GCC_OPTIONS.
in all do_spec calls afterwards. Used for %<S from self specs.
The `known' field describes whether this is an internal switch.
The `validated' field describes whether any spec has looked at this switch;
if it remains false at the end of the run, the switch must be meaningless.
The `ordering' field is used to temporarily mark switches that have to be
kept in a specific order. */

#define SWITCH_LIVE (1 << 0)
#define SWITCH_FALSE (1 << 1)
#define SWITCH_IGNORE (1 << 2)
#define SWITCH_IGNORE_PERMANENTLY (1 << 3)
#define SWITCH_KEEP_FOR_GCC (1 << 4)

struct switchstr
{
const char *part1;
const char **args;
unsigned int live_cond;
bool known;
bool validated;
bool ordering;
};

static struct switchstr *switches;

static int n_switches;
Expand Down Expand Up @@ -9827,6 +9792,17 @@ set_multilib_dir (void)
++p;
}

multilib_dir =
targetm_common.compute_multilib (
switches,
n_switches,
multilib_dir,
multilib_defaults,
multilib_select,
multilib_matches,
multilib_exclusions,
multilib_reuse);

if (multilib_dir == NULL && multilib_os_dir != NULL
&& strcmp (multilib_os_dir, ".") == 0)
{
Expand Down
36 changes: 36 additions & 0 deletions gcc/opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,40 @@ extern char *gen_producer_string (const char *language_string,

#define OPTION_SET_P(OPTION) global_options_set.x_ ## OPTION

/* Find all the switches given to us
and make a vector describing them.
The elements of the vector are strings, one per switch given.
If a switch uses following arguments, then the `part1' field
is the switch itself and the `args' field
is a null-terminated vector containing the following arguments.
Bits in the `live_cond' field are:
SWITCH_LIVE to indicate this switch is true in a conditional spec.
SWITCH_FALSE to indicate this switch is overridden by a later switch.
SWITCH_IGNORE to indicate this switch should be ignored (used in %<S).
SWITCH_IGNORE_PERMANENTLY to indicate this switch should be ignored.
SWITCH_KEEP_FOR_GCC to indicate that this switch, otherwise ignored,
should be included in COLLECT_GCC_OPTIONS.
in all do_spec calls afterwards. Used for %<S from self specs.
The `known' field describes whether this is an internal switch.
The `validated' field describes whether any spec has looked at this switch;
if it remains false at the end of the run, the switch must be meaningless.
The `ordering' field is used to temporarily mark switches that have to be
kept in a specific order. */

#define SWITCH_LIVE (1 << 0)
#define SWITCH_FALSE (1 << 1)
#define SWITCH_IGNORE (1 << 2)
#define SWITCH_IGNORE_PERMANENTLY (1 << 3)
#define SWITCH_KEEP_FOR_GCC (1 << 4)

struct switchstr
{
const char *part1;
const char **args;
unsigned int live_cond;
bool known;
bool validated;
bool ordering;
};

#endif

0 comments on commit 5ca9980

Please sign in to comment.