Skip to content

Commit

Permalink
Update CodeGenOpt
Browse files Browse the repository at this point in the history
There is a flag-day change around CodeGen enums in llvm/llvm-project#66295.

Update the code to use both old and new schemes depending on the LLVM version used.

Change enum to uint32_t in some places to reduce the number of include guards.
  • Loading branch information
piotrAMD committed Sep 19, 2023
1 parent 7aa4658 commit e60c1cc
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 16 deletions.
5 changes: 2 additions & 3 deletions lgc/include/lgc/patch/Patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

Expand Down
28 changes: 26 additions & 2 deletions lgc/interface/lgc/LgcContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<llvm::TargetMachine> 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.
//
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
4 changes: 2 additions & 2 deletions lgc/patch/Patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion lgc/state/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint32_t>(getLgcContext()->getOptimizationLevel()));

// Add pass to clear pipeline state from IR
passMgr->addPass(PipelineStateClearer());
Expand Down
29 changes: 27 additions & 2 deletions lgc/state/LgcContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,23 @@ static cl::opt<bool> EmitLgc("emit-lgc", cl::desc("Emit LLVM assembly suitable f
static cl::opt<bool> 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<CodeGenOpt::Level> 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<CodeGenOptLevel>
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
Expand Down Expand Up @@ -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<TargetMachine> LgcContext::createTargetMachine(StringRef gpuName, CodeGenOpt::Level optLevel) {
#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768
// Old version of the code
std::unique_ptr<TargetMachine> 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<TargetMachine> 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
Expand Down Expand Up @@ -245,7 +263,7 @@ std::unique_ptr<TargetMachine> LgcContext::createTargetMachine(StringRef gpuName
if (OptLevel.getPosition() != 0)
optLevel = OptLevel;

LLPC_OUTS("TargetMachine optimization level = " << optLevel << "\n");
LLPC_OUTS("TargetMachine optimization level = " << static_cast<uint32_t>(optLevel) << "\n");

return std::unique_ptr<TargetMachine>(target->createTargetMachine(triple, gpuName, "", targetOpts, {}, {}, optLevel));
}
Expand Down Expand Up @@ -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();
}

Expand Down
27 changes: 27 additions & 0 deletions lgc/tool/lgc/lgc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
Expand Down Expand Up @@ -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<cl::opt<CodeGenFileType> *>(opt) = CGFT_AssemblyFile;
#else
// New version of the code (also handles unknown version, which we treat as latest)
*static_cast<cl::opt<CodeGenFileType> *>(opt) = CodeGenFileType::AssemblyFile;
#endif
}

// Create the LgcContext.
#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768
// Old version of the code
std::unique_ptr<TargetMachine> 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> targetMachine(LgcContext::createTargetMachine(gpuName, CodeGenOptLevel::Default));
#endif
if (!targetMachine) {
errs() << progName << ": GPU type '" << gpuName << "' not recognized\n";
return 1;
Expand Down
32 changes: 31 additions & 1 deletion llpc/context/llpcContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint32_t>(CodeGenOpt::Level::Default);

optLevel = getPipelineContext()->getPipelineOptions()->optimizationLevel;
if (optLevel > 3)
optLevel = 3;
Expand All @@ -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<uint32_t>(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.
//
Expand Down
14 changes: 14 additions & 0 deletions llpc/context/llpcContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<llvm::Module> loadLibrary(const BinaryData *lib);

Expand Down Expand Up @@ -129,7 +136,14 @@ class Context : public llvm::LLVMContext {
std::unique_ptr<llvm::TargetMachine> m_targetMachine; // Target machine for LGC context
std::unique_ptr<lgc::LgcContext> m_builderContext; // LGC context

#if LLVM_MAIN_REVISION && LLVM_MAIN_REVISION < 474768
// Old version of the code
std::optional<llvm::CodeGenOpt::Level> m_lastOptLevel{}; // What getOptimizationLevel() last returned
#else
// New version of the code (also handles unknown version, which we treat as latest)
std::optional<llvm::CodeGenOptLevel> m_lastOptLevel{}; // What getOptimizationLevel() last returned
#endif

std::unique_ptr<llvm_dialects::DialectContext> m_dialectContext;

unsigned m_useCount = 0; // Number of times this context is used.
Expand Down
24 changes: 22 additions & 2 deletions llpc/tool/amdllpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,24 @@ cl::opt<bool> 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<CodeGenOpt::Level> 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<CodeGenOptLevel> 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<ResourceLayoutScheme> LayoutScheme("resource-layout-scheme", cl::desc("The resource layout scheme:"),
Expand Down Expand Up @@ -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<uint32_t>(CodeGenOpt::Level::Default);
compileInfo->compPipelineInfo.options.optimizationLevel = static_cast<uint32_t>(CodeGenOpt::Level::Default);
#else
// New version of the code (also handles unknown version, which we treat as latest)
compileInfo->gfxPipelineInfo.options.optimizationLevel = static_cast<uint32_t>(CodeGenOptLevel::Default);
compileInfo->compPipelineInfo.options.optimizationLevel = static_cast<uint32_t>(CodeGenOptLevel::Default);
#endif

compileInfo->gfxPipelineInfo.options.resourceLayoutScheme = LayoutScheme;
compileInfo->compPipelineInfo.options.forceCsThreadIdSwizzling = ForceCsThreadIdSwizzling;
compileInfo->compPipelineInfo.options.overrideThreadGroupSizeX = OverrideThreadGroupSizeX;
Expand Down
8 changes: 7 additions & 1 deletion llpc/tool/llpcCompilationUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<llvm::CodeGenOpt::Level> 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<llvm::CodeGenOptLevel> 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
};

Expand Down
2 changes: 1 addition & 1 deletion llpc/tool/llpcComputePipelineBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Expected<BinaryData> 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<uint32_t>(compileInfo.optimizationLevel.value());
}
pipelineInfo->options.threadGroupSwizzleMode = compileInfo.compPipelineInfo.options.threadGroupSwizzleMode;
pipelineInfo->options.reverseThreadGroup = compileInfo.compPipelineInfo.options.reverseThreadGroup;
Expand Down
Loading

0 comments on commit e60c1cc

Please sign in to comment.