From: Kito Cheng <kito.cheng@gmail.com>
To: Kito Cheng <kito.cheng@sifive.com>
Cc: gcc-patches@gcc.gnu.org, palmer@dabbelt.com, jeffreyalaw@gmail.com
Subject: Re: [PATCH v2] RISC-V: Handle multi-lib path correclty for linux
Date: Mon, 8 May 2023 15:03:18 +0800 [thread overview]
Message-ID: <CA+yXCZCjvADVJd6d4bBx7fVTsZbMygXEWzhPtNJ=r3ZaBkQS9Q@mail.gmail.com> (raw)
In-Reply-To: <20230504080130.24217-1-kito.cheng@sifive.com>
Committed to trunk
On Thu, May 4, 2023 at 4:03 PM Kito Cheng via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> RISC-V Linux encodes the ABI into the path, so in theory, we can only use that
> to select multi-lib paths, and no way to use different multi-lib paths between
> `rv32i/ilp32` and `rv32ima/ilp32`, we'll mapping both to `/lib/ilp32`.
>
> It's hard to do that with GCC's builtin multi-lib selection mechanism; builtin
> mechanism did the option string compare and then enumerate all possible reuse
> rules during the build time. However, it's impossible to RISC-V; we have a huge
> number of combinations of `-march`, so implementing a customized multi-lib
> selection becomes the only solution.
>
> Multi-lib configuration is only used for determines which ISA should be used
> when compiling the corresponding ABI variant after this patch.
>
> During the multi-lib selection stage, only consider -mabi as the only key to
> select the multi-lib path.
>
> gcc/ChangeLog:
>
> * common/config/riscv/riscv-common.cc (riscv_select_multilib_by_abi): New.
> (riscv_select_multilib): New.
> (riscv_compute_multilib): Extract logic to riscv_select_multilib and
> also handle select_by_abi.
> * config/riscv/elf.h (RISCV_USE_CUSTOMISED_MULTI_LIB): Change it
> to select_by_abi_arch_cmodel from 1.
> * config/riscv/linux.h (RISCV_USE_CUSTOMISED_MULTI_LIB): Define.
> * config/riscv/riscv-opts.h (enum riscv_multilib_select_kind): New.
>
> ---
> V2 Changes:
> - Fix some trivial issue cause I forgot to squash patches...
>
> This patch also plan backport to GCC 13 after landing to trunk.
>
> ---
> gcc/common/config/riscv/riscv-common.cc | 128 ++++++++++++++++--------
> gcc/config/riscv/elf.h | 2 +-
> gcc/config/riscv/linux.h | 2 +
> gcc/config/riscv/riscv-opts.h | 9 ++
> 4 files changed, 100 insertions(+), 41 deletions(-)
>
> diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
> index 309a52def75f..57a2a279ef53 100644
> --- a/gcc/common/config/riscv/riscv-common.cc
> +++ b/gcc/common/config/riscv/riscv-common.cc
> @@ -1441,9 +1441,6 @@ riscv_multi_lib_check (int argc ATTRIBUTE_UNUSED,
> return "";
> }
>
> -/* We only override this in bare-metal toolchain. */
> -#ifdef RISCV_USE_CUSTOMISED_MULTI_LIB
> -
> /* Find last switch with the prefix, options are take last one in general,
> return NULL if not found, and return the option value if found, it could
> return empty string if the option has no value. */
> @@ -1597,6 +1594,68 @@ riscv_check_conds (
> return match_score + ok_count * 100;
> }
>
> +static const char *
> +riscv_select_multilib_by_abi (
> + const std::string &riscv_current_arch_str,
> + const std::string &riscv_current_abi_str,
> + const riscv_subset_list *subset_list, const struct switchstr *switches,
> + int n_switches, const std::vector<riscv_multi_lib_info_t> &multilib_infos)
> +{
> + for (size_t i = 0; i < multilib_infos.size (); ++i)
> + if (riscv_current_abi_str == multilib_infos[i].abi_str)
> + return xstrdup (multilib_infos[i].path.c_str ());
> +
> + return NULL;
> +}
> +
> +static const char *
> +riscv_select_multilib (
> + const std::string &riscv_current_arch_str,
> + const std::string &riscv_current_abi_str,
> + const riscv_subset_list *subset_list, const struct switchstr *switches,
> + int n_switches, const std::vector<riscv_multi_lib_info_t> &multilib_infos)
> +{
> + int match_score = 0;
> + int max_match_score = 0;
> + int best_match_multi_lib = -1;
> + /* Try to decision which set we should used. */
> + /* We have 3 level decision tree here, ABI, check input arch/ABI must
> + be superset of multi-lib arch, and other rest option checking. */
> + for (size_t i = 0; i < multilib_infos.size (); ++i)
> + {
> + /* Check ABI is same first. */
> + if (riscv_current_abi_str != multilib_infos[i].abi_str)
> + continue;
> +
> + /* Found a potential compatible multi-lib setting!
> + Calculate the match score. */
> + match_score = subset_list->match_score (multilib_infos[i].subset_list);
> +
> + /* Checking other cond in the multi-lib setting. */
> + match_score = riscv_check_conds (switches, n_switches, match_score,
> + multilib_infos[i].conds);
> +
> + /* Record highest match score multi-lib setting. */
> + if (match_score > max_match_score)
> + {
> + best_match_multi_lib = i;
> + max_match_score = match_score;
> + }
> + }
> +
> + if (best_match_multi_lib == -1)
> + {
> + riscv_no_matched_multi_lib = true;
> + return NULL;
> + }
> + else
> + return xstrdup (multilib_infos[best_match_multi_lib].path.c_str ());
> +}
> +
> +#ifndef RISCV_USE_CUSTOMISED_MULTI_LIB
> +#define RISCV_USE_CUSTOMISED_MULTI_LIB select_by_builtin
> +#endif
> +
> /* Implement TARGET_COMPUTE_MULTILIB. */
> static const char *
> riscv_compute_multilib (
> @@ -1609,6 +1668,11 @@ riscv_compute_multilib (
> const char *multilib_exclusions ATTRIBUTE_UNUSED,
> const char *multilib_reuse ATTRIBUTE_UNUSED)
> {
> + enum riscv_multilib_select_kind select_kind = RISCV_USE_CUSTOMISED_MULTI_LIB;
> +
> + if (select_kind == select_by_builtin)
> + return multilib_dir;
> +
> const char *p;
> const char *this_path;
> size_t this_path_len;
> @@ -1672,7 +1736,13 @@ riscv_compute_multilib (
> }
>
> this_path_len = p - this_path;
> - multilib_info.path = std::string (this_path, this_path_len);
> + const char *multi_os_dir_pos
> + = (const char *) memchr (this_path, ':', this_path_len);
> + if (multi_os_dir_pos)
> + multilib_info.path
> + = std::string (this_path, multi_os_dir_pos - this_path);
> + else
> + multilib_info.path = std::string (this_path, this_path_len);
>
> option_conds.clear ();
> /* Pasrse option check list into vector<string>.
> @@ -1707,48 +1777,26 @@ riscv_compute_multilib (
> p++;
> }
>
> - int match_score = 0;
> - int max_match_score = 0;
> - int best_match_multi_lib = -1;
> - /* Try to decision which set we should used. */
> - /* We have 3 level decision tree here, ABI, check input arch/ABI must
> - be superset of multi-lib arch, and other rest option checking. */
> - for (size_t i = 0; i < multilib_infos.size (); ++i)
> + switch (select_kind)
> {
> - /* Check ABI is same first. */
> - if (riscv_current_abi_str != multilib_infos[i].abi_str)
> - continue;
> -
> - /* Found a potential compatible multi-lib setting!
> - Calculate the match score. */
> - match_score = subset_list->match_score (multilib_infos[i].subset_list);
> -
> - /* Checking other cond in the multi-lib setting. */
> - match_score = riscv_check_conds (switches,
> - n_switches,
> - match_score,
> - multilib_infos[i].conds);
> -
> - /* Record highest match score multi-lib setting. */
> - if (match_score > max_match_score)
> - {
> - best_match_multi_lib = i;
> - max_match_score = match_score;
> - }
> - }
> -
> - if (best_match_multi_lib == -1)
> - {
> - riscv_no_matched_multi_lib = true;
> - return multilib_dir;
> + case select_by_abi:
> + return riscv_select_multilib (riscv_current_arch_str,
> + riscv_current_abi_str, subset_list,
> + switches, n_switches, multilib_infos);
> + case select_by_abi_arch_cmodel:
> + return riscv_select_multilib_by_abi (riscv_current_arch_str,
> + riscv_current_abi_str, subset_list,
> + switches, n_switches,
> + multilib_infos);
> + case select_by_builtin:
> + gcc_unreachable ();
> + default:
> + gcc_unreachable ();
> }
> - else
> - return xstrdup (multilib_infos[best_match_multi_lib].path.c_str ());
> }
>
> #undef TARGET_COMPUTE_MULTILIB
> #define TARGET_COMPUTE_MULTILIB riscv_compute_multilib
> -#endif
>
> vec<const char *>
> riscv_get_valid_option_values (int option_code,
> diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
> index a725c00b6373..4b7e5c988ca2 100644
> --- a/gcc/config/riscv/elf.h
> +++ b/gcc/config/riscv/elf.h
> @@ -37,4 +37,4 @@ along with GCC; see the file COPYING3. If not see
> #undef ENDFILE_SPEC
> #define ENDFILE_SPEC "crtend%O%s"
>
> -#define RISCV_USE_CUSTOMISED_MULTI_LIB 1
> +#define RISCV_USE_CUSTOMISED_MULTI_LIB select_by_abi_arch_cmodel
> diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
> index 2fdfd930cf2d..3e625e0f8676 100644
> --- a/gcc/config/riscv/linux.h
> +++ b/gcc/config/riscv/linux.h
> @@ -66,3 +66,5 @@ along with GCC; see the file COPYING3. If not see
> "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ " \
> "/lib/ " \
> "/usr/lib/ "
> +
> +#define RISCV_USE_CUSTOMISED_MULTI_LIB select_by_abi
> diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
> index 4207db240ea0..1b2e6de5e1b1 100644
> --- a/gcc/config/riscv/riscv-opts.h
> +++ b/gcc/config/riscv/riscv-opts.h
> @@ -82,6 +82,15 @@ enum riscv_autovec_lmul_enum {
> RVV_M8 = 8
> };
>
> +enum riscv_multilib_select_kind {
> + /* Select multilib by builtin way. */
> + select_by_builtin,
> + /* Select multilib by ABI, arch and code model. */
> + select_by_abi_arch_cmodel,
> + /* Select multilib by ABI only. */
> + select_by_abi,
> +};
> +
> #define MASK_ZICSR (1 << 0)
> #define MASK_ZIFENCEI (1 << 1)
>
> --
> 2.39.2
>
next prev parent reply other threads:[~2023-05-08 7:03 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-04 8:01 Kito Cheng
2023-05-08 7:03 ` Kito Cheng [this message]
2023-05-12 8:36 ` Andreas Schwab
2023-05-12 8:59 ` Kito Cheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CA+yXCZCjvADVJd6d4bBx7fVTsZbMygXEWzhPtNJ=r3ZaBkQS9Q@mail.gmail.com' \
--to=kito.cheng@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jeffreyalaw@gmail.com \
--cc=kito.cheng@sifive.com \
--cc=palmer@dabbelt.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).