[clang] [RISCV][RFC] BareMetal multilibs YAML usage (PR #75191)

Emil J via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 12 06:29:16 PST 2023


https://github.com/ekliptik created https://github.com/llvm/llvm-project/pull/75191

This is an initial, minimal change to get a viable embedded toolchain build for RV32. Add the 7th of December LLVM RISC-V call, it was discussed that merging the functionalities of the RISC-V toolchain driver into BareMetal is desired. I don't know what the set of requirements for a "RISC-V toolchain" are. I'm guessing it's for [this repo](https://github.com/riscv-collab/riscv-gnu-toolchain) and requires GCC to be built as well. **The goal of this PR** then is not to replace RISCVToolchain.cpp but to start the search for an easier, more ordinary way to get a RISC-V toolchain, while we build it downstream and try to stay synchronized. It is a messy experiment and not intended to be merged as-is.

Originally, I copied the `addMultilibFlag` from `clang/lib/Driver/ToolChains/Fuchsia.cpp` for consistency. However, it looked like the limitations of YAML are already showing themselves, since it seemed to fail to match even string quote escaped exclamation mark. More experimentation is needed for that discussion. Instead, I simplified to have a single `+no-except` feature flag (with no complement flag) which allowed me to follow the except/noexcept suggested multilib layering approach at `clang/docs/Multilib.rst`, with noexcept-specific matches are later in the file, and therefore of higher priority.

Tagging in yaml mechanism contributors @mplatings @petrhosek, RISC-V code owner @asb, and colleagues @andcarminati @agostonrobert

References:
[The YAML RFC](https://discourse.llvm.org/t/rfc-multilib/67494/28) 
[Related ARM toolchain exception multilib PR](https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/pull/367)

>From eecc1d1bdcf7aa587dda5335ce8c1fcfbe2ddb6b Mon Sep 17 00:00:00 2001
From: Emil Tywoniak <Emil.Tywoniak at hightec-rt.com>
Date: Tue, 12 Dec 2023 13:57:29 +0000
Subject: [PATCH] [RISCV] BareMetal multilibs YAML usage RFC

---
 clang/lib/Driver/ToolChain.cpp            | 29 +++++++++++++++++++++++
 clang/lib/Driver/ToolChains/BareMetal.cpp | 19 +++++----------
 clang/test/Driver/baremetal-multilib.yaml | 12 ++++++++++
 3 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index ab19166f18c2dc..c0f97f1dd38bcb 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -9,6 +9,7 @@
 #include "clang/Driver/ToolChain.h"
 #include "ToolChains/Arch/AArch64.h"
 #include "ToolChains/Arch/ARM.h"
+#include "ToolChains/Arch/RISCV.h"
 #include "ToolChains/Clang.h"
 #include "ToolChains/CommonArgs.h"
 #include "ToolChains/Flang.h"
@@ -240,6 +241,30 @@ static void getARMMultilibFlags(const Driver &D,
   }
 }
 
+
+static void getRISCVMultilibFlags(const Driver &D,
+                                      const llvm::Triple &Triple,
+                                      const llvm::opt::ArgList &Args,
+                                      Multilib::flags_list &Result) {
+  std::vector<StringRef> Features;
+  tools::riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
+  const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
+  llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
+                                       UnifiedFeatures.end());
+  llvm::dbgs() << "Getting RISCV multilib flags!\n";
+  // std::vector<std::string> MArch;
+  for (const auto &F : UnifiedFeatures)
+    Result.push_back(F.str());
+
+  Result.push_back(("-march=" + Triple.getArchName()).str());
+
+  bool Exceptions =
+      Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true);
+  if (!Exceptions)
+    Result.push_back("+no-except");
+}
+
+
 Multilib::flags_list
 ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
   using namespace clang::driver::options;
@@ -260,6 +285,10 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
   case llvm::Triple::thumbeb:
     getARMMultilibFlags(D, Triple, Args, Result);
     break;
+  case llvm::Triple::riscv32:
+  case llvm::Triple::riscv64:
+    getRISCVMultilibFlags(D, Triple, Args, Result);
+    break;
   default:
     break;
   }
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 42c8336e626c7b..7f922778fdd823 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -33,7 +33,7 @@ using namespace clang::driver;
 using namespace clang::driver::tools;
 using namespace clang::driver::toolchains;
 
-static bool findRISCVMultilibs(const Driver &D,
+[[maybe_unused]] static bool findRISCVMultilibs(const Driver &D,
                                const llvm::Triple &TargetTriple,
                                const ArgList &Args, DetectedMultilibs &Result) {
   Multilib::flags_list Flags;
@@ -220,18 +220,11 @@ static std::string computeBaseSysRoot(const Driver &D,
 void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
                               const ArgList &Args) {
   DetectedMultilibs Result;
-  if (isRISCVBareMetal(Triple)) {
-    if (findRISCVMultilibs(D, Triple, Args, Result)) {
-      SelectedMultilibs = Result.SelectedMultilibs;
-      Multilibs = Result.Multilibs;
-    }
-  } else {
-    llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
-    llvm::sys::path::append(MultilibPath, MultilibFilename);
-    findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
-    SelectedMultilibs = Result.SelectedMultilibs;
-    Multilibs = Result.Multilibs;
-  }
+  llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
+  llvm::sys::path::append(MultilibPath, MultilibFilename);
+  findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
+  SelectedMultilibs = Result.SelectedMultilibs;
+  Multilibs = Result.Multilibs;
 }
 
 bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
diff --git a/clang/test/Driver/baremetal-multilib.yaml b/clang/test/Driver/baremetal-multilib.yaml
index af26e82621c91e..92bd434b45601d 100644
--- a/clang/test/Driver/baremetal-multilib.yaml
+++ b/clang/test/Driver/baremetal-multilib.yaml
@@ -119,6 +119,18 @@ Variants:
   Flags: [--target=thumbv8.1m.main-none-unknown-eabihf, -march=thumbv8.1m.main+mve, -mfpu=none]
 
 
+- Dir: rv32imafc/except
+  Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +c]
+- Dir: rv32imafc/noexcept
+  Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +c, +no-except]
+
+- Dir: rv32imafdc/except
+  Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +d, +c]
+- Dir: rv32imafdc/noexcept
+  Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +d, +c, +no-except]
+
+
+
 # The second section of the file is a map from auto-detected flags
 # to custom flags. The auto-detected flags can be printed out
 # by running clang with `-print-multi-flags-experimental`.



More information about the cfe-commits mailing list