diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -813,8 +813,11 @@ if (UsesCodeGen && !TM) return; - if (TM) + + if (TM) { + TM->initializeOptionsWithModuleMetadata(*TheModule); TheModule->setDataLayout(TM->createDataLayout()); + } legacy::PassManager PerModulePasses; PerModulePasses.add( diff --git a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp --- a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp +++ b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp @@ -108,6 +108,7 @@ getFeaturesStr(), Options, getRelocModel(), getCodeModel(), OLvl); std::unique_ptr TM(Machine); + TM->initializeOptionsWithModuleMetadata(*M); setFunctionAttributes(getCPUStr(), getFeaturesStr(), *M); legacy::PassManager Passes; diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -147,6 +147,7 @@ target_machine->createDataLayout().getStringRepresentation().c_str()); } module.setTargetTriple(real_triple); + target_machine->initializeOptionsWithModuleMetadata(module); module.setDataLayout(target_machine->createDataLayout()); } return changed_module; diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst @@ -129,9 +129,10 @@ .. code-block:: c++ + TheModule->setTargetTriple(TargetTriple); + TargetMachine->initializeOptionsWithModuleMetadata(*TheModule); TheModule->setDataLayout(TargetMachine->createDataLayout()); - TheModule->setTargetTriple(TargetTriple); - + Emit Object Code ================ diff --git a/llvm/examples/Kaleidoscope/Chapter8/toy.cpp b/llvm/examples/Kaleidoscope/Chapter8/toy.cpp --- a/llvm/examples/Kaleidoscope/Chapter8/toy.cpp +++ b/llvm/examples/Kaleidoscope/Chapter8/toy.cpp @@ -1241,6 +1241,7 @@ auto TheTargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM); + TheTargetMachine->initializeOptionsWithModuleMetadata(*TheModule); TheModule->setDataLayout(TheTargetMachine->createDataLayout()); auto Filename = "output.o"; diff --git a/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h --- a/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -41,7 +41,7 @@ Optional RelocModel; CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive; - std::unique_ptr create() const; + std::unique_ptr create(Module &TheModule) const; }; /// This class define an interface similar to the LTOCodeGenerator, but adapted diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -98,6 +98,9 @@ unsigned RequireStructuredCFG : 1; unsigned O0WantsFastISel : 1; +private: + mutable unsigned OptionsCanBeInitalizedFromModule : 1; + public: const TargetOptions DefaultOptions; mutable TargetOptions Options; @@ -150,7 +153,10 @@ } /// Create a DataLayout. - const DataLayout createDataLayout() const { return DL; } + const DataLayout createDataLayout() const { + OptionsCanBeInitalizedFromModule = false; + return DL; + } /// Test if a DataLayout if compatible with the CodeGen for this target. /// @@ -180,6 +186,17 @@ return DL.getPointerSize(DL.getAllocaAddrSpace()); } + /// Target hook for updating this TargetMachine's Options based + // on the provided module metadata. + virtual void + setTargetOptionsWithModuleMetadata(const Module &M LLVM_ATTRIBUTE_UNUSED) {} + + /// This method ensures that `setTargetOptionsWithModuleMetadata` is + // called, and ensures that is called before `createDataLayout` so that + // Options set from module metadata are modified as early as possible + // before they are used. + void initializeOptionsWithModuleMetadata(const Module &M); + /// Reset the target options based on the function's attributes. // FIXME: Remove TargetOptions that affect per-function code generation // from TargetMachine. diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -148,9 +148,13 @@ else CodeModel = M.getCodeModel(); - return std::unique_ptr(TheTarget->createTargetMachine( + std::unique_ptr TM(TheTarget->createTargetMachine( TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel, CodeModel, Conf.CGOptLevel)); + + TM->initializeOptionsWithModuleMetadata(M); + + return TM; } static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -371,6 +371,7 @@ } TargetMach = createTargetMachine(); + TargetMach->initializeOptionsWithModuleMetadata(*MergedModule); return true; } diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -541,7 +541,8 @@ } // TargetMachine factory -std::unique_ptr TargetMachineBuilder::create() const { +std::unique_ptr +TargetMachineBuilder::create(Module &TheModule) const { std::string ErrMsg; const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg); @@ -554,9 +555,13 @@ Features.getDefaultSubtargetFeatures(TheTriple); std::string FeatureStr = Features.getString(); - return std::unique_ptr( + std::unique_ptr TM( TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options, RelocModel, None, CGOptLevel)); + + TM->initializeOptionsWithModuleMetadata(TheModule); + + return TM; } /** @@ -848,8 +853,8 @@ initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple())); // Optimize now - optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding, - nullptr); + optimizeModule(TheModule, *TMBuilder.create(TheModule), OptLevel, + Freestanding, nullptr); } /// Write out the generated object file, either from CacheEntryPath or from @@ -920,7 +925,8 @@ /*IsImporting*/ false); // CodeGen - auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create()); + auto OutputBuffer = + codegenModule(*TheModule, *TMBuilder.create(*TheModule)); if (SavedObjectsDirectoryPath.empty()) ProducedBinaries[count] = std::move(OutputBuffer); else @@ -1093,8 +1099,8 @@ auto &ImportList = ImportLists[ModuleIdentifier]; // Run the main process now, and generates a binary auto OutputBuffer = ProcessThinLTOModule( - *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList, - ExportList, GUIDPreservedSymbols, + *TheModule, *Index, ModuleMap, *TMBuilder.create(*TheModule), + ImportList, ExportList, GUIDPreservedSymbols, ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions, DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count); diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -37,7 +37,8 @@ : TheTarget(T), DL(DataLayoutString), TargetTriple(TT), TargetCPU(CPU), TargetFS(FS), AsmInfo(nullptr), MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false), O0WantsFastISel(false), - DefaultOptions(Options), Options(Options) {} + OptionsCanBeInitalizedFromModule(true), DefaultOptions(Options), + Options(Options) {} TargetMachine::~TargetMachine() = default; @@ -45,6 +46,14 @@ return getRelocationModel() == Reloc::PIC_; } +void TargetMachine::initializeOptionsWithModuleMetadata(const Module &M) { + assert( + OptionsCanBeInitalizedFromModule && + "setOptionsWithModuleMetadata cannot be called after createDataLayout"); + + setTargetOptionsWithModuleMetadata(M); +} + /// Reset the target options based on the function's attributes. // FIXME: This function needs to go away for a number of reasons: // a) global state on the TargetMachine is terrible in general, diff --git a/llvm/lib/Target/TargetMachineC.cpp b/llvm/lib/Target/TargetMachineC.cpp --- a/llvm/lib/Target/TargetMachineC.cpp +++ b/llvm/lib/Target/TargetMachineC.cpp @@ -193,6 +193,7 @@ std::string error; + TM->initializeOptionsWithModuleMetadata(*Mod); Mod->setDataLayout(TM->createDataLayout()); CodeGenFileType ft; diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -474,6 +474,10 @@ return 0; assert(M && "Should have exited if we didn't have a module!"); + + // Initialise target default options from module metadata + Target->initializeOptionsWithModuleMetadata(*M); + if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; diff --git a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp --- a/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp +++ b/llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp @@ -91,6 +91,7 @@ // Set up the module to build for our target. M->setTargetTriple(TM->getTargetTriple().normalize()); + TM->initializeOptionsWithModuleMetadata(*M); M->setDataLayout(TM->createDataLayout()); // Build up a PM to do instruction selection. diff --git a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp --- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp +++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp @@ -123,6 +123,7 @@ // M->setTargetTriple(TM->getTargetTriple().normalize()); + TM->initializeOptionsWithModuleMetadata(*M); M->setDataLayout(TM->createDataLayout()); setFunctionAttributes(TM->getTargetCPU(), TM->getTargetFeatureString(), *M); diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -674,6 +674,9 @@ std::unique_ptr TM(Machine); + if (TM) + TM->initializeOptionsWithModuleMetadata(*M); + // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. setFunctionAttributes(CPUStr, FeaturesStr, *M); diff --git a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp b/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp --- a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp +++ b/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp @@ -51,6 +51,7 @@ M = parseAssemblyString(Assembly, SMError, Context); if (!M) report_fatal_error(SMError.getMessage()); + TM->initializeOptionsWithModuleMetadata(*M); M->setDataLayout(TM->createDataLayout()); F = M->getFunction("f"); diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h --- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h @@ -70,8 +70,8 @@ static std::unique_ptr parseMIR(LLVMContext &Context, std::unique_ptr &MIR, - const TargetMachine &TM, - StringRef MIRCode, const char *FuncName, + TargetMachine &TM, StringRef MIRCode, + const char *FuncName, MachineModuleInfo &MMI) { SMDiagnostic Diagnostic; std::unique_ptr MBuffer = MemoryBuffer::getMemBuffer(MIRCode); @@ -83,6 +83,7 @@ if (!M) return nullptr; + TM.initializeOptionsWithModuleMetadata(*M); M->setDataLayout(TM.createDataLayout()); if (MIR->parseMachineFunctions(*M, MMI)) @@ -92,7 +93,7 @@ } static std::pair, std::unique_ptr> -createDummyModule(LLVMContext &Context, const LLVMTargetMachine &TM, +createDummyModule(LLVMContext &Context, LLVMTargetMachine &TM, StringRef MIRFunc) { SmallString<512> S; StringRef MIRString = (Twine(R"MIR( diff --git a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt --- a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt +++ b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt @@ -8,6 +8,7 @@ Passes RuntimeDyld Support + Target native ) diff --git a/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp --- a/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp @@ -93,6 +93,7 @@ LLVMContext Ctx; ModuleBuilder MB(Ctx, TM->getTargetTriple().str(), "TestModule"); + TM->initializeOptionsWithModuleMetadata(*MB.getModule()); MB.getModule()->setDataLayout(TM->createDataLayout()); auto *Main = MB.createFunctionDecl( FunctionType::get(Type::getInt32Ty(Ctx), diff --git a/llvm/unittests/MI/LiveIntervalTest.cpp b/llvm/unittests/MI/LiveIntervalTest.cpp --- a/llvm/unittests/MI/LiveIntervalTest.cpp +++ b/llvm/unittests/MI/LiveIntervalTest.cpp @@ -50,8 +50,10 @@ } std::unique_ptr parseMIR(LLVMContext &Context, - legacy::PassManagerBase &PM, std::unique_ptr &MIR, - const LLVMTargetMachine &TM, StringRef MIRCode, const char *FuncName) { + legacy::PassManagerBase &PM, + std::unique_ptr &MIR, + LLVMTargetMachine &TM, StringRef MIRCode, + const char *FuncName) { SMDiagnostic Diagnostic; std::unique_ptr MBuffer = MemoryBuffer::getMemBuffer(MIRCode); MIR = createMIRParser(std::move(MBuffer), Context); @@ -62,6 +64,7 @@ if (!M) return nullptr; + TM.initializeOptionsWithModuleMetadata(*M); M->setDataLayout(TM.createDataLayout()); MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM); diff --git a/mlir/lib/Conversion/GPUToCUDA/ConvertKernelFuncToCubin.cpp b/mlir/lib/Conversion/GPUToCUDA/ConvertKernelFuncToCubin.cpp --- a/mlir/lib/Conversion/GPUToCUDA/ConvertKernelFuncToCubin.cpp +++ b/mlir/lib/Conversion/GPUToCUDA/ConvertKernelFuncToCubin.cpp @@ -139,6 +139,7 @@ } // Set the data layout of the llvm module to match what the ptx target needs. + targetMachine->initializeOptionsWithModuleMetadata(llvmModule); llvmModule.setDataLayout(targetMachine->createDataLayout()); auto ptx = translateModuleToPtx(llvmModule, *targetMachine); diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp --- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp @@ -110,8 +110,9 @@ } std::unique_ptr machine( target->createTargetMachine(targetTriple, "generic", "", {}, {})); - llvmModule->setDataLayout(machine->createDataLayout()); llvmModule->setTargetTriple(targetTriple); + machine->initializeOptionsWithModuleMetadata(*llvmModule); + llvmModule->setDataLayout(machine->createDataLayout()); return false; }