aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Frontend
diff options
context:
space:
mode:
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) {