[llvm] [flang] [clang] [flang] add fveclib flag (PR #71734)

Tom Eccles via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 10 02:45:27 PST 2023


https://github.com/tblah updated https://github.com/llvm/llvm-project/pull/71734

>From ac9c18ef7d286147fd1ae4a49efe343644d2ccd1 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Tue, 7 Nov 2023 18:55:20 +0000
Subject: [PATCH 1/2] [flang] add fveclib flag

-fveclib= allows users to choose a vectorized libm so that loops
containing math functions can be vectorized.

This is implemented as much as possible in the same way as in clang.
The driver test in veclib.f90 is copied from the clang test.
---
 clang/include/clang/Driver/Options.td         |  2 +-
 clang/lib/Driver/ToolChains/Flang.cpp         | 34 +++++++++++
 .../include/flang/Frontend/CodeGenOptions.def |  1 +
 flang/include/flang/Frontend/CodeGenOptions.h | 11 ++++
 flang/lib/Frontend/CompilerInvocation.cpp     | 29 ++++++++++
 flang/lib/Frontend/FrontendActions.cpp        | 58 ++++++++++++++++---
 flang/test/Driver/driver-help-hidden.f90      |  1 +
 flang/test/Driver/driver-help.f90             |  2 +
 flang/test/Driver/fveclib-codegen.f90         | 13 +++++
 flang/test/Driver/fveclib.f90                 | 30 ++++++++++
 10 files changed, 172 insertions(+), 9 deletions(-)
 create mode 100644 flang/test/Driver/fveclib-codegen.f90
 create mode 100644 flang/test/Driver/fveclib.f90

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 36052511203f65c..f275ec68e710769 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3118,7 +3118,7 @@ def fno_global_isel : Flag<["-"], "fno-global-isel">, Group<f_clang_Group>,
 def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_Group>,
   Alias<fno_global_isel>;
 def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>,
-  Visibility<[ClangOption, CC1Option]>,
+  Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
     HelpText<"Use the given vector functions library">,
     Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,none">,
     NormalizedValuesScope<"CodeGenOptions">,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 999039f83ddfb92..b5ebbc4ef37e1db 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -232,6 +232,40 @@ void Flang::addTargetOptions(const ArgList &Args,
     break;
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {
+    StringRef Name = A->getValue();
+    if (Name == "SVML") {
+      if (Triple.getArch() != llvm::Triple::x86 &&
+          Triple.getArch() != llvm::Triple::x86_64)
+        D.Diag(diag::err_drv_unsupported_opt_for_target)
+            << Name << Triple.getArchName();
+    } else if (Name == "LIBMVEC-X86") {
+      if (Triple.getArch() != llvm::Triple::x86 &&
+          Triple.getArch() != llvm::Triple::x86_64)
+        D.Diag(diag::err_drv_unsupported_opt_for_target)
+            << Name << Triple.getArchName();
+    } else if (Name == "SLEEF" || Name == "ArmPL") {
+      if (Triple.getArch() != llvm::Triple::aarch64 &&
+          Triple.getArch() != llvm::Triple::aarch64_be)
+        D.Diag(diag::err_drv_unsupported_opt_for_target)
+            << Name << Triple.getArchName();
+    }
+
+    if (Triple.isOSDarwin()) {
+      // flang doesn't currently suport nostdlib, nodefaultlibs. Adding these
+      // here incase they are added someday
+      if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+        if (A->getValue() == StringRef{"Accelerate"}) {
+          CmdArgs.push_back("-framework");
+          CmdArgs.push_back("Accelerate");
+          A->render(Args, CmdArgs);
+        }
+      }
+    } else {
+      A->render(Args, CmdArgs);
+    }
+  }
+
   // TODO: Add target specific flags, ABI, mtune option etc.
 }
 
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 1e350869f1377e3..9d09ac1cbb251b1 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -37,6 +37,7 @@ CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis pass
 CODEGENOPT(Underscoring, 1, 1)
 ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
 ENUM_CODEGENOPT(DebugInfo,  llvm::codegenoptions::DebugInfoKind, 4,  llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate
+ENUM_CODEGENOPT(VecLib, VectorLibrary, 3, VectorLibrary::NoLibrary) ///< Vector functions library to use
 
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index b0e0c91e09ab38f..1eb2264560a02fa 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -81,6 +81,17 @@ class CodeGenOptions : public CodeGenOptionsBase {
     RK_WithPattern, // Remark pattern specified via '-Rgroup=regexp'.
   };
 
+  enum class VectorLibrary {
+    NoLibrary,  // Don't use any vector library.
+    Accelerate, // Use the Accelerate framework.
+    LIBMVEC,    // GLIBC vector math library.
+    MASSV,      // IBM MASS vector library.
+    SVML,       // Intel short vector math library.
+    SLEEF,      // SLEEF SIMD Library for Evaluating Elementary Functions.
+    Darwin_libsystem_m, // Use Darwin's libsystem_m vector functions.
+    ArmPL               // Arm Performance Libraries.
+  };
+
   /// Optimization remark with an optional regular expression pattern.
   struct OptRemark {
     RemarkKind Kind = RemarkKind::RK_Missing;
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index ba2ecab3742587a..299694f72dfd864 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -153,6 +153,34 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
   return true;
 }
 
+static bool parseVectorLibArg(Fortran::frontend::CodeGenOptions &opts,
+                              llvm::opt::ArgList &args,
+                              clang::DiagnosticsEngine &diags) {
+  llvm::opt::Arg *arg = args.getLastArg(clang::driver::options::OPT_fveclib);
+  if (!arg)
+    return true;
+
+  using VectorLibrary = Fortran::frontend::CodeGenOptions::VectorLibrary;
+  std::optional<VectorLibrary> val =
+      llvm::StringSwitch<std::optional<VectorLibrary>>(arg->getValue())
+          .Case("Accelerate", VectorLibrary::Accelerate)
+          .Case("LIBMVEC", VectorLibrary::LIBMVEC)
+          .Case("MASSV", VectorLibrary::MASSV)
+          .Case("SVML", VectorLibrary::SVML)
+          .Case("SLEEF", VectorLibrary::SLEEF)
+          .Case("Darwin_libsystem_m", VectorLibrary::Darwin_libsystem_m)
+          .Case("ArmPL", VectorLibrary::ArmPL)
+          .Case("NoLibrary", VectorLibrary::NoLibrary)
+          .Default(std::nullopt);
+  if (!val.has_value()) {
+    diags.Report(clang::diag::err_drv_invalid_value)
+        << arg->getAsString(args) << arg->getValue();
+    return false;
+  }
+  opts.setVecLib(val.value());
+  return true;
+}
+
 // Generate an OptRemark object containing info on if the -Rgroup
 // specified is enabled or not.
 static CodeGenOptions::OptRemark
@@ -1103,6 +1131,7 @@ bool CompilerInvocation::createFromArgs(
   parsePreprocessorArgs(res.getPreprocessorOpts(), args);
   parseCodeGenArgs(res.getCodeGenOpts(), args, diags);
   success &= parseDebugArgs(res.getCodeGenOpts(), args, diags);
+  success &= parseVectorLibArg(res.getCodeGenOpts(), args, diags);
   success &= parseSemaArgs(res, args, diags);
   success &= parseDialectArgs(res, args, diags);
   success &= parseDiagArgs(res, args, diags);
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 73c00c8679c7ec6..7a25fb37a96d9b3 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -843,6 +843,44 @@ getOutputStream(CompilerInstance &ci, llvm::StringRef inFile,
   llvm_unreachable("Invalid action!");
 }
 
+static std::unique_ptr<llvm::TargetLibraryInfoImpl>
+createTLII(llvm::Triple &targetTriple, const CodeGenOptions &codeGenOpts) {
+  auto tlii = std::make_unique<llvm::TargetLibraryInfoImpl>(targetTriple);
+  assert(tlii && "Failed to create TargetLibraryInfo");
+
+  using VecLib = llvm::TargetLibraryInfoImpl::VectorLibrary;
+  VecLib vecLib = VecLib::NoLibrary;
+  switch (codeGenOpts.getVecLib()) {
+  case CodeGenOptions::VectorLibrary::Accelerate:
+    vecLib = VecLib::Accelerate;
+    break;
+  case CodeGenOptions::VectorLibrary::LIBMVEC:
+    vecLib = VecLib::LIBMVEC_X86;
+    break;
+  case CodeGenOptions::VectorLibrary::MASSV:
+    vecLib = VecLib::MASSV;
+    break;
+  case CodeGenOptions::VectorLibrary::SVML:
+    vecLib = VecLib::SVML;
+    break;
+  case CodeGenOptions::VectorLibrary::SLEEF:
+    vecLib = VecLib::SLEEFGNUABI;
+    break;
+  case CodeGenOptions::VectorLibrary::Darwin_libsystem_m:
+    vecLib = VecLib::DarwinLibSystemM;
+    break;
+  case CodeGenOptions::VectorLibrary::ArmPL:
+    vecLib = VecLib::ArmPL;
+    break;
+  case CodeGenOptions::VectorLibrary::NoLibrary:
+    vecLib = VecLib::NoLibrary;
+    break;
+  }
+
+  tlii->addVectorizableFunctionsFromVecLib(vecLib, targetTriple);
+  return tlii;
+}
+
 /// Generate target-specific machine-code or assembly file from the input LLVM
 /// module.
 ///
@@ -851,11 +889,10 @@ getOutputStream(CompilerInstance &ci, llvm::StringRef inFile,
 /// \param [in] act Backend act to run (assembly vs machine-code generation)
 /// \param [in] llvmModule LLVM module to lower to assembly/machine-code
 /// \param [out] os Output stream to emit the generated code to
-static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
-                                              llvm::TargetMachine &tm,
-                                              BackendActionTy act,
-                                              llvm::Module &llvmModule,
-                                              llvm::raw_pwrite_stream &os) {
+static void generateMachineCodeOrAssemblyImpl(
+    clang::DiagnosticsEngine &diags, llvm::TargetMachine &tm,
+    BackendActionTy act, llvm::Module &llvmModule, llvm::raw_pwrite_stream &os,
+    const CodeGenOptions &codeGenOpts) {
   assert(((act == BackendActionTy::Backend_EmitObj) ||
           (act == BackendActionTy::Backend_EmitAssembly)) &&
          "Unsupported action");
@@ -869,8 +906,7 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
 
   llvm::Triple triple(llvmModule.getTargetTriple());
   std::unique_ptr<llvm::TargetLibraryInfoImpl> tlii =
-      std::make_unique<llvm::TargetLibraryInfoImpl>(triple);
-  assert(tlii && "Failed to create TargetLibraryInfo");
+      createTLII(triple, codeGenOpts);
   codeGenPasses.add(new llvm::TargetLibraryInfoWrapperPass(*tlii));
 
   llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly)
@@ -923,6 +959,12 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(pb);
 #include "llvm/Support/Extension.def"
 
+  // Register the target library analysis directly and give it a customized
+  // preset TLI depending on -fveclib
+  llvm::Triple triple(llvmModule->getTargetTriple());
+  std::unique_ptr<llvm::TargetLibraryInfoImpl> tlii = createTLII(triple, opts);
+  fam.registerPass([&] { return llvm::TargetLibraryAnalysis(*tlii); });
+
   // Register all the basic analyses with the managers.
   pb.registerModuleAnalyses(mam);
   pb.registerCGSCCAnalyses(cgam);
@@ -1228,7 +1270,7 @@ void CodeGenAction::executeAction() {
       action == BackendActionTy::Backend_EmitObj) {
     generateMachineCodeOrAssemblyImpl(
         diags, *tm, action, *llvmModule,
-        ci.isOutputStreamNull() ? *os : ci.getOutputStream());
+        ci.isOutputStreamNull() ? *os : ci.getOutputStream(), codeGenOpts);
     return;
   }
 }
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index 6d399f1d179a022..54a2ff03462d1ab 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -98,6 +98,7 @@
 ! CHECK-NEXT: -fstack-arrays          Attempt to allocate array temporaries on the stack, no matter their size
 ! CHECK-NEXT: -fsyntax-only           Run the preprocessor, parser and semantic analysis stages
 ! CHECK-NEXT: -funderscoring          Appends one trailing underscore to external names
+! CHECK-NEXT: -fveclib=<value>        Use the given vector functions library
 ! CHECK-NEXT: -fversion-loops-for-stride
 ! CHECK-NEXT:                         Create unit-strided versions of loops
 ! CHECK-NEXT: -fxor-operator          Enable .XOR. as a synonym of .NEQV.
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 31c9caa32ea8292..db6347aa1c628a8 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -86,6 +86,7 @@
 ! HELP-NEXT: -fstack-arrays          Attempt to allocate array temporaries on the stack, no matter their size
 ! HELP-NEXT: -fsyntax-only           Run the preprocessor, parser and semantic analysis stages
 ! HELP-NEXT: -funderscoring          Appends one trailing underscore to external names
+! HELP-NEXT: -fveclib=<value>        Use the given vector functions library
 ! HELP-NEXT: -fversion-loops-for-stride
 ! HELP-NEXT:                         Create unit-strided versions of loops
 ! HELP-NEXT: -fxor-operator          Enable .XOR. as a synonym of .NEQV.
@@ -220,6 +221,7 @@
 ! HELP-FC1-NEXT: -fstack-arrays          Attempt to allocate array temporaries on the stack, no matter their size
 ! HELP-FC1-NEXT: -fsyntax-only           Run the preprocessor, parser and semantic analysis stages
 ! HELP-FC1-NEXT: -funderscoring          Appends one trailing underscore to external names
+! HELP-FC1-NEXT: -fveclib=<value>        Use the given vector functions library
 ! HELP-FC1-NEXT: -fversion-loops-for-stride
 ! HELP-FC1-NEXT:                         Create unit-strided versions of loops
 ! HELP-FC1-NEXT: -fxor-operator          Enable .XOR. as a synonym of .NEQV.
diff --git a/flang/test/Driver/fveclib-codegen.f90 b/flang/test/Driver/fveclib-codegen.f90
new file mode 100644
index 000000000000000..e5f362aab1b6105
--- /dev/null
+++ b/flang/test/Driver/fveclib-codegen.f90
@@ -0,0 +1,13 @@
+! test that -fveclib= is passed to the backend
+! -target aarch64 so that ArmPL is available
+! RUN: %flang -S -target aarch64-unknown-linux-gnu -mcpu=neoverse-v1 -Ofast -fveclib=ArmPL -o - %s | FileCheck %s
+
+subroutine sb(a, b)
+  real :: a(:), b(:)
+  integer :: i
+  do i=1,100
+! check that we used a vectorized call to powf()
+! CHECK: armpl_svpow_f32_x
+    a(i) = a(i) ** b(i)
+  end do
+end subroutine
diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90
new file mode 100644
index 000000000000000..898c65b0c850aff
--- /dev/null
+++ b/flang/test/Driver/fveclib.f90
@@ -0,0 +1,30 @@
+! RUN: %flang -### -c -fveclib=none %s 2>&1 | FileCheck -check-prefix CHECK-NOLIB %s
+! RUN: %flang -### -c -fveclib=Accelerate %s 2>&1 | FileCheck -check-prefix CHECK-ACCELERATE %s
+! RUN: %flang -### -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-libmvec %s
+! RUN: %flang -### -c -fveclib=MASSV %s 2>&1 | FileCheck -check-prefix CHECK-MASSV %s
+! RUN: %flang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck -check-prefix CHECK-DARWIN_LIBSYSTEM_M %s
+! RUN: %flang -### -c --target=aarch64-none-none -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-SLEEF %s
+! RUN: %flang -### -c --target=aarch64-none-none -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ARMPL %s
+! RUN: not %flang -c -fveclib=something %s 2>&1 | FileCheck -check-prefix CHECK-INVALID %s
+
+! CHECK-NOLIB: "-fveclib=none"
+! CHECK-ACCELERATE: "-fveclib=Accelerate"
+! CHECK-libmvec: "-fveclib=libmvec"
+! CHECK-MASSV: "-fveclib=MASSV"
+! CHECK-DARWIN_LIBSYSTEM_M: "-fveclib=Darwin_libsystem_m"
+! CHECK-SLEEF: "-fveclib=SLEEF"
+! CHECK-ARMPL: "-fveclib=ArmPL"
+
+! CHECK-INVALID: error: invalid value 'something' in '-fveclib=something'
+
+! RUN: not %flang --target=x86-none-none -c -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=x86-none-none -c -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=aarch64-none-none -c -fveclib=LIBMVEC-X86 %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! RUN: not %flang --target=aarch64-none-none -c -fveclib=SVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s
+! CHECK-ERROR: unsupported option {{.*}} for target
+
+! RUN: %flang -fveclib=Accelerate %s -target arm64-apple-ios8.0.0 -### 2>&1 | FileCheck --check-prefix=CHECK-LINK %s
+! CHECK-LINK: "-framework" "Accelerate"
+
+! TODO: if we add support for -nostdlib or -nodefaultlibs we need to test that
+! these prevent "-framework Accelerate" being added on Darwin

>From 09ed9d42991cbf85e331444a801ac25c653c6b89 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 9 Nov 2023 16:21:17 +0000
Subject: [PATCH 2/2] Move common code to llvm/Frontend/Driver

---
 clang/include/clang/Basic/CodeGenOptions.def  |  2 +-
 clang/include/clang/Basic/CodeGenOptions.h    | 12 +---
 clang/include/clang/Driver/Options.td         |  2 +-
 clang/lib/CodeGen/BackendUtil.cpp             | 46 ++--------------
 clang/lib/CodeGen/CMakeLists.txt              |  1 +
 .../lib/Tooling/DumpTool/ClangSrcLocDump.cpp  |  6 +-
 .../include/flang/Frontend/CodeGenOptions.def |  2 +-
 flang/include/flang/Frontend/CodeGenOptions.h | 12 +---
 flang/lib/Frontend/CMakeLists.txt             |  1 +
 flang/lib/Frontend/CompilerInvocation.cpp     |  2 +-
 flang/lib/Frontend/FrontendActions.cpp        | 45 ++-------------
 .../llvm/Frontend/Driver/CodeGenOptions.h     | 40 ++++++++++++++
 llvm/lib/Frontend/CMakeLists.txt              |  1 +
 llvm/lib/Frontend/Driver/CMakeLists.txt       | 15 +++++
 llvm/lib/Frontend/Driver/CodeGenOptions.cpp   | 55 +++++++++++++++++++
 15 files changed, 130 insertions(+), 112 deletions(-)
 create mode 100644 llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
 create mode 100644 llvm/lib/Frontend/Driver/CMakeLists.txt
 create mode 100644 llvm/lib/Frontend/Driver/CodeGenOptions.cpp

diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 843559f202abe35..675645cd534ed76 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -426,7 +426,7 @@ ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
 VALUE_CODEGENOPT(InlineMaxStackSize, 32, UINT_MAX)
 
 // Vector functions library to use.
-ENUM_CODEGENOPT(VecLib, VectorLibrary, 3, NoLibrary)
+ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary)
 
 /// The default TLS model to use.
 ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index c8e2544f891cc2b..b202d01af0ed6ce 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -17,6 +17,7 @@
 #include "clang/Basic/XRayInstr.h"
 #include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/Frontend/Debug/Options.h"
+#include "llvm/Frontend/Driver/CodeGenOptions.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Target/TargetOptions.h"
@@ -58,17 +59,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
     OnlyAlwaysInlining  // Only run the always inlining pass.
   };
 
-  enum VectorLibrary {
-    NoLibrary,  // Don't use any vector library.
-    Accelerate, // Use the Accelerate framework.
-    LIBMVEC,    // GLIBC vector math library.
-    MASSV,      // IBM MASS vector library.
-    SVML,       // Intel short vector math library.
-    SLEEF,      // SLEEF SIMD Library for Evaluating Elementary Functions.
-    Darwin_libsystem_m, // Use Darwin's libsytem_m vector functions.
-    ArmPL               // Arm Performance Libraries.
-  };
-
   enum ObjCDispatchMethodKind {
     Legacy = 0,
     NonLegacy = 1,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index f275ec68e710769..6dcc78c17fa33f8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3121,7 +3121,7 @@ def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
     HelpText<"Use the given vector functions library">,
     Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,none">,
-    NormalizedValuesScope<"CodeGenOptions">,
+    NormalizedValuesScope<"llvm::driver::VectorLibrary">,
     NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF",
                       "Darwin_libsystem_m", "ArmPL", "NoLibrary"]>,
     MarshallingInfoEnum<CodeGenOpts<"VecLib">, "NoLibrary">;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 46c84da4c74a094..4a89d4422ea55c4 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -27,6 +27,7 @@
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Frontend/Driver/CodeGenOptions.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/LegacyPassManager.h"
@@ -55,6 +56,7 @@
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/HipStdPar/HipStdPar.h"
 #include "llvm/Transforms/IPO/EmbedBitcodePass.h"
 #include "llvm/Transforms/IPO/LowerTypeTests.h"
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
@@ -78,7 +80,6 @@
 #include "llvm/Transforms/Scalar/EarlyCSE.h"
 #include "llvm/Transforms/Scalar/GVN.h"
 #include "llvm/Transforms/Scalar/JumpThreading.h"
-#include "llvm/Transforms/HipStdPar/HipStdPar.h"
 #include "llvm/Transforms/Utils/Debugify.h"
 #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -258,45 +259,6 @@ static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
   return false;
 }
 
-static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
-                                         const CodeGenOptions &CodeGenOpts) {
-  TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
-
-  switch (CodeGenOpts.getVecLib()) {
-  case CodeGenOptions::Accelerate:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate,
-                                             TargetTriple);
-    break;
-  case CodeGenOptions::LIBMVEC:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::LIBMVEC_X86,
-                                             TargetTriple);
-    break;
-  case CodeGenOptions::MASSV:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV,
-                                             TargetTriple);
-    break;
-  case CodeGenOptions::SVML:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML,
-                                             TargetTriple);
-    break;
-  case CodeGenOptions::SLEEF:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SLEEFGNUABI,
-                                             TargetTriple);
-    break;
-  case CodeGenOptions::Darwin_libsystem_m:
-    TLII->addVectorizableFunctionsFromVecLib(
-        TargetLibraryInfoImpl::DarwinLibSystemM, TargetTriple);
-    break;
-  case CodeGenOptions::ArmPL:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::ArmPL,
-                                             TargetTriple);
-    break;
-  default:
-    break;
-  }
-  return TLII;
-}
-
 static std::optional<llvm::CodeModel::Model>
 getCodeModel(const CodeGenOptions &CodeGenOpts) {
   unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
@@ -584,7 +546,7 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
                                        raw_pwrite_stream *DwoOS) {
   // Add LibraryInfo.
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
-      createTLII(TargetTriple, CodeGenOpts));
+      llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
   CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
 
   // Normal mode, emit a .s or .o file by running the code generator. Note,
@@ -917,7 +879,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
   // Register the target library analysis directly and give it a customized
   // preset TLI.
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
-      createTLII(TargetTriple, CodeGenOpts));
+      llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
   // Register all the basic analyses with the managers.
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index da98848e3b44387..258ce868f3cfca2 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS
   Coverage
   Demangle
   Extensions
+  FrontendDriver
   FrontendHLSL
   FrontendOpenMP
   FrontendOffloading
diff --git a/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp b/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp
index f48fbb0f3c6ad62..1529bfa75d6d582 100644
--- a/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp
+++ b/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp
@@ -111,7 +111,7 @@ int main(int argc, const char **argv) {
 
   auto Files = llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions(), OFS);
 
-  auto Driver = std::make_unique<driver::Driver>(
+  auto Driver = std::make_unique<clang::driver::Driver>(
       "clang", llvm::sys::getDefaultTargetTriple(), Diagnostics,
       "ast-api-dump-tool", OFS);
 
@@ -121,14 +121,14 @@ int main(int argc, const char **argv) {
     return 1;
 
   const auto &Jobs = Comp->getJobs();
-  if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
+  if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
     SmallString<256> error_msg;
     llvm::raw_svector_ostream error_stream(error_msg);
     Jobs.Print(error_stream, "; ", true);
     return 1;
   }
 
-  const auto &Cmd = cast<driver::Command>(*Jobs.begin());
+  const auto &Cmd = cast<clang::driver::Command>(*Jobs.begin());
   const llvm::opt::ArgStringList &CC1Args = Cmd.getArguments();
 
   auto Invocation = std::make_unique<CompilerInvocation>();
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 9d09ac1cbb251b1..72e7bdab12a14da 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -37,7 +37,7 @@ CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis pass
 CODEGENOPT(Underscoring, 1, 1)
 ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
 ENUM_CODEGENOPT(DebugInfo,  llvm::codegenoptions::DebugInfoKind, 4,  llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate
-ENUM_CODEGENOPT(VecLib, VectorLibrary, 3, VectorLibrary::NoLibrary) ///< Vector functions library to use
+ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use
 
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 1eb2264560a02fa..a3c39bda10667be 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
 
 #include "llvm/Frontend/Debug/Options.h"
+#include "llvm/Frontend/Driver/CodeGenOptions.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Target/TargetOptions.h"
@@ -81,17 +82,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
     RK_WithPattern, // Remark pattern specified via '-Rgroup=regexp'.
   };
 
-  enum class VectorLibrary {
-    NoLibrary,  // Don't use any vector library.
-    Accelerate, // Use the Accelerate framework.
-    LIBMVEC,    // GLIBC vector math library.
-    MASSV,      // IBM MASS vector library.
-    SVML,       // Intel short vector math library.
-    SLEEF,      // SLEEF SIMD Library for Evaluating Elementary Functions.
-    Darwin_libsystem_m, // Use Darwin's libsystem_m vector functions.
-    ArmPL               // Arm Performance Libraries.
-  };
-
   /// Optimization remark with an optional regular expression pattern.
   struct OptRemark {
     RemarkKind Kind = RemarkKind::RK_Missing;
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index a06b610112f2090..1eba37f4573f6f4 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -52,6 +52,7 @@ add_flang_library(flangFrontend
   Support
   Target
   TargetParser
+  FrontendDriver
   FrontendOpenACC
   FrontendOpenMP
 
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 299694f72dfd864..75a3b5c62ab5324 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -160,7 +160,7 @@ static bool parseVectorLibArg(Fortran::frontend::CodeGenOptions &opts,
   if (!arg)
     return true;
 
-  using VectorLibrary = Fortran::frontend::CodeGenOptions::VectorLibrary;
+  using VectorLibrary = llvm::driver::VectorLibrary;
   std::optional<VectorLibrary> val =
       llvm::StringSwitch<std::optional<VectorLibrary>>(arg->getValue())
           .Case("Accelerate", VectorLibrary::Accelerate)
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 7a25fb37a96d9b3..9e018b44e02316d 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -843,44 +843,6 @@ getOutputStream(CompilerInstance &ci, llvm::StringRef inFile,
   llvm_unreachable("Invalid action!");
 }
 
-static std::unique_ptr<llvm::TargetLibraryInfoImpl>
-createTLII(llvm::Triple &targetTriple, const CodeGenOptions &codeGenOpts) {
-  auto tlii = std::make_unique<llvm::TargetLibraryInfoImpl>(targetTriple);
-  assert(tlii && "Failed to create TargetLibraryInfo");
-
-  using VecLib = llvm::TargetLibraryInfoImpl::VectorLibrary;
-  VecLib vecLib = VecLib::NoLibrary;
-  switch (codeGenOpts.getVecLib()) {
-  case CodeGenOptions::VectorLibrary::Accelerate:
-    vecLib = VecLib::Accelerate;
-    break;
-  case CodeGenOptions::VectorLibrary::LIBMVEC:
-    vecLib = VecLib::LIBMVEC_X86;
-    break;
-  case CodeGenOptions::VectorLibrary::MASSV:
-    vecLib = VecLib::MASSV;
-    break;
-  case CodeGenOptions::VectorLibrary::SVML:
-    vecLib = VecLib::SVML;
-    break;
-  case CodeGenOptions::VectorLibrary::SLEEF:
-    vecLib = VecLib::SLEEFGNUABI;
-    break;
-  case CodeGenOptions::VectorLibrary::Darwin_libsystem_m:
-    vecLib = VecLib::DarwinLibSystemM;
-    break;
-  case CodeGenOptions::VectorLibrary::ArmPL:
-    vecLib = VecLib::ArmPL;
-    break;
-  case CodeGenOptions::VectorLibrary::NoLibrary:
-    vecLib = VecLib::NoLibrary;
-    break;
-  }
-
-  tlii->addVectorizableFunctionsFromVecLib(vecLib, targetTriple);
-  return tlii;
-}
-
 /// Generate target-specific machine-code or assembly file from the input LLVM
 /// module.
 ///
@@ -905,8 +867,8 @@ static void generateMachineCodeOrAssemblyImpl(
       createTargetTransformInfoWrapperPass(tm.getTargetIRAnalysis()));
 
   llvm::Triple triple(llvmModule.getTargetTriple());
-  std::unique_ptr<llvm::TargetLibraryInfoImpl> tlii =
-      createTLII(triple, codeGenOpts);
+  llvm::TargetLibraryInfoImpl *tlii =
+      llvm::driver::createTLII(triple, codeGenOpts.getVecLib());
   codeGenPasses.add(new llvm::TargetLibraryInfoWrapperPass(*tlii));
 
   llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly)
@@ -962,7 +924,8 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   // Register the target library analysis directly and give it a customized
   // preset TLI depending on -fveclib
   llvm::Triple triple(llvmModule->getTargetTriple());
-  std::unique_ptr<llvm::TargetLibraryInfoImpl> tlii = createTLII(triple, opts);
+  llvm::TargetLibraryInfoImpl *tlii =
+      llvm::driver::createTLII(triple, opts.getVecLib());
   fam.registerPass([&] { return llvm::TargetLibraryAnalysis(*tlii); });
 
   // Register all the basic analyses with the managers.
diff --git a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
new file mode 100644
index 000000000000000..0b1d924a26b2de3
--- /dev/null
+++ b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h
@@ -0,0 +1,40 @@
+//===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines frontend codegen options common to clang and flang
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FRONTEND_DRIVER_CODEGENOPTIONS_H
+#define LLVM_FRONTEND_DRIVER_CODEGENOPTIONS_H
+
+namespace llvm {
+class Triple;
+class TargetLibraryInfoImpl;
+} // namespace llvm
+
+namespace llvm::driver {
+
+/// Vector library option used with -fveclib=
+enum class VectorLibrary {
+  NoLibrary,          // Don't use any vector library.
+  Accelerate,         // Use the Accelerate framework.
+  LIBMVEC,            // GLIBC vector math library.
+  MASSV,              // IBM MASS vector library.
+  SVML,               // Intel short vector math library.
+  SLEEF,              // SLEEF SIMD Library for Evaluating Elementary Functions.
+  Darwin_libsystem_m, // Use Darwin's libsystem_m vector functions.
+  ArmPL               // Arm Performance Libraries.
+};
+
+TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
+                                  VectorLibrary Veclib);
+
+} // end namespace llvm::driver
+
+#endif
diff --git a/llvm/lib/Frontend/CMakeLists.txt b/llvm/lib/Frontend/CMakeLists.txt
index 5ef092e0a1a9ede..62dd0da1e6c2deb 100644
--- a/llvm/lib/Frontend/CMakeLists.txt
+++ b/llvm/lib/Frontend/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(Driver)
 add_subdirectory(HLSL)
 add_subdirectory(OpenACC)
 add_subdirectory(OpenMP)
diff --git a/llvm/lib/Frontend/Driver/CMakeLists.txt b/llvm/lib/Frontend/Driver/CMakeLists.txt
new file mode 100644
index 000000000000000..23de4994a300d8e
--- /dev/null
+++ b/llvm/lib/Frontend/Driver/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_llvm_component_library(LLVMFrontendDriver
+  CodeGenOptions.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend/Driver
+
+  DEPENDS
+  LLVMAnalysis
+  LLVMTargetParser
+
+  LINK_COMPONENTS
+  Core
+  Support
+  Analysis
+  )
diff --git a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
new file mode 100644
index 000000000000000..96c5b19a4a59135
--- /dev/null
+++ b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp
@@ -0,0 +1,55 @@
+//===--- CodeGenOptions.cpp - Shared codegen option handling --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/Driver/CodeGenOptions.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace llvm::driver {
+
+TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
+                                  driver::VectorLibrary Veclib) {
+  TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
+
+  using VectorLibrary = llvm::driver::VectorLibrary;
+  switch (Veclib) {
+  case VectorLibrary::Accelerate:
+    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate,
+                                             TargetTriple);
+    break;
+  case VectorLibrary::LIBMVEC:
+    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::LIBMVEC_X86,
+                                             TargetTriple);
+    break;
+  case VectorLibrary::MASSV:
+    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV,
+                                             TargetTriple);
+    break;
+  case VectorLibrary::SVML:
+    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML,
+                                             TargetTriple);
+    break;
+  case VectorLibrary::SLEEF:
+    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SLEEFGNUABI,
+                                             TargetTriple);
+    break;
+  case VectorLibrary::Darwin_libsystem_m:
+    TLII->addVectorizableFunctionsFromVecLib(
+        TargetLibraryInfoImpl::DarwinLibSystemM, TargetTriple);
+    break;
+  case VectorLibrary::ArmPL:
+    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::ArmPL,
+                                             TargetTriple);
+    break;
+  default:
+    break;
+  }
+  return TLII;
+}
+
+} // namespace llvm::driver



More information about the cfe-commits mailing list