diff --git a/lgc/include/lgc/patch/Patch.h b/lgc/include/lgc/patch/Patch.h index 2d1e27dd22..7c52020eae 100644 --- a/lgc/include/lgc/patch/Patch.h +++ b/lgc/include/lgc/patch/Patch.h @@ -53,8 +53,7 @@ class Patch { virtual ~Patch() {} static void addPasses(PipelineState *pipelineState, lgc::PassManager &passMgr, llvm::Timer *patchTimer, - llvm::Timer *optTimer, Pipeline::CheckShaderCacheFunc checkShaderCacheFunc, - llvm::CodeGenOpt::Level optLevel); + llvm::Timer *optTimer, Pipeline::CheckShaderCacheFunc checkShaderCacheFunc, uint32_t optLevel); // Register all the patching passes into the given pass manager static void registerPasses(lgc::PassManager &passMgr); @@ -65,7 +64,7 @@ class Patch { static llvm::GlobalVariable *getLdsVariable(PipelineState *pipelineState, llvm::Module *module); protected: - static void addOptimizationPasses(lgc::PassManager &passMgr, llvm::CodeGenOpt::Level optLevel); + static void addOptimizationPasses(lgc::PassManager &passMgr, uint32_t optLevel); void init(llvm::Module *module); diff --git a/lgc/interface/lgc/LgcContext.h b/lgc/interface/lgc/LgcContext.h index 43abac27a7..efc48e4de1 100644 --- a/lgc/interface/lgc/LgcContext.h +++ b/lgc/interface/lgc/LgcContext.h @@ -84,7 +84,15 @@ class LgcContext { // @param gpuName : LLVM GPU name (e.g. "gfx900"); empty to use -mcpu option setting // @param optLevel : LLVM optimization level used to initialize target machine static std::unique_ptr createTargetMachine(llvm::StringRef gpuName, - llvm::CodeGenOpt::Level optLevel); +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code + llvm::CodeGenOpt::Level optLevel +#else + // New version of the code (also handles unknown + // version, which we treat as latest) + llvm::CodeGenOptLevel optLevel +#endif + ); // Create the LgcContext. // @@ -129,11 +137,21 @@ class LgcContext { // Adds target passes to pass manager, depending on "-filetype" and "-emit-llvm" options void addTargetPasses(lgc::LegacyPassManager &passMgr, llvm::Timer *codeGenTimer, llvm::raw_pwrite_stream &outStream); +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code // Returns the optimization level for the context. llvm::CodeGenOpt::Level getOptimizationLevel() const; // Returns the optimization level used for context initialization. llvm::CodeGenOpt::Level getInitialOptimizationLevel() const { return m_initialOptLevel; } +#else + // New version of the code (also handles unknown version, which we treat as latest) + // Returns the optimization level for the context. + llvm::CodeGenOptLevel getOptimizationLevel() const; + + // Returns the optimization level used for context initialization. + llvm::CodeGenOptLevel getInitialOptimizationLevel() const { return m_initialOptLevel; } +#endif // Utility method to create a start/stop timer pass static llvm::ModulePass *createStartStopTimer(llvm::Timer *timer, bool starting); @@ -167,7 +185,13 @@ class LgcContext { TargetInfo *m_targetInfo = nullptr; // Target info unsigned m_palAbiVersion = 0xFFFFFFFF; // PAL pipeline ABI version to compile for PassManagerCache *m_passManagerCache = nullptr; // Pass manager cache and creator - llvm::CodeGenOpt::Level m_initialOptLevel; // Optimization level at initialization +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code + llvm::CodeGenOpt::Level m_initialOptLevel; // Optimization level at initialization +#else + // New version of the code (also handles unknown version, which we treat as latest) + llvm::CodeGenOptLevel m_initialOptLevel; // Optimization level at initialization +#endif }; } // namespace lgc diff --git a/lgc/patch/Patch.cpp b/lgc/patch/Patch.cpp index 74e5d01a8e..d1945e356d 100644 --- a/lgc/patch/Patch.cpp +++ b/lgc/patch/Patch.cpp @@ -117,7 +117,7 @@ namespace lgc { // @param optLevel : The optimization level uses to adjust the aggressiveness of // passes and which passes to add. void Patch::addPasses(PipelineState *pipelineState, lgc::PassManager &passMgr, Timer *patchTimer, Timer *optTimer, - Pipeline::CheckShaderCacheFunc checkShaderCacheFunc, CodeGenOpt::Level optLevel) { + Pipeline::CheckShaderCacheFunc checkShaderCacheFunc, uint32_t optLevel) { // Start timer for patching passes. if (patchTimer) LgcContext::createAndAddStartStopTimer(passMgr, patchTimer, true); @@ -340,7 +340,7 @@ void Patch::registerPasses(PassBuilder &passBuilder) { // @param [in/out] passMgr : Pass manager to add passes to // @param optLevel : The optimization level uses to adjust the aggressiveness of // passes and which passes to add. -void Patch::addOptimizationPasses(lgc::PassManager &passMgr, CodeGenOpt::Level optLevel) { +void Patch::addOptimizationPasses(lgc::PassManager &passMgr, uint32_t optLevel) { LLPC_OUTS("PassManager optimization level = " << optLevel << "\n"); passMgr.addPass(ForceFunctionAttrsPass()); diff --git a/lgc/state/Compiler.cpp b/lgc/state/Compiler.cpp index cc5c075abe..e0226c99eb 100644 --- a/lgc/state/Compiler.cpp +++ b/lgc/state/Compiler.cpp @@ -219,7 +219,7 @@ bool PipelineState::generate(Module *pipelineModule, raw_pwrite_stream &outStrea } else { // Patching. Patch::addPasses(this, *passMgr, patchTimer, optTimer, std::move(checkShaderCacheFunc), - getLgcContext()->getOptimizationLevel()); + static_cast(getLgcContext()->getOptimizationLevel())); // Add pass to clear pipeline state from IR passMgr->addPass(PipelineStateClearer()); diff --git a/lgc/state/LgcContext.cpp b/lgc/state/LgcContext.cpp index e53c6d8b5e..bf0c4705bf 100644 --- a/lgc/state/LgcContext.cpp +++ b/lgc/state/LgcContext.cpp @@ -77,12 +77,23 @@ static cl::opt EmitLgc("emit-lgc", cl::desc("Emit LLVM assembly suitable f static cl::opt ShowEncoding("show-encoding", cl::desc("Show instruction encodings"), cl::init(false)); // -opt: Override the optimization level passed in to LGC with the given one. +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 +// Old version of the code static cl::opt OptLevel("opt", cl::desc("Set the optimization level for LGC:"), cl::init(CodeGenOpt::Default), values(clEnumValN(CodeGenOpt::None, "none", "no optimizations"), clEnumValN(CodeGenOpt::Less, "quick", "quick compilation time"), clEnumValN(CodeGenOpt::Default, "default", "default optimizations"), clEnumValN(CodeGenOpt::Aggressive, "fast", "fast execution time"))); +#else +// New version of the code (also handles unknown version, which we treat as latest) +static cl::opt + OptLevel("opt", cl::desc("Set the optimization level for LGC:"), cl::init(CodeGenOptLevel::Default), + values(clEnumValN(CodeGenOptLevel::None, "none", "no optimizations"), + clEnumValN(CodeGenOptLevel::Less, "quick", "quick compilation time"), + clEnumValN(CodeGenOptLevel::Default, "default", "default optimizations"), + clEnumValN(CodeGenOptLevel::Aggressive, "fast", "fast execution time"))); +#endif // ===================================================================================================================== // Set default for a command-line option, but only if command-line processing has not happened yet, or did not see @@ -216,7 +227,14 @@ bool LgcContext::isGpuNameValid(llvm::StringRef gpuName) { // // @param gpuName : LLVM GPU name (e.g. "gfx900"); empty to use -mcpu option setting // @param optLevel : LLVM optimization level used to initialize target machine -std::unique_ptr LgcContext::createTargetMachine(StringRef gpuName, CodeGenOpt::Level optLevel) { +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 +// Old version of the code +std::unique_ptr LgcContext::createTargetMachine(StringRef gpuName, CodeGenOpt::Level optLevel) +#else +// New version of the code (also handles unknown version, which we treat as latest) +std::unique_ptr LgcContext::createTargetMachine(StringRef gpuName, CodeGenOptLevel optLevel) +#endif +{ assert(Initialized && "Must call LgcContext::initialize before LgcContext::createTargetMachine"); std::string mcpuName = codegen::getMCPU(); // -mcpu setting from llvm/CodeGen/CommandFlags.h @@ -245,7 +263,7 @@ std::unique_ptr LgcContext::createTargetMachine(StringRef gpuName if (OptLevel.getPosition() != 0) optLevel = OptLevel; - LLPC_OUTS("TargetMachine optimization level = " << optLevel << "\n"); + LLPC_OUTS("TargetMachine optimization level = " << static_cast(optLevel) << "\n"); return std::unique_ptr(target->createTargetMachine(triple, gpuName, "", targetOpts, {}, {}, optLevel)); } @@ -358,7 +376,14 @@ void LgcContext::addTargetPasses(lgc::LegacyPassManager &passMgr, Timer *codeGen passMgr.add(createStartStopTimer(codeGenTimer, false)); } +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 +// Old version of the code llvm::CodeGenOpt::Level LgcContext::getOptimizationLevel() const { +#else +// New version of the code (also handles unknown version, which we treat as latest) +llvm::CodeGenOptLevel LgcContext::getOptimizationLevel() const { +#endif + return m_targetMachine->getOptLevel(); } diff --git a/lgc/tool/lgc/lgc.cpp b/lgc/tool/lgc/lgc.cpp index c6f8bdb27f..adc2f70ed4 100644 --- a/lgc/tool/lgc/lgc.cpp +++ b/lgc/tool/lgc/lgc.cpp @@ -159,6 +159,8 @@ static bool runPassPipeline(Pipeline &pipeline, Module &module, raw_pwrite_strea passMgr->addPass(VerifierPass()); passMgr->addPass(PipelineStateRecorder()); +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code switch (codegen::getFileType()) { case CGFT_AssemblyFile: passMgr->addPass(PrintModulePass(outStream)); @@ -169,6 +171,19 @@ static bool runPassPipeline(Pipeline &pipeline, Module &module, raw_pwrite_strea case CGFT_Null: break; } +#else + // New version of the code (also handles unknown version, which we treat as latest) + switch (codegen::getFileType()) { + case CodeGenFileType::AssemblyFile: + passMgr->addPass(PrintModulePass(outStream)); + break; + case CodeGenFileType::ObjectFile: + passMgr->addPass(BitcodeWriterPass(outStream)); + break; + case CodeGenFileType::Null: + break; + } +#endif passMgr->run(module); return true; @@ -239,11 +254,23 @@ int main(int argc, char **argv) { assert(optIterator != cl::getRegisteredOptions().end()); cl::Option *opt = optIterator->second; if (opt->getNumOccurrences() == 0) +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code *static_cast *>(opt) = CGFT_AssemblyFile; +#else + // New version of the code (also handles unknown version, which we treat as latest) + *static_cast *>(opt) = CodeGenFileType::AssemblyFile; +#endif } // Create the LgcContext. +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code std::unique_ptr targetMachine(LgcContext::createTargetMachine(gpuName, CodeGenOpt::Level::Default)); +#else + // New version of the code (also handles unknown version, which we treat as latest) + std::unique_ptr targetMachine(LgcContext::createTargetMachine(gpuName, CodeGenOptLevel::Default)); +#endif if (!targetMachine) { errs() << progName << ": GPU type '" << gpuName << "' not recognized\n"; return 1; diff --git a/llpc/context/llpcContext.cpp b/llpc/context/llpcContext.cpp index 68a477096e..7131973b35 100644 --- a/llpc/context/llpcContext.cpp +++ b/llpc/context/llpcContext.cpp @@ -105,12 +105,15 @@ LgcContext *Context::getLgcContext() { return &*m_builderContext; } +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 +// Old version of the code // ===================================================================================================================== // Get optimization level. Also resets what getLastOptimizationLevel() returns. // // @returns: the optimization level for the context. CodeGenOpt::Level Context::getOptimizationLevel() { - uint32_t optLevel = CodeGenOpt::Level::Default; + uint32_t optLevel = static_cast(CodeGenOpt::Level::Default); + optLevel = getPipelineContext()->getPipelineOptions()->optimizationLevel; if (optLevel > 3) optLevel = 3; @@ -126,6 +129,33 @@ CodeGenOpt::Level Context::getLastOptimizationLevel() const { return *m_lastOptLevel; } +#else +// New version of the code (also handles unknown version, which we treat as latest) + +// ===================================================================================================================== +// Get optimization level. Also resets what getLastOptimizationLevel() returns. +// +// @returns: the optimization level for the context. +CodeGenOptLevel Context::getOptimizationLevel() { + uint32_t optLevel = static_cast(CodeGenOptLevel::Default); + + optLevel = getPipelineContext()->getPipelineOptions()->optimizationLevel; + if (optLevel > 3) + optLevel = 3; + else if (optLevel == 0) // Workaround for noopt bugs in the AMDGPU backend in LLVM. + optLevel = 1; + m_lastOptLevel = CodeGenOptLevel(optLevel); + return *m_lastOptLevel; +} + +// ===================================================================================================================== +// Get the optimization level returned by the last getOptimizationLevel(). +CodeGenOptLevel Context::getLastOptimizationLevel() const { + return *m_lastOptLevel; +} + +#endif + // ===================================================================================================================== // Loads library from external LLVM library. // diff --git a/llpc/context/llpcContext.h b/llpc/context/llpcContext.h index b2f5f41901..54b77138dd 100644 --- a/llpc/context/llpcContext.h +++ b/llpc/context/llpcContext.h @@ -84,8 +84,15 @@ class Context : public llvm::LLVMContext { // Get (create if necessary) LgcContext lgc::LgcContext *getLgcContext(); +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code llvm::CodeGenOpt::Level getOptimizationLevel(); llvm::CodeGenOpt::Level getLastOptimizationLevel() const; +#else + // New version of the code (also handles unknown version, which we treat as latest) + llvm::CodeGenOptLevel getOptimizationLevel(); + llvm::CodeGenOptLevel getLastOptimizationLevel() const; +#endif std::unique_ptr loadLibrary(const BinaryData *lib); @@ -129,7 +136,14 @@ class Context : public llvm::LLVMContext { std::unique_ptr m_targetMachine; // Target machine for LGC context std::unique_ptr m_builderContext; // LGC context +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code std::optional m_lastOptLevel{}; // What getOptimizationLevel() last returned +#else + // New version of the code (also handles unknown version, which we treat as latest) + std::optional m_lastOptLevel{}; // What getOptimizationLevel() last returned +#endif + std::unique_ptr m_dialectContext; unsigned m_useCount = 0; // Number of times this context is used. diff --git a/llpc/tool/amdllpc.cpp b/llpc/tool/amdllpc.cpp index f0847a6196..4aaee3e7b9 100644 --- a/llpc/tool/amdllpc.cpp +++ b/llpc/tool/amdllpc.cpp @@ -303,12 +303,24 @@ cl::opt DumpDuplicatePipelines( // -llpc_opt: Override the optimization level passed in to LGC with the given one. This options is the same as the // `-opt` option in lgc. The reason for the second option is to be able to test the LLPC API. If both options are set // then `-opt` wins. + +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 +// Old version of the code cl::opt LlpcOptLevel("llpc-opt", cl::desc("The optimization level for amdllpc to pass to LLPC:"), cl::init(CodeGenOpt::Default), values(clEnumValN(CodeGenOpt::None, "none", "no optimizations"), clEnumValN(CodeGenOpt::Less, "quick", "quick compilation time"), clEnumValN(CodeGenOpt::Default, "default", "default optimizations"), clEnumValN(CodeGenOpt::Aggressive, "fast", "fast execution time"))); +#else + // New version of the code (also handles unknown version, which we treat as latest) +cl::opt LlpcOptLevel("llpc-opt", cl::desc("The optimization level for amdllpc to pass to LLPC:"), + cl::init(CodeGenOptLevel::Default), + values(clEnumValN(CodeGenOptLevel::None, "none", "no optimizations"), + clEnumValN(CodeGenOptLevel::Less, "quick", "quick compilation time"), + clEnumValN(CodeGenOptLevel::Default, "default", "default optimizations"), + clEnumValN(CodeGenOptLevel::Aggressive, "fast", "fast execution time"))); +#endif // -resource-layout-scheme: specifies the layout scheme of the resource cl::opt LayoutScheme("resource-layout-scheme", cl::desc("The resource layout scheme:"), @@ -534,8 +546,16 @@ static void initCompileInfo(CompileInfo *compileInfo) { } // We want the default optimization level to be "Default" which is not 0. - compileInfo->gfxPipelineInfo.options.optimizationLevel = CodeGenOpt::Level::Default; - compileInfo->compPipelineInfo.options.optimizationLevel = CodeGenOpt::Level::Default; +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code + compileInfo->gfxPipelineInfo.options.optimizationLevel = static_cast(CodeGenOpt::Level::Default); + compileInfo->compPipelineInfo.options.optimizationLevel = static_cast(CodeGenOpt::Level::Default); +#else + // New version of the code (also handles unknown version, which we treat as latest) + compileInfo->gfxPipelineInfo.options.optimizationLevel = static_cast(CodeGenOptLevel::Default); + compileInfo->compPipelineInfo.options.optimizationLevel = static_cast(CodeGenOptLevel::Default); +#endif + compileInfo->gfxPipelineInfo.options.resourceLayoutScheme = LayoutScheme; compileInfo->compPipelineInfo.options.forceCsThreadIdSwizzling = ForceCsThreadIdSwizzling; compileInfo->compPipelineInfo.options.overrideThreadGroupSizeX = OverrideThreadGroupSizeX; diff --git a/llpc/tool/llpcCompilationUtils.h b/llpc/tool/llpcCompilationUtils.h index 456da7c854..dc22245d57 100644 --- a/llpc/tool/llpcCompilationUtils.h +++ b/llpc/tool/llpcCompilationUtils.h @@ -103,8 +103,14 @@ struct CompileInfo { bool scratchAccessBoundsChecks; // Whether to enable scratch access bounds checks bool enableImplicitInvariantExports; // Whether to enable implicit marking of position exports as invariant VfxPipelineType pipelineType; // Pipeline type +#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768 + // Old version of the code std::optional optimizationLevel; // The optimization level to pass the compiler - bool internalRtShaders; // Whether to enable intrinsics for internal RT shaders +#else + // New version of the code (also handles unknown version, which we treat as latest) + std::optional optimizationLevel; // The optimization level to pass the compiler +#endif + bool internalRtShaders; // Whether to enable intrinsics for internal RT shaders bool enableColorExportShader; // Enable color export shader, only compile each stage of the pipeline without linking }; diff --git a/llpc/tool/llpcComputePipelineBuilder.cpp b/llpc/tool/llpcComputePipelineBuilder.cpp index e81db59926..0c416bb1c3 100644 --- a/llpc/tool/llpcComputePipelineBuilder.cpp +++ b/llpc/tool/llpcComputePipelineBuilder.cpp @@ -138,7 +138,7 @@ Expected ComputePipelineBuilder::buildComputePipeline() { pipelineInfo->options.overrideThreadGroupSizeY = compileInfo.compPipelineInfo.options.overrideThreadGroupSizeY; pipelineInfo->options.overrideThreadGroupSizeZ = compileInfo.compPipelineInfo.options.overrideThreadGroupSizeZ; if (compileInfo.optimizationLevel.has_value()) { - pipelineInfo->options.optimizationLevel = compileInfo.optimizationLevel.value(); + pipelineInfo->options.optimizationLevel = static_cast(compileInfo.optimizationLevel.value()); } pipelineInfo->options.threadGroupSwizzleMode = compileInfo.compPipelineInfo.options.threadGroupSwizzleMode; pipelineInfo->options.reverseThreadGroup = compileInfo.compPipelineInfo.options.reverseThreadGroup; diff --git a/llpc/tool/llpcGraphicsPipelineBuilder.cpp b/llpc/tool/llpcGraphicsPipelineBuilder.cpp index 778a0da096..cdbe175080 100644 --- a/llpc/tool/llpcGraphicsPipelineBuilder.cpp +++ b/llpc/tool/llpcGraphicsPipelineBuilder.cpp @@ -154,7 +154,7 @@ Expected GraphicsPipelineBuilder::buildGraphicsPipeline() { pipelineInfo->options.enableScratchAccessBoundsChecks = compileInfo.scratchAccessBoundsChecks; pipelineInfo->options.enableImplicitInvariantExports = compileInfo.enableImplicitInvariantExports; if (compileInfo.optimizationLevel.has_value()) { - pipelineInfo->options.optimizationLevel = compileInfo.optimizationLevel.value(); + pipelineInfo->options.optimizationLevel = static_cast(compileInfo.optimizationLevel.value()); } pipelineInfo->options.internalRtShaders = compileInfo.internalRtShaders; pipelineInfo->enableColorExportShader |= compileInfo.enableColorExportShader;