Index: gold/gold-plugin.cpp =================================================================== --- gold/gold-plugin.cpp +++ gold/gold-plugin.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringSwitch.h" #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/CodeGen/CommandFlags.h" @@ -20,6 +21,7 @@ #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/LTO/Caching.h" #include "llvm/LTO/LTO.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -132,6 +134,7 @@ static std::string extra_library_path; static std::string triple; static std::string mcpu; + static std::string code_model; // When the thinlto plugin option is specified, only read the function // the information from intermediate files and write a combined // global index for the ThinLTO backends. @@ -181,6 +184,8 @@ if (opt.startswith("mcpu=")) { mcpu = opt.substr(strlen("mcpu=")); + } else if (opt.startswith("code-model=")) { + code_model = opt.substr(strlen("code-model=")); } else if (opt.startswith("extra-library-path=")) { extra_library_path = opt.substr(strlen("extra_library_path=")); } else if (opt.startswith("mtriple=")) { @@ -664,6 +669,19 @@ llvm_unreachable("Invalid optimization level"); } +static CodeModel::Model getCodeModel(std::string CodeModel) { + unsigned CM = + llvm::StringSwitch(CodeModel) + .Case("small", llvm::CodeModel::Small) + .Case("kernel", llvm::CodeModel::Kernel) + .Case("medium", llvm::CodeModel::Medium) + .Case("large", llvm::CodeModel::Large) + .Case("default", llvm::CodeModel::Default) + .Default(~0u); + assert(CodeModel != ~0u && "invalid code model!"); + return static_cast(CM); +} + /// Parse the thinlto_prefix_replace option into the \p OldPrefix and /// \p NewPrefix strings, if it was specified. static void getThinLTOOldAndNewPrefix(std::string &OldPrefix, @@ -688,6 +706,8 @@ Conf.MAttrs = MAttrs; Conf.RelocModel = *RelocationModel; + if (!options::code_model.empty()) + Conf.CodeModel = getCodeModel(options::code_model); Conf.CGOptLevel = getCGOptLevel(); Conf.DisableVerify = options::DisableVerify; Conf.OptLevel = options::OptLevel; Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -13,6 +13,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/ELF.h" #include @@ -147,6 +148,7 @@ Target2Policy Target2 = Target2Policy::GotRel; BuildIdKind BuildId = BuildIdKind::None; ELFKind EKind = ELFNoneKind; + llvm::CodeModel::Model CModel = llvm::CodeModel::Default; uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t ErrorLimit = 20; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -569,6 +569,23 @@ if (Config->ThinLTOJobs == 0) error("--thinlto-jobs: number of threads must be > 0"); + if (auto *Arg = Args.getLastArg(OPT_code_model_eq)) { + StringRef S = Arg->getValue(); + if (S == "default") { + Config->CModel = CodeModel::Default; + } else if (S == "small") { + Config->CModel = CodeModel::Small; + } else if (S == "kernel") { + Config->CModel = CodeModel::Kernel; + } else if (S == "medium") { + Config->CModel = CodeModel::Medium; + } else if (S == "large") { + Config->CModel = CodeModel::Large; + } else { + error("unknown code model: " + S); + } + } + Config->ZCombreloc = !hasZOption(Args, "nocombreloc"); Config->ZExecstack = hasZOption(Args, "execstack"); Config->ZNodelete = hasZOption(Args, "nodelete"); Index: lld/ELF/LTO.cpp =================================================================== --- lld/ELF/LTO.cpp +++ lld/ELF/LTO.cpp @@ -73,6 +73,7 @@ Conf.Options.RelaxELFRelocations = true; Conf.RelocModel = Config->Pic ? Reloc::PIC_ : Reloc::Static; + Conf.CodeModel = Config->CModel; Conf.DisableVerify = Config->DisableVerify; Conf.DiagHandler = diagnosticHandler; Conf.OptLevel = Config->LTOO; Index: lld/ELF/Options.td =================================================================== --- lld/ELF/Options.td +++ lld/ELF/Options.td @@ -383,3 +383,4 @@ def mllvm: S<"mllvm">; def save_temps: F<"save-temps">; def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; +def code_model_eq: J<"code-model=">; Index: lld/test/ELF/code-model.s =================================================================== --- /dev/null +++ lld/test/ELF/code-model.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: ld.lld %t -code-model=default -o %t2 +# RUN: ld.lld %t -code-model=small -o %t2 +# RUN: ld.lld %t -code-model=kernel -o %t2 +# RUN: ld.lld %t -code-model=medium -o %t2 +# RUN: ld.lld %t -code-model=large -o %t2 + +# RUN: not ld.lld %t -code-model=bad_model -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=BAD_MODEL %s +# BAD_MODEL: error: unknown code model: bad_model + +.globl _start +_start: + mov $60, %rax + mov $37, %rdi + syscall +