diff options
Diffstat (limited to 'flang/lib')
-rw-r--r-- | flang/lib/Frontend/CodeGenOptions.cpp | 11 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInstance.cpp | 10 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 24 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 12 |
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) { |