aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Frontend
diff options
context:
space:
mode:
authorDavid Truby <david.truby@arm.com>2024-07-03 18:49:42 +0100
committerGitHub <noreply@github.com>2024-07-03 18:49:42 +0100
commit9e6b46a9846cf5051c2aaef361af0fe1a76c856e (patch)
treea511c6b9dc1b2301d526e133f8b65f053c85b34a /flang/lib/Frontend
parent845dee36ba4161df153ba05009cea615e20eda5a (diff)
downloadllvm-9e6b46a9846cf5051c2aaef361af0fe1a76c856e.zip
llvm-9e6b46a9846cf5051c2aaef361af0fe1a76c856e.tar.gz
llvm-9e6b46a9846cf5051c2aaef361af0fe1a76c856e.tar.bz2
[flang] Implement -mcmodel flag (#95411)
This patch implements the -mcmodel flag from clang, allowing the Code Model to be changed for the LLVM module. The same set of mcmodel flags are accepted as in clang and the same Code Model attributes are added to the LLVM module for those flags. Also add `-mlarge-data-threshold` for x86-64, which is automatically set by the shared command-line code (see below). This is also added as an attribute into the LLVM module and on the target machine. A function is created for `addMCModel` that is copied out of clang's argument handling so that it can be shared with flang. --------- Co-authored-by: Mats Petersson <mats.petersson@arm.com>
Diffstat (limited to 'flang/lib/Frontend')
-rw-r--r--flang/lib/Frontend/CodeGenOptions.cpp11
-rw-r--r--flang/lib/Frontend/CompilerInstance.cpp10
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp24
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp12
4 files changed, 56 insertions, 1 deletions
diff --git a/flang/lib/Frontend/CodeGenOptions.cpp b/flang/lib/Frontend/CodeGenOptions.cpp
index a794718..8a9d3c2 100644
--- a/flang/lib/Frontend/CodeGenOptions.cpp
+++ b/flang/lib/Frontend/CodeGenOptions.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Frontend/CodeGenOptions.h"
+#include <optional>
#include <string.h>
namespace Fortran::frontend {
@@ -21,4 +22,14 @@ CodeGenOptions::CodeGenOptions() {
#include "flang/Frontend/CodeGenOptions.def"
}
+std::optional<llvm::CodeModel::Model> getCodeModel(llvm::StringRef string) {
+ return llvm::StringSwitch<std::optional<llvm::CodeModel::Model>>(string)
+ .Case("tiny", llvm::CodeModel::Model::Tiny)
+ .Case("small", llvm::CodeModel::Model::Small)
+ .Case("kernel", llvm::CodeModel::Model::Kernel)
+ .Case("medium", llvm::CodeModel::Model::Medium)
+ .Case("large", llvm::CodeModel::Model::Large)
+ .Default(std::nullopt);
+}
+
} // end namespace Fortran::frontend
diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp
index c781373..27c36b7 100644
--- a/flang/lib/Frontend/CompilerInstance.cpp
+++ b/flang/lib/Frontend/CompilerInstance.cpp
@@ -321,11 +321,19 @@ bool CompilerInstance::setUpTargetMachine() {
assert(OptLevelOrNone && "Invalid optimization level!");
llvm::CodeGenOptLevel OptLevel = *OptLevelOrNone;
std::string featuresStr = getTargetFeatures();
+ std::optional<llvm::CodeModel::Model> cm = getCodeModel(CGOpts.CodeModel);
targetMachine.reset(theTarget->createTargetMachine(
theTriple, /*CPU=*/targetOpts.cpu,
/*Features=*/featuresStr, llvm::TargetOptions(),
/*Reloc::Model=*/CGOpts.getRelocationModel(),
- /*CodeModel::Model=*/std::nullopt, OptLevel));
+ /*CodeModel::Model=*/cm, OptLevel));
assert(targetMachine && "Failed to create TargetMachine");
+ if (cm.has_value()) {
+ const llvm::Triple triple(theTriple);
+ if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) &&
+ triple.getArch() == llvm::Triple::x86_64) {
+ targetMachine->setLargeDataThreshold(CGOpts.LargeDataThreshold);
+ }
+ }
return true;
}
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index f96d72f..e2d60ad 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -32,6 +32,7 @@
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
@@ -386,6 +387,29 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.IsPIE = 1;
}
+ // -mcmodel option.
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_mcmodel_EQ)) {
+ llvm::StringRef modelName = a->getValue();
+ std::optional<llvm::CodeModel::Model> codeModel = getCodeModel(modelName);
+
+ if (codeModel.has_value())
+ opts.CodeModel = modelName;
+ else
+ diags.Report(clang::diag::err_drv_invalid_value)
+ << a->getAsString(args) << modelName;
+ }
+
+ if (const llvm::opt::Arg *arg = args.getLastArg(
+ clang::driver::options::OPT_mlarge_data_threshold_EQ)) {
+ uint64_t LDT;
+ if (llvm::StringRef(arg->getValue()).getAsInteger(/*Radix=*/10, LDT)) {
+ diags.Report(clang::diag::err_drv_invalid_value)
+ << arg->getSpelling() << arg->getValue();
+ }
+ opts.LargeDataThreshold = LDT;
+ }
+
// This option is compatible with -f[no-]underscoring in gfortran.
if (args.hasFlag(clang::driver::options::OPT_fno_underscoring,
clang::driver::options::OPT_funderscoring, false)) {
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 24db4df..a85ecd1 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -866,6 +866,17 @@ void CodeGenAction::generateLLVMIR() {
llvmModule->setPIELevel(
static_cast<llvm::PIELevel::Level>(opts.PICLevel));
}
+
+ // Set mcmodel level LLVM module flags
+ std::optional<llvm::CodeModel::Model> cm = getCodeModel(opts.CodeModel);
+ if (cm.has_value()) {
+ const llvm::Triple triple(ci.getInvocation().getTargetOpts().triple);
+ llvmModule->setCodeModel(*cm);
+ if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) &&
+ triple.getArch() == llvm::Triple::x86_64) {
+ llvmModule->setLargeDataThreshold(opts.LargeDataThreshold);
+ }
+ }
}
static std::unique_ptr<llvm::raw_pwrite_stream>
@@ -1280,6 +1291,7 @@ void CodeGenAction::executeAction() {
// and the command-line target option if specified, or the default if not
// given on the command-line).
llvm::TargetMachine &targetMachine = ci.getTargetMachine();
+
const std::string &theTriple = targetMachine.getTargetTriple().str();
if (llvmModule->getTargetTriple() != theTriple) {