public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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
>

  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).