Create a new hook to let target could override the multi-lib-os result.

The motivation for this change arises from the fact that using
TARGET_COMPUTE_MULTILIB to override the original multilib_dir can lead
to unexpected behavior with multilib_os_dir.

In our build scripts, we establish a connection between multilib_os_dir
and multilib_dir. For example, in gcc/config/riscv/t-linux, we set
multilib_os_dir to be the parent directory of multilib_dir. However,
when TARGET_COMPUTE_MULTILIB overrides multilib_dir and returns a reused
result for multilib_dir, multilib_os_dir ends up being identical to
multilib_dir. This discrepancy is clearly inconsistent with our
expectations.

gcc/ChangeLog:

        * common/common-target.def (compute_multilib_os): New.
        * common/common-targhooks.cc (default_compute_multilib_os): New.
        * common/common-targhooks.h (default_compute_multilib_os): New.
        * doc/tm.texi (TARGET_COMPUTE_MULTILIB_OS): New.
        * doc/tm.texi.in: Regen.
        * gcc.cc (set_multilib_dir): Call targetm_common.compute_multilib_os.
---
 gcc/common/common-target.def   | 14 ++++++++++++++
 gcc/common/common-targhooks.cc |  9 +++++++++
 gcc/common/common-targhooks.h  |  5 +++++
 gcc/doc/tm.texi                | 10 ++++++++++
 gcc/doc/tm.texi.in             |  1 +
 gcc/gcc.cc                     |  4 ++++
 6 files changed, 43 insertions(+)

diff --git a/gcc/common/common-target.def b/gcc/common/common-target.def
index 08d8a6aeb85..a582320b3a2 100644
--- a/gcc/common/common-target.def
+++ b/gcc/common/common-target.def
@@ -109,6 +109,20 @@ The default definition does nothing but return 
@var{multilib_dir} directly.",
                const char *multilib_reuse),
  default_compute_multilib)
 
+ DEFHOOK
+(compute_multilib_os,
+ "Some targets like RISC-V might have complicated multilib os dir which\n\
+needs to change it according to the value of multilib_dir.  This hook allows\n\
+targets to override the result from the built-in multilib mechanism.\n\
+@var{multilib_os_dir} is the os dirnames for multi-lib, which will override\n\
+the result of MULTILIB_OSDIRNAMES.\n\
+@var{multilib_dir} is the multi-lib result which is computed by the built-in\n\
+multi-lib mechanism.\n\
+The default definition does nothing but return @var{multilib_os_dir} 
directly.",
+ const char *, (const char *multilib_os_dir,
+               const char *multilib_dir),
+ default_compute_multilib_os)
+
 /* Leave the boolean fields at the end.  */
 
 /* True if unwinding tables should be generated by default.  */
diff --git a/gcc/common/common-targhooks.cc b/gcc/common/common-targhooks.cc
index 91a788d6927..343daccb398 100644
--- a/gcc/common/common-targhooks.cc
+++ b/gcc/common/common-targhooks.cc
@@ -105,3 +105,12 @@ default_compute_multilib(
 {
   return multilib;
 }
+
+/* Default version of TARGET_COMPUTE_MULTILIB_OS.  */
+const char *
+default_compute_multilib_os (
+  const char *multilib_os,
+  const char *)
+{
+  return multilib_os;
+}
\ No newline at end of file
diff --git a/gcc/common/common-targhooks.h b/gcc/common/common-targhooks.h
index 1366d1c4ef6..c645035e999 100644
--- a/gcc/common/common-targhooks.h
+++ b/gcc/common/common-targhooks.h
@@ -43,4 +43,9 @@ default_compute_multilib(
   const char *,
   const char *);
 
+const char *
+default_compute_multilib_os (
+  const char *multilib_os,
+  const char *);
+
 #endif
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 9f42913a4ef..04462055212 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -803,6 +803,16 @@ and @var{MULTILIB_REUSE}.
 The default definition does nothing but return @var{multilib_dir} directly.
 @end deftypefn
 
+@deftypefn {Common Target Hook} {const char *} TARGET_COMPUTE_MULTILIB_OS 
(const char *@var{multilib_os_dir}, const char *@var{multilib_dir})
+Some targets like RISC-V might have complicated multilib os dir which
+needs to change it according to the value of multilib_dir.  This hook allows
+targets to override the result from the built-in multilib mechanism.
+@var{multilib_os_dir} is the os dirnames for multi-lib, which will override
+the result of MULTILIB_OSDIRNAMES.
+@var{multilib_dir} is the multi-lib result which is computed by the built-in
+multi-lib mechanism.
+The default definition does nothing but return @var{multilib_os_dir} directly.
+@end deftypefn
 
 @defmac SWITCHABLE_TARGET
 Some targets need to switch between substantially different subtargets
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 6dbe22581ca..8d95a71a6c8 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -747,6 +747,7 @@ options are changed via @code{#pragma GCC optimize} or by 
using the
 
 @hook TARGET_COMPUTE_MULTILIB
 
+@hook TARGET_COMPUTE_MULTILIB_OS
 
 @defmac SWITCHABLE_TARGET
 Some targets need to switch between substantially different subtargets
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 04b3736a5da..645a1e34cbc 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -10007,6 +10007,10 @@ set_multilib_dir (void)
       multilib_exclusions,
       multilib_reuse);
 
+  multilib_os_dir = targetm_common.compute_multilib_os (
+    multilib_os_dir,
+    multilib_dir);
+
   if (multilib_dir == NULL && multilib_os_dir != NULL
       && strcmp (multilib_os_dir, ".") == 0)
     {
-- 
2.25.1

Reply via email to