Skip to content

[Multilib] Add -fmultilib-flag command-line option #110658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 13, 2025

Conversation

vhscampos
Copy link
Member

@vhscampos vhscampos commented Oct 1, 2024

This patch is the second step to extend the current multilib system to support the selection of library variants which do not correspond to existing command-line options.

Proposal can be found in https://discourse.llvm.org/t/rfc-multilib-custom-flags/81058

The multilib mechanism supports libraries that target code generation or language options such as --target, -mcpu, -mfpu, -mbranch-protection. However, some library variants are particular to features that do not correspond to any command-line options. Examples include variants for multithreading and semihosting.

This work introduces a way to instruct the multilib system to consider these features in library selection.

The driver must be informed about the multilib custom flags with a new command-line option.

-fmultilib-flag=C

Where the grammar for C is:

C -> option
option -> multithreaded | no-multithreaded | io-none | io-semihosting | io-linux-syscalls | ...

There must be one option instance for each flag specified:

-fmultilib-flag=multithreaded -fmultilib-flag=io-semihosting

Contradictory options are untied by last one wins.

These options are to be used exclusively by the multilib mechanism in the Clang driver. Hence they are not forwarded to the compiler frontend. On the other hand,

@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-cmd-line-option branch from 3e06d0b to 0020798 Compare October 1, 2024 13:30
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-yaml-parsing branch from 0944b25 to e194bda Compare October 24, 2024 09:13
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-cmd-line-option branch from 0020798 to 829fad5 Compare October 24, 2024 09:15
@vhscampos vhscampos marked this pull request as ready for review October 24, 2024 09:17
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Oct 24, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 24, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Victor Campos (vhscampos)

Changes

This option is passed through to the multilib system. It is then used in conjunction with other options to select the proper library variant.

Details about this change can be found in this thread: https://discourse.llvm.org/t/rfc-multilib-custom-flags/81058


Full diff: https://github.com/llvm/llvm-project/pull/110658.diff

3 Files Affected:

  • (modified) clang/include/clang/Driver/Options.td (+2)
  • (modified) clang/lib/Driver/ToolChain.cpp (+14)
  • (modified) clang/test/Driver/print-multi-selection-flags.c (+7)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0cb7c0c0ae04f7..1fff1fa3edd052 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5684,6 +5684,8 @@ def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
 def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
 def print_multi_flags : Flag<["-", "--"], "print-multi-flags-experimental">,
   HelpText<"Print the flags used for selecting multilibs (experimental)">;
+def fmultilib_flag : Joined<["-", "--"], "fmultilib-flag=">,
+  Visibility<[ClangOption]>;
 def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
   Flags<[Unsupported]>;
 def print_target_triple : Flag<["-", "--"], "print-target-triple">,
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 4df31770950858..19f5f59897eda2 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -196,6 +196,16 @@ bool ToolChain::defaultToIEEELongDouble() const {
   return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
 }
 
+static void
+processARMAArch64MultilibCustomFlags(Multilib::flags_list &List,
+                                     const llvm::opt::ArgList &Args) {
+  for (const Arg *MultilibFlagArg :
+       Args.filtered(options::OPT_fmultilib_flag)) {
+    List.push_back(MultilibFlagArg->getAsString(Args));
+    MultilibFlagArg->claim();
+  }
+}
+
 static void getAArch64MultilibFlags(const Driver &D,
                                           const llvm::Triple &Triple,
                                           const llvm::opt::ArgList &Args,
@@ -232,6 +242,8 @@ static void getAArch64MultilibFlags(const Driver &D,
   if (ABIArg) {
     Result.push_back(ABIArg->getAsString(Args));
   }
+
+  processARMAArch64MultilibCustomFlags(Result, Args);
 }
 
 static void getARMMultilibFlags(const Driver &D,
@@ -285,6 +297,8 @@ static void getARMMultilibFlags(const Driver &D,
   if (BranchProtectionArg) {
     Result.push_back(BranchProtectionArg->getAsString(Args));
   }
+
+  processARMAArch64MultilibCustomFlags(Result, Args);
 }
 
 static void getRISCVMultilibFlags(const Driver &D, const llvm::Triple &Triple,
diff --git a/clang/test/Driver/print-multi-selection-flags.c b/clang/test/Driver/print-multi-selection-flags.c
index 4bb62665ad8981..6bf50cd0976a6b 100644
--- a/clang/test/Driver/print-multi-selection-flags.c
+++ b/clang/test/Driver/print-multi-selection-flags.c
@@ -82,3 +82,10 @@
 // CHECK-RV32E-ORDER: --target=riscv32-unknown-none-elf
 // CHECK-RV32E-ORDER: -mabi=ilp32e
 // CHECK-RV32E-ORDER: -march=rv32e{{[0-9]+p[0-9]+}}_c{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}
+
+// RUN: %clang -print-multi-flags-experimental --target=armv8m.main-none-eabi -fmultilib-flag=foo -fmultilib-flag=bar | FileCheck --check-prefixes=CHECK-MULTILIB-CUSTOM-FLAG,CHECK-ARM-MULTILIB-CUSTOM-FLAG %s
+// RUN: %clang -print-multi-flags-experimental --target=aarch64-none-eabi     -fmultilib-flag=foo -fmultilib-flag=bar | FileCheck --check-prefixes=CHECK-MULTILIB-CUSTOM-FLAG,CHECK-AARCH64-MULTILIB-CUSTOM-FLAG %s
+// CHECK-ARM-MULTILIB-CUSTOM-FLAG:     --target=thumbv8m.main-unknown-none-eabi
+// CHECK-AARCH64-MULTILIB-CUSTOM-FLAG: --target=aarch64-unknown-none-eabi
+// CHECK-MULTILIB-CUSTOM-FLAG-DAG:     -fmultilib-flag=foo
+// CHECK-MULTILIB-CUSTOM-FLAG-DAG:     -fmultilib-flag=bar

@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-cmd-line-option branch from 829fad5 to ee2d268 Compare November 4, 2024 13:52
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-yaml-parsing branch from dd45234 to 4c9756a Compare November 20, 2024 14:46
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-cmd-line-option branch from ee2d268 to 7b8f0d9 Compare November 20, 2024 14:47
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-cmd-line-option branch from 7b8f0d9 to c0bb75d Compare December 10, 2024 12:52
This patch adds support for custom flags in the multilib YAML file.

Details about this change can be found in:
https://discourse.llvm.org/t/rfc-multilib-custom-flags/81058

CustomFlagDeclaration objects are instantiated using shared_ptr. This is
motivated by the fact that each custom flag value,
CustomFlagValueDetail, contains a back reference to their corresponding
flag declaration.

Since the CustomFlagDeclaration objects are transferred from the YAML
parser to the MultilibSet instance after the parsing is finished, back
references implemented as raw pointers would become dangling. This would
need to be remediated in the copy/move constructors by updating the
pointer.

Therefore it's just simpler and less error-prone to have all references
to CustomFlagDeclaration, including the back reference, as shared_ptr.
This way dangling pointers are not a concern.
We've decided to restrict the driver arguments that can be specified to
only macro definitions. Hence this patch adjusts the YAML parsing for
that.
This option is passed through to the multilib system. It is then used in
conjunction with other options to select the proper library variant.

Details about this change can be found in this thread:
https://discourse.llvm.org/t/rfc-multilib-custom-flags/81058
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-yaml-parsing branch from 96e089e to 42c7ca1 Compare December 11, 2024 13:30
@vhscampos vhscampos force-pushed the users/vhscampos/multilib-flags-cmd-line-option branch from c0bb75d to 17265b1 Compare December 11, 2024 13:30
Base automatically changed from users/vhscampos/multilib-flags-yaml-parsing to main January 13, 2025 13:51
@vhscampos vhscampos merged commit 2a551ab into main Jan 13, 2025
8 checks passed
@vhscampos vhscampos deleted the users/vhscampos/multilib-flags-cmd-line-option branch January 13, 2025 13:53
kazutakahirata pushed a commit to kazutakahirata/llvm-project that referenced this pull request Jan 13, 2025
This patch is the second step to extend the current multilib system to
support the selection of library variants which do not correspond to
existing command-line options.

Proposal can be found in
https://discourse.llvm.org/t/rfc-multilib-custom-flags/81058

The multilib mechanism supports libraries that target code generation or
language options such as --target, -mcpu, -mfpu, -mbranch-protection.
However, some library variants are particular to features that do not
correspond to any command-line options. Examples include variants for
multithreading and semihosting.

This work introduces a way to instruct the multilib system to consider
these features in library selection.

The driver must be informed about the multilib custom flags with a new
command-line option.
```
-fmultilib-flag=C
```
Where the grammar for C is:
```
C -> option
option -> multithreaded | no-multithreaded | io-none | io-semihosting | io-linux-syscalls | ...
```
There must be one option instance for each flag specified:
```
-fmultilib-flag=multithreaded -fmultilib-flag=io-semihosting
```
Contradictory options are untied by *last one wins*.

These options are to be used exclusively by the multilib mechanism in
the Clang driver. Hence they are not forwarded to the compiler frontend.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants