aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorTom Eccles <tom.eccles@arm.com>2023-11-13 10:04:50 +0000
committerGitHub <noreply@github.com>2023-11-13 10:04:50 +0000
commita207e6307a589d482fd11c1aac17507c6eabc802 (patch)
tree7e43a5318da175a334bde09077f6ef1f072b7375 /flang
parent4cc791bc98e075879f8c379f17e0b0369d57a40d (diff)
downloadllvm-a207e6307a589d482fd11c1aac17507c6eabc802.zip
llvm-a207e6307a589d482fd11c1aac17507c6eabc802.tar.gz
llvm-a207e6307a589d482fd11c1aac17507c6eabc802.tar.bz2
[flang] add fveclib flag (#71734)
-fveclib= allows users to choose a vectorized libm so that loops containing math functions are 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.
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Frontend/CodeGenOptions.def1
-rw-r--r--flang/include/flang/Frontend/CodeGenOptions.h1
-rw-r--r--flang/lib/Frontend/CMakeLists.txt1
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp29
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp16
-rw-r--r--flang/test/Driver/driver-help-hidden.f901
-rw-r--r--flang/test/Driver/driver-help.f902
-rw-r--r--flang/test/Driver/fveclib-codegen.f9015
-rw-r--r--flang/test/Driver/fveclib.f9030
9 files changed, 92 insertions, 4 deletions
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 1e35086..72e7bda 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, 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 b0e0c91..a3c39bd 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"
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index a06b610..1eba37f4 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 3fef377..334da3a 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 = llvm::driver::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
@@ -1116,6 +1144,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 73c00c8..d7ca7b6 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -850,11 +850,13 @@ getOutputStream(CompilerInstance &ci, llvm::StringRef inFile,
/// \param [in] tm Target machine to aid the code-gen pipeline set-up
/// \param [in] act Backend act to run (assembly vs machine-code generation)
/// \param [in] llvmModule LLVM module to lower to assembly/machine-code
+/// \param [in] codeGenOpts options configuring codegen pipeline
/// \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,
+ const CodeGenOptions &codeGenOpts,
llvm::raw_pwrite_stream &os) {
assert(((act == BackendActionTy::Backend_EmitObj) ||
(act == BackendActionTy::Backend_EmitAssembly)) &&
@@ -868,9 +870,8 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
createTargetTransformInfoWrapperPass(tm.getTargetIRAnalysis()));
llvm::Triple triple(llvmModule.getTargetTriple());
- std::unique_ptr<llvm::TargetLibraryInfoImpl> tlii =
- std::make_unique<llvm::TargetLibraryInfoImpl>(triple);
- assert(tlii && "Failed to create TargetLibraryInfo");
+ llvm::TargetLibraryInfoImpl *tlii =
+ llvm::driver::createTLII(triple, codeGenOpts.getVecLib());
codeGenPasses.add(new llvm::TargetLibraryInfoWrapperPass(*tlii));
llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly)
@@ -923,6 +924,13 @@ 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());
+ llvm::TargetLibraryInfoImpl *tlii =
+ llvm::driver::createTLII(triple, opts.getVecLib());
+ fam.registerPass([&] { return llvm::TargetLibraryAnalysis(*tlii); });
+
// Register all the basic analyses with the managers.
pb.registerModuleAnalyses(mam);
pb.registerCGSCCAnalyses(cgam);
@@ -1227,7 +1235,7 @@ void CodeGenAction::executeAction() {
if (action == BackendActionTy::Backend_EmitAssembly ||
action == BackendActionTy::Backend_EmitObj) {
generateMachineCodeOrAssemblyImpl(
- diags, *tm, action, *llvmModule,
+ diags, *tm, action, *llvmModule, codeGenOpts,
ci.isOutputStreamNull() ? *os : ci.getOutputStream());
return;
}
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index bd04ffa..b276f19 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -102,6 +102,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 2f81ec2..ea9c892 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -88,6 +88,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.
@@ -222,6 +223,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 0000000..8d7d3af1
--- /dev/null
+++ b/flang/test/Driver/fveclib-codegen.f90
@@ -0,0 +1,15 @@
+! test that -fveclib= is passed to the backend
+! -target aarch64 so that ArmPL is available
+! RUN: %flang -S -Ofast -fveclib=LIBMVEC -o - %s | FileCheck %s
+! RUN: %flang -S -Ofast -fveclib=NoLibrary -o - %s | FileCheck %s --check-prefix=NOLIB
+
+subroutine sb(a, b)
+ real :: a(:), b(:)
+ integer :: i
+ do i=1,100
+! check that we used a vectorized call to powf()
+! CHECK: _ZGVbN4vv_powf
+! NOLIB: powf
+ 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 0000000..898c65b
--- /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