diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index b286ff359ec40..46d2f97807935 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -25,6 +25,7 @@ #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Config/llvm-config.h" #include "llvm/Frontend/Driver/CodeGenOptions.h" @@ -51,6 +52,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Program.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/Timer.h" #include "llvm/Support/ToolOutputFile.h" @@ -1351,7 +1353,10 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, assert(OptLevelOrNone && "Invalid optimization level!"); Conf.CGOptLevel = *OptLevelOrNone; Conf.OptLevel = CGOpts.OptimizationLevel; - initTargetOptions(CI, Diags, Conf.Options); + // llvm::codegen::RegisterCodeGenFlags F; + Conf.ModifyTargetOptions = [&](llvm::TargetOptions &TargetOpts) -> void { + initTargetOptions(CI, Diags, TargetOpts); + }; Conf.SampleProfile = std::move(SampleProfile); Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops; Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops; diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp index 3ebd4ea979322..f940951584fab 100644 --- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp +++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp @@ -358,8 +358,6 @@ Expected> createLTO(const ArgList &Args) { lto::createInProcessThinBackend(heavyweight_hardware_concurrency(Jobs)); Conf.CPU = Args.getLastArgValue(OPT_arch); - Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple); - Conf.RemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename, RemarksFilename); Conf.RemarksPasses = diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index d55f95493a85f..f0dfe47a1d4d5 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -46,16 +46,23 @@ std::string BitcodeCompiler::getThinLTOOutputFile(StringRef path) { lto::Config BitcodeCompiler::createConfig() { lto::Config c; - c.Options = initTargetOptionsFromCodeGenFlags(); - c.Options.EmitAddrsig = true; + bool emitAsm = ctx.config.emit == EmitKind::ASM; + c.ModifyTargetOptions = [emitAsm](TargetOptions &options) { + options.EmitAddrsig = true; + // Always emit a section per function/datum with LTO. LLVM LTO should get + // most of the benefit of linker GC, but there are still opportunities for + // ICF. + options.FunctionSections = true; + options.DataSections = true; + + if (emitAsm) { + options.MCOptions.AsmVerbose = true; + } + }; + for (StringRef C : ctx.config.mllvmOpts) c.MllvmArgs.emplace_back(C.str()); - // Always emit a section per function/datum with LTO. LLVM LTO should get most - // of the benefit of linker GC, but there are still opportunities for ICF. - c.Options.FunctionSections = true; - c.Options.DataSections = true; - // Use static reloc model on 32-bit x86 because it usually results in more // compact code, and because there are also known code generation bugs when // using the PIC model (see PR34306). @@ -95,7 +102,6 @@ lto::Config BitcodeCompiler::createConfig() { }; } else if (ctx.config.emit == EmitKind::ASM) { c.CGFileType = CodeGenFileType::AssemblyFile; - c.Options.MCOptions.AsmVerbose = true; } if (!ctx.config.saveTempsArgs.empty()) diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 6f916a501a262..692651a8506ca 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -46,47 +46,52 @@ static std::string getThinLTOOutputFile(Ctx &ctx, StringRef modulePath) { static lto::Config createConfig(Ctx &ctx) { lto::Config c; - // LLD supports the new relocations and address-significance tables. - c.Options = initTargetOptionsFromCodeGenFlags(); - c.Options.EmitAddrsig = true; - for (StringRef C : ctx.arg.mllvmOpts) - c.MllvmArgs.emplace_back(C.str()); - - // Always emit a section per function/datum with LTO. - c.Options.FunctionSections = true; - c.Options.DataSections = true; - - // Check if basic block sections must be used. - // Allowed values for --lto-basic-block-sections are "all", - // "", or none. This is the equivalent - // of -fbasic-block-sections= flag in clang. - if (!ctx.arg.ltoBasicBlockSections.empty()) { - if (ctx.arg.ltoBasicBlockSections == "all") { - c.Options.BBSections = BasicBlockSection::All; - } else if (ctx.arg.ltoBasicBlockSections == "labels") { - c.Options.BBAddrMap = true; - Warn(ctx) - << "'--lto-basic-block-sections=labels' is deprecated; Please use " - "'--lto-basic-block-address-map' instead"; - } else if (ctx.arg.ltoBasicBlockSections == "none") { - c.Options.BBSections = BasicBlockSection::None; - } else { - ErrorOr> MBOrErr = - MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str()); - if (!MBOrErr) { - ErrAlways(ctx) << "cannot open " << ctx.arg.ltoBasicBlockSections << ":" - << MBOrErr.getError().message(); + // Set up the callback to modify TargetOptions. + c.ModifyTargetOptions = [&](TargetOptions &Options) -> void { + // LLD supports the new relocations and address-significance tables. + Options.EmitAddrsig = true; + // Always emit a section per function/datum with LTO. + Options.FunctionSections = true; + Options.DataSections = true; + + // Check if basic block sections must be used. + // Allowed values for --lto-basic-block-sections are "all", + // "", or none. This is the + // equivalent of -fbasic-block-sections= flag in clang. + if (!ctx.arg.ltoBasicBlockSections.empty()) { + if (ctx.arg.ltoBasicBlockSections == "all") { + Options.BBSections = BasicBlockSection::All; + } else if (ctx.arg.ltoBasicBlockSections == "labels") { + Options.BBAddrMap = true; + Warn(ctx) + << "'--lto-basic-block-sections=labels' is deprecated; Please use " + "'--lto-basic-block-address-map' instead"; + } else if (ctx.arg.ltoBasicBlockSections == "none") { + Options.BBSections = BasicBlockSection::None; } else { - c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr); + ErrorOr> MBOrErr = + MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str()); + if (!MBOrErr) { + ErrAlways(ctx) << "cannot open " << ctx.arg.ltoBasicBlockSections + << ":" << MBOrErr.getError().message(); + } else { + Options.BBSectionsFuncListBuf = std::move(*MBOrErr); + } + Options.BBSections = BasicBlockSection::List; } - c.Options.BBSections = BasicBlockSection::List; } - } - c.Options.BBAddrMap = ctx.arg.ltoBBAddrMap; + Options.BBAddrMap = ctx.arg.ltoBBAddrMap; - c.Options.UniqueBasicBlockSectionNames = - ctx.arg.ltoUniqueBasicBlockSectionNames; + Options.UniqueBasicBlockSectionNames = + ctx.arg.ltoUniqueBasicBlockSectionNames; + if (ctx.arg.ltoEmitAsm) { + Options.MCOptions.AsmVerbose = true; + } + }; + + for (StringRef C : ctx.arg.mllvmOpts) + c.MllvmArgs.emplace_back(C.str()); if (auto relocModel = getRelocModelFromCMModel()) c.RelocModel = *relocModel; @@ -156,7 +161,7 @@ static lto::Config createConfig(Ctx &ctx) { if (ctx.arg.ltoEmitAsm) { c.CGFileType = CodeGenFileType::AssemblyFile; - c.Options.MCOptions.AsmVerbose = true; + // c.Options.MCOptions.AsmVerbose = true; } if (!ctx.arg.saveTempsArgs.empty()) diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp index 2c360374ef3cc..e25c63e1fce6b 100644 --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -38,8 +38,12 @@ static std::string getThinLTOOutputFile(StringRef modulePath) { static lto::Config createConfig() { lto::Config c; - c.Options = initTargetOptionsFromCodeGenFlags(); - c.Options.EmitAddrsig = config->icfLevel == ICFLevel::safe; + + bool emitAddrsig = config->icfLevel == ICFLevel::safe; + c.ModifyTargetOptions = [emitAddrsig](TargetOptions &options) { + options.EmitAddrsig = emitAddrsig; + }; + for (StringRef C : config->mllvmOpts) c.MllvmArgs.emplace_back(C.str()); for (StringRef pluginFn : config->passPlugins) diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 668cdf21ea3ed..f6f69e934a00a 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -42,11 +42,11 @@ static std::string getThinLTOOutputFile(StringRef modulePath) { static lto::Config createConfig() { lto::Config c; - c.Options = initTargetOptionsFromCodeGenFlags(); - - // Always emit a section per function/data with LTO. - c.Options.FunctionSections = true; - c.Options.DataSections = true; + c.ModifyTargetOptions = [&](TargetOptions &options) { + // Always emit a section per function/data with LTO. + options.FunctionSections = true; + options.DataSections = true; + }; c.DisableVerify = ctx.arg.disableVerify; c.DiagHandler = diagnosticHandler; diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index 566a87ed1a790..4af8b4af5f177 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -47,7 +47,9 @@ struct Config { // Note: when adding fields here, consider whether they need to be added to // computeLTOCacheKey in LTO.cpp. std::string CPU; - TargetOptions Options; + // Callback to modify the target options once they are instantiated. + std::function ModifyTargetOptions = + [](TargetOptions &) {}; std::vector MAttrs; std::vector MllvmArgs; std::vector PassPlugins; diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h index f992be9899e3d..fd91345cf548f 100644 --- a/llvm/include/llvm/LTO/LTO.h +++ b/llvm/include/llvm/LTO/LTO.h @@ -74,7 +74,7 @@ LLVM_ABI std::string computeLTOCacheKey( StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map &ResolvedODR, - const GVSummaryMapTy &DefinedGlobals, + const GVSummaryMapTy &DefinedGlobals, const Triple &TT, const DenseSet &CfiFunctionDefs = {}, const DenseSet &CfiFunctionDecls = {}); diff --git a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h index caff198358caa..117269c1b58a1 100644 --- a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h +++ b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -249,6 +249,7 @@ struct LTOCodeGenerator { std::string SaveIRBeforeOptPath; lto::Config Config; + llvm::TargetOptions TO; }; /// A convenience function that calls cl::ParseCommandLineOptions on the given diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index bbbdfcbd71f2b..f609a8a5a7a84 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -24,6 +24,7 @@ #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/CGData/CodeGenData.h" #include "llvm/CodeGen/Analysis.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/DiagnosticPrinter.h" @@ -106,7 +107,7 @@ std::string llvm::computeLTOCacheKey( const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map &ResolvedODR, - const GVSummaryMapTy &DefinedGlobals, + const GVSummaryMapTy &DefinedGlobals, const Triple &TT, const DenseSet &CfiFunctionDefs, const DenseSet &CfiFunctionDecls) { // Compute the unique hash for this entry. @@ -140,14 +141,17 @@ std::string llvm::computeLTOCacheKey( Hasher.update(ArrayRef(&I, 1)); }; AddString(Conf.CPU); + TargetOptions Opts = codegen::InitTargetOptionsFromCodeGenFlags(TT); + Conf.ModifyTargetOptions(Opts); + // FIXME: Hash more of Options. For now all clients initialize Options from // command-line flags (which is unsupported in production), but may set // X86RelaxRelocations. The clang driver can also pass FunctionSections, // DataSections and DebuggerTuning via command line flags. - AddUnsigned(Conf.Options.MCOptions.X86RelaxRelocations); - AddUnsigned(Conf.Options.FunctionSections); - AddUnsigned(Conf.Options.DataSections); - AddUnsigned((unsigned)Conf.Options.DebuggerTuning); + AddUnsigned(Opts.MCOptions.X86RelaxRelocations); + AddUnsigned(Opts.FunctionSections); + AddUnsigned(Opts.DataSections); + AddUnsigned((unsigned)Opts.DebuggerTuning); for (auto &A : Conf.MAttrs) AddString(A); if (Conf.RelocModel) @@ -1535,10 +1539,10 @@ class InProcessThinBackend : public CGThinBackend { const GVSummaryMapTy &DefinedGlobals, MapVector &ModuleMap) { auto ModuleID = BM.getModuleIdentifier(); + LTOLLVMContext BackendContext(Conf); llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (in-process)", ModuleID); auto RunThinBackend = [&](AddStreamFn AddStream) { - LTOLLVMContext BackendContext(Conf); Expected> MOrErr = BM.parseModule(BackendContext); if (!MOrErr) return MOrErr.takeError(); @@ -1559,10 +1563,15 @@ class InProcessThinBackend : public CGThinBackend { // no module hash. return RunThinBackend(AddStream); + auto Mod = ModuleMap.front().second.parseModule(BackendContext); + if (!Mod) + return Mod.takeError(); + Triple TT = (*Mod)->getTargetTriple(); + // The module may be cached, this helps handling it. std::string Key = computeLTOCacheKey( Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR, - DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls); + DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls); Expected CacheAddStreamOrErr = Cache(Task, Key, ModuleID); if (Error Err = CacheAddStreamOrErr.takeError()) return Err; @@ -1650,9 +1659,9 @@ class FirstRoundThinBackend : public InProcessThinBackend { auto ModuleID = BM.getModuleIdentifier(); llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)", ModuleID); + LTOLLVMContext BackendContext(Conf); auto RunThinBackend = [&](AddStreamFn CGAddStream, AddStreamFn IRAddStream) { - LTOLLVMContext BackendContext(Conf); Expected> MOrErr = BM.parseModule(BackendContext); if (!MOrErr) return MOrErr.takeError(); @@ -1678,10 +1687,15 @@ class FirstRoundThinBackend : public InProcessThinBackend { // no module hash. return RunThinBackend(CGAddStream, IRAddStream); + auto Mod = ModuleMap.front().second.parseModule(BackendContext); + if (!Mod) + return Mod.takeError(); + Triple TT = (*Mod)->getTargetTriple(); + // Get CGKey for caching object in CGCache. std::string CGKey = computeLTOCacheKey( Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR, - DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls); + DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls); Expected CacheCGAddStreamOrErr = CGCache(Task, CGKey, ModuleID); if (Error Err = CacheCGAddStreamOrErr.takeError()) @@ -1747,8 +1761,8 @@ class SecondRoundThinBackend : public InProcessThinBackend { auto ModuleID = BM.getModuleIdentifier(); llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)", ModuleID); + LTOLLVMContext BackendContext(Conf); auto RunThinBackend = [&](AddStreamFn AddStream) { - LTOLLVMContext BackendContext(Conf); std::unique_ptr LoadedModule = cgdata::loadModuleForTwoRounds(BM, Task, BackendContext, *IRFiles); @@ -1763,11 +1777,16 @@ class SecondRoundThinBackend : public InProcessThinBackend { // no module hash. return RunThinBackend(AddStream); + auto Mod = ModuleMap.front().second.parseModule(BackendContext); + if (!Mod) + return Mod.takeError(); + Triple TT = (*Mod)->getTargetTriple(); + // Get Key for caching the final object file in Cache with the combined // CGData hash. std::string Key = computeLTOCacheKey( Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR, - DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls); + DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls); Key = recomputeLTOCacheKey(Key, /*ExtraID=*/std::to_string(CombinedCGDataHash)); Expected CacheAddStreamOrErr = Cache(Task, Key, ModuleID); @@ -2340,7 +2359,7 @@ class OutOfProcessThinBackend : public CGThinBackend { // The module may be cached, this helps handling it. J.CacheKey = computeLTOCacheKey(Conf, CombinedIndex, J.ModuleID, ImportList, ExportList, ResolvedODR, DefinedGlobals, - CfiFunctionDefs, CfiFunctionDecls); + Triple, CfiFunctionDefs, CfiFunctionDecls); // The module may be cached, this helps handling it. auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID); @@ -2436,12 +2455,14 @@ class OutOfProcessThinBackend : public CGThinBackend { auto &Ops = CodegenOptions; Ops.push_back(Saver.save("-O" + Twine(C.OptLevel))); + TargetOptions TO = codegen::InitTargetOptionsFromCodeGenFlags(Triple); + C.ModifyTargetOptions(TO); - if (C.Options.EmitAddrsig) + if (TO.EmitAddrsig) Ops.push_back("-faddrsig"); - if (C.Options.FunctionSections) + if (TO.FunctionSections) Ops.push_back("-ffunction-sections"); - if (C.Options.DataSections) + if (TO.DataSections) Ops.push_back("-fdata-sections"); if (C.RelocModel == Reloc::PIC_) diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 43e5c3b398372..09d9f40567ed7 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -22,6 +22,7 @@ #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/CGData/CodeGenData.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/IR/LLVMRemarkStreamer.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/PassManager.h" @@ -215,6 +216,9 @@ static void RegisterPassPlugins(ArrayRef PassPlugins, } } +// Required to call InitTargetOptionsFromCodeGenFlags(). +static codegen::RegisterCodeGenFlags F; + static std::unique_ptr createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) { const Triple &TheTriple = M.getTargetTriple(); @@ -236,7 +240,10 @@ createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) { else CodeModel = M.getCodeModel(); - TargetOptions TargetOpts = Conf.Options; + TargetOptions TargetOpts = + codegen::InitTargetOptionsFromCodeGenFlags(TheTriple); + Conf.ModifyTargetOptions(TargetOpts); + if (TargetOpts.MCOptions.ABIName.empty()) { TargetOpts.MCOptions.ABIName = M.getTargetABIFromMD(); } @@ -413,9 +420,9 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod); } -static void codegen(const Config &Conf, TargetMachine *TM, - AddStreamFn AddStream, unsigned Task, Module &Mod, - const ModuleSummaryIndex &CombinedIndex) { +static void startCodegen(const Config &Conf, TargetMachine *TM, + AddStreamFn AddStream, unsigned Task, Module &Mod, + const ModuleSummaryIndex &CombinedIndex) { llvm::TimeTraceScope timeScope("codegen"); if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod)) return; @@ -526,8 +533,8 @@ static void splitCodeGen(const Config &C, TargetMachine *TM, std::unique_ptr TM = createTargetMachine(C, T, *MPartInCtx); - codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx, - CombinedIndex); + startCodegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx, + CombinedIndex); }, // Pass BC using std::move to ensure that it get moved rather than // copied into the thread's context. @@ -591,7 +598,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream, } if (ParallelCodeGenParallelismLevel == 1) { - codegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex); + startCodegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex); } else { splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, Mod, CombinedIndex); @@ -652,7 +659,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, if (CodeGenOnly) { // If CodeGenOnly is set, we only perform code generation and skip // optimization. This value may differ from Conf.CodeGenOnly. - codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex); + startCodegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex); return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); } @@ -675,7 +682,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, if (IRAddStream) cgdata::saveModuleForTwoRounds(Mod, Task, IRAddStream); - codegen(Conf, TM, AddStream, Task, Mod, CombinedIndex); + startCodegen(Conf, TM, AddStream, Task, Mod, CombinedIndex); return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); }; diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 46be71da5a092..2826bb240b8e7 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -166,7 +166,7 @@ void LTOCodeGenerator::setModule(std::unique_ptr Mod) { } void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) { - Config.Options = Options; + TO = Options; } void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) { @@ -230,7 +230,7 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) { bool LTOCodeGenerator::useAIXSystemAssembler() { const auto &Triple = TargetMach->getTargetTriple(); - return Triple.isOSAIX() && Config.Options.DisableIntegratedAS; + return Triple.isOSAIX() && TO.DisableIntegratedAS; } bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) { @@ -397,7 +397,7 @@ bool LTOCodeGenerator::determineTarget() { // If data-sections is not explicitly set or unset, set data-sections by // default to match the behaviour of lld and gold plugin. if (!codegen::getExplicitDataSections()) - Config.Options.DataSections = true; + TO.DataSections = true; TargetMach = createTargetMachine(); assert(TargetMach && "Unable to create target machine"); @@ -408,7 +408,7 @@ bool LTOCodeGenerator::determineTarget() { std::unique_ptr LTOCodeGenerator::createTargetMachine() { assert(MArch && "MArch is not set!"); return std::unique_ptr(MArch->createTargetMachine( - MergedModule->getTargetTriple(), Config.CPU, FeatureStr, Config.Options, + MergedModule->getTargetTriple(), Config.CPU, FeatureStr, TO, Config.RelocModel, std::nullopt, Config.CGOptLevel)); } diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 93b672ae7840c..da7d2c0b1955d 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -374,15 +374,14 @@ class ModuleCacheEntry { llvm::lto::Config Conf; Conf.OptLevel = OptLevel; - Conf.Options = TMBuilder.Options; Conf.CPU = TMBuilder.MCpu; Conf.MAttrs.push_back(TMBuilder.MAttr); Conf.RelocModel = TMBuilder.RelocModel; Conf.CGOptLevel = TMBuilder.CGOptLevel; Conf.Freestanding = Freestanding; - std::string Key = - computeLTOCacheKey(Conf, Index, ModuleID, ImportList, ExportList, - ResolvedODR, DefinedGVSummaries); + std::string Key = computeLTOCacheKey( + Conf, Index, ModuleID, ImportList, ExportList, ResolvedODR, + DefinedGVSummaries, TMBuilder.TheTriple); // This choice of file name allows the cache to be pruned (see pruneCache() // in include/llvm/Support/CachePruning.h). diff --git a/llvm/test/CodeGen/RISCV/tls-models.ll b/llvm/test/CodeGen/RISCV/tls-models.ll index 52c2c31d8fa81..8caa6108ffbe9 100644 --- a/llvm/test/CodeGen/RISCV/tls-models.ll +++ b/llvm/test/CodeGen/RISCV/tls-models.ll @@ -7,10 +7,13 @@ ; RUN: | FileCheck -check-prefix=RV64-PIC %s ; RUN: llc -mtriple=riscv64 -relocation-model=pic -enable-tlsdesc < %s \ ; RUN: | FileCheck -check-prefix=RV64-PIC-TLSDESC %s +; RUN: llc -mtriple=riscv64-unknown-fuchsia -relocation-model=pic < %s \ +; RUN: | FileCheck -check-prefix=RV64-PIC-FUCHSIA %s ; RUN: llc -mtriple=riscv32 < %s | FileCheck -check-prefix=RV32-NOPIC %s ; RUN: llc -mtriple=riscv32 < %s -enable-tlsdesc | FileCheck -check-prefix=RV32-NOPIC-TLSDESC %s ; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefix=RV64-NOPIC %s ; RUN: llc -mtriple=riscv64 < %s -enable-tlsdesc | FileCheck -check-prefix=RV64-NOPIC-TLSDESC %s +; RUN: llc -mtriple=riscv64-unknown-fuchsia < %s | FileCheck -check-prefix=RV64-NOPIC-FUCHSIA %s ; Check that TLS symbols are lowered correctly based on the specified ; model. Make sure they're external to avoid them all being optimised to Local @@ -69,6 +72,16 @@ define ptr @f1() nounwind { ; RV64-PIC-TLSDESC-NEXT: add a0, a0, tp ; RV64-PIC-TLSDESC-NEXT: ret ; +; RV64-PIC-FUCHSIA-LABEL: f1: +; RV64-PIC-FUCHSIA: # %bb.0: # %entry +; RV64-PIC-FUCHSIA-NEXT: .Ltlsdesc_hi0: +; RV64-PIC-FUCHSIA-NEXT: auipc a0, %tlsdesc_hi(unspecified) +; RV64-PIC-FUCHSIA-NEXT: ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0) +; RV64-PIC-FUCHSIA-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0) +; RV64-PIC-FUCHSIA-NEXT: jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) +; RV64-PIC-FUCHSIA-NEXT: add a0, a0, tp +; RV64-PIC-FUCHSIA-NEXT: ret +; ; RV32-NOPIC-LABEL: f1: ; RV32-NOPIC: # %bb.0: # %entry ; RV32-NOPIC-NEXT: .Lpcrel_hi0: @@ -100,6 +113,14 @@ define ptr @f1() nounwind { ; RV64-NOPIC-TLSDESC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) ; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp ; RV64-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-FUCHSIA-LABEL: f1: +; RV64-NOPIC-FUCHSIA: # %bb.0: # %entry +; RV64-NOPIC-FUCHSIA-NEXT: .Lpcrel_hi0: +; RV64-NOPIC-FUCHSIA-NEXT: auipc a0, %tls_ie_pcrel_hi(unspecified) +; RV64-NOPIC-FUCHSIA-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) +; RV64-NOPIC-FUCHSIA-NEXT: add a0, a0, tp +; RV64-NOPIC-FUCHSIA-NEXT: ret entry: ret ptr @unspecified } @@ -152,6 +173,16 @@ define ptr @f2() nounwind { ; RV64-PIC-TLSDESC-NEXT: add a0, a0, tp ; RV64-PIC-TLSDESC-NEXT: ret ; +; RV64-PIC-FUCHSIA-LABEL: f2: +; RV64-PIC-FUCHSIA: # %bb.0: # %entry +; RV64-PIC-FUCHSIA-NEXT: .Ltlsdesc_hi1: +; RV64-PIC-FUCHSIA-NEXT: auipc a0, %tlsdesc_hi(ld) +; RV64-PIC-FUCHSIA-NEXT: ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi1)(a0) +; RV64-PIC-FUCHSIA-NEXT: addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi1) +; RV64-PIC-FUCHSIA-NEXT: jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi1) +; RV64-PIC-FUCHSIA-NEXT: add a0, a0, tp +; RV64-PIC-FUCHSIA-NEXT: ret +; ; RV32-NOPIC-LABEL: f2: ; RV32-NOPIC: # %bb.0: # %entry ; RV32-NOPIC-NEXT: .Lpcrel_hi1: @@ -183,6 +214,14 @@ define ptr @f2() nounwind { ; RV64-NOPIC-TLSDESC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0) ; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp ; RV64-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-FUCHSIA-LABEL: f2: +; RV64-NOPIC-FUCHSIA: # %bb.0: # %entry +; RV64-NOPIC-FUCHSIA-NEXT: .Lpcrel_hi1: +; RV64-NOPIC-FUCHSIA-NEXT: auipc a0, %tls_ie_pcrel_hi(ld) +; RV64-NOPIC-FUCHSIA-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0) +; RV64-NOPIC-FUCHSIA-NEXT: add a0, a0, tp +; RV64-NOPIC-FUCHSIA-NEXT: ret entry: ret ptr @ld } @@ -223,6 +262,14 @@ define ptr @f3() nounwind { ; RV64-PIC-TLSDESC-NEXT: add a0, a0, tp ; RV64-PIC-TLSDESC-NEXT: ret ; +; RV64-PIC-FUCHSIA-LABEL: f3: +; RV64-PIC-FUCHSIA: # %bb.0: # %entry +; RV64-PIC-FUCHSIA-NEXT: .Lpcrel_hi0: +; RV64-PIC-FUCHSIA-NEXT: auipc a0, %tls_ie_pcrel_hi(ie) +; RV64-PIC-FUCHSIA-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) +; RV64-PIC-FUCHSIA-NEXT: add a0, a0, tp +; RV64-PIC-FUCHSIA-NEXT: ret +; ; RV32-NOPIC-LABEL: f3: ; RV32-NOPIC: # %bb.0: # %entry ; RV32-NOPIC-NEXT: .Lpcrel_hi2: @@ -254,6 +301,14 @@ define ptr @f3() nounwind { ; RV64-NOPIC-TLSDESC-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0) ; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp ; RV64-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-FUCHSIA-LABEL: f3: +; RV64-NOPIC-FUCHSIA: # %bb.0: # %entry +; RV64-NOPIC-FUCHSIA-NEXT: .Lpcrel_hi2: +; RV64-NOPIC-FUCHSIA-NEXT: auipc a0, %tls_ie_pcrel_hi(ie) +; RV64-NOPIC-FUCHSIA-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi2)(a0) +; RV64-NOPIC-FUCHSIA-NEXT: add a0, a0, tp +; RV64-NOPIC-FUCHSIA-NEXT: ret entry: ret ptr @ie } @@ -290,6 +345,13 @@ define ptr @f4() nounwind { ; RV64-PIC-TLSDESC-NEXT: addi a0, a0, %tprel_lo(le) ; RV64-PIC-TLSDESC-NEXT: ret ; +; RV64-PIC-FUCHSIA-LABEL: f4: +; RV64-PIC-FUCHSIA: # %bb.0: # %entry +; RV64-PIC-FUCHSIA-NEXT: lui a0, %tprel_hi(le) +; RV64-PIC-FUCHSIA-NEXT: add a0, a0, tp, %tprel_add(le) +; RV64-PIC-FUCHSIA-NEXT: addi a0, a0, %tprel_lo(le) +; RV64-PIC-FUCHSIA-NEXT: ret +; ; RV32-NOPIC-LABEL: f4: ; RV32-NOPIC: # %bb.0: # %entry ; RV32-NOPIC-NEXT: lui a0, %tprel_hi(le) @@ -317,6 +379,13 @@ define ptr @f4() nounwind { ; RV64-NOPIC-TLSDESC-NEXT: add a0, a0, tp, %tprel_add(le) ; RV64-NOPIC-TLSDESC-NEXT: addi a0, a0, %tprel_lo(le) ; RV64-NOPIC-TLSDESC-NEXT: ret +; +; RV64-NOPIC-FUCHSIA-LABEL: f4: +; RV64-NOPIC-FUCHSIA: # %bb.0: # %entry +; RV64-NOPIC-FUCHSIA-NEXT: lui a0, %tprel_hi(le) +; RV64-NOPIC-FUCHSIA-NEXT: add a0, a0, tp, %tprel_add(le) +; RV64-NOPIC-FUCHSIA-NEXT: addi a0, a0, %tprel_lo(le) +; RV64-NOPIC-FUCHSIA-NEXT: ret entry: ret ptr @le } diff --git a/llvm/test/CodeGen/X86/tls-desc.ll b/llvm/test/CodeGen/X86/tls-desc.ll index c73986e69e791..f7dc0ceeeeb32 100644 --- a/llvm/test/CodeGen/X86/tls-desc.ll +++ b/llvm/test/CodeGen/X86/tls-desc.ll @@ -2,6 +2,7 @@ ; RUN: llc < %s -mtriple=i686 --relocation-model=pic -enable-tlsdesc | FileCheck %s --check-prefix=X86 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 --relocation-model=pic -enable-tlsdesc | FileCheck %s --check-prefix=X32 ; RUN: llc < %s -mtriple=x86_64 --relocation-model=pic -enable-tlsdesc | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown-fuchsia --relocation-model=pic | FileCheck %s --check-prefix=X64-FUCHSIA @x = thread_local global i32 0, align 4 @y = internal thread_local global i32 1, align 4 @@ -62,6 +63,19 @@ define ptr @f1() nounwind { ; X64-NEXT: #NO_APP ; X64-NEXT: popq %rcx ; X64-NEXT: retq +; +; X64-FUCHSIA-LABEL: f1: +; X64-FUCHSIA: # %bb.0: +; X64-FUCHSIA-NEXT: pushq %rax +; X64-FUCHSIA-NEXT: #APP +; X64-FUCHSIA-NEXT: #NO_APP +; X64-FUCHSIA-NEXT: leaq x@tlsdesc(%rip), %rax +; X64-FUCHSIA-NEXT: callq *x@tlscall(%rax) +; X64-FUCHSIA-NEXT: addq %fs:0, %rax +; X64-FUCHSIA-NEXT: #APP +; X64-FUCHSIA-NEXT: #NO_APP +; X64-FUCHSIA-NEXT: popq %rcx +; X64-FUCHSIA-NEXT: retq %a = call { i32, i32, i32, i32, i32, i32 } asm sideeffect "", "=r,=r,=r,=r,=r,=r,~{dirflag},~{fpsr},~{flags}"() %b = call ptr @llvm.threadlocal.address.p0(ptr @x) %a.0 = extractvalue { i32, i32, i32, i32, i32, i32 } %a, 0 @@ -109,6 +123,15 @@ define i32 @f2() nounwind { ; X64-NEXT: movl (%rax,%rcx), %eax ; X64-NEXT: popq %rcx ; X64-NEXT: retq +; +; X64-FUCHSIA-LABEL: f2: +; X64-FUCHSIA: # %bb.0: +; X64-FUCHSIA-NEXT: pushq %rax +; X64-FUCHSIA-NEXT: leaq x@tlsdesc(%rip), %rax +; X64-FUCHSIA-NEXT: callq *x@tlscall(%rax) +; X64-FUCHSIA-NEXT: movl %fs:(%rax), %eax +; X64-FUCHSIA-NEXT: popq %rcx +; X64-FUCHSIA-NEXT: retq %1 = tail call ptr @llvm.threadlocal.address.p0(ptr @x) %2 = load i32, ptr %1 ret i32 %2 @@ -147,6 +170,15 @@ define ptr @f3() nounwind { ; X64-NEXT: addq %fs:0, %rax ; X64-NEXT: popq %rcx ; X64-NEXT: retq +; +; X64-FUCHSIA-LABEL: f3: +; X64-FUCHSIA: # %bb.0: +; X64-FUCHSIA-NEXT: pushq %rax +; X64-FUCHSIA-NEXT: leaq x@tlsdesc(%rip), %rax +; X64-FUCHSIA-NEXT: callq *x@tlscall(%rax) +; X64-FUCHSIA-NEXT: addq %fs:0, %rax +; X64-FUCHSIA-NEXT: popq %rcx +; X64-FUCHSIA-NEXT: retq %1 = tail call ptr @llvm.threadlocal.address.p0(ptr @x) ret ptr %1 } @@ -192,6 +224,17 @@ define i32 @f4() nounwind { ; X64-NEXT: movl %ecx, %eax ; X64-NEXT: popq %rcx ; X64-NEXT: retq +; +; X64-FUCHSIA-LABEL: f4: +; X64-FUCHSIA: # %bb.0: +; X64-FUCHSIA-NEXT: pushq %rax +; X64-FUCHSIA-NEXT: leaq _TLS_MODULE_BASE_@tlsdesc(%rip), %rax +; X64-FUCHSIA-NEXT: callq *_TLS_MODULE_BASE_@tlscall(%rax) +; X64-FUCHSIA-NEXT: movl %fs:y@DTPOFF(%rax), %ecx +; X64-FUCHSIA-NEXT: addl %fs:z@DTPOFF(%rax), %ecx +; X64-FUCHSIA-NEXT: movl %ecx, %eax +; X64-FUCHSIA-NEXT: popq %rcx +; X64-FUCHSIA-NEXT: retq %1 = load i32, ptr @y, align 4 %2 = load i32, ptr @z, align 4 %3 = add nsw i32 %1, %2 diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp index 955c1130e9f4c..87ca7810d5486 100644 --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -334,7 +334,7 @@ static int run(int argc, char **argv) { Conf.TimeTraceGranularity = TimeTraceGranularity; } Conf.CPU = codegen::getMCPU(); - Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple()); + Conf.ModifyTargetOptions = [](llvm::TargetOptions &TO) {}; Conf.MAttrs = codegen::getMAttrs(); if (auto RM = codegen::getExplicitRelocModel()) Conf.RelocModel = *RM;