Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 22f2a94

Browse files
committed
Start porting the lowering passes to the new pass manager
This PR starts porting the lowering passes added in SpirvLower::addPasses to the new pass manager. It also makes some changes to the infrastructure for the new pass manager to allow adding function analyses.
1 parent f046278 commit 22f2a94

9 files changed

Lines changed: 142 additions & 28 deletions

File tree

lgc/interface/lgc/LgcContext.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,18 @@ class LgcContext {
108108
// @param useBuilderRecorder : True to use BuilderRecorder, false to use BuilderImpl
109109
Builder *createBuilder(Pipeline *pipeline, bool useBuilderRecorder);
110110

111-
// Prepare a pass manager. This manually adds a target-aware TLI pass, so middle-end optimizations do not
111+
// Prepare a legacy pass manager. This manually adds a target-aware TLI pass, so middle-end optimizations do not
112112
// think that we have library functions.
113113
//
114114
// @param [in/out] passMgr : Pass manager
115115
void preparePassManager(llvm::legacy::PassManager *passMgr);
116116

117+
// Prepare a pass manager. This manually adds a target-aware TLI pass, so middle-end optimizations do not
118+
// think that we have library functions.
119+
//
120+
// @param [in/out] passMgr : Pass manager
121+
void preparePassManager(lgc::PassManager &passMgr);
122+
117123
// Adds target passes to pass manager, depending on "-filetype" and "-emit-llvm" options
118124
void addTargetPasses(lgc::LegacyPassManager &passMgr, llvm::Timer *codeGenTimer, llvm::raw_pwrite_stream &outStream);
119125

lgc/interface/lgc/PassManager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,14 @@ class PassManager : public llvm::ModulePassManager {
5151
public:
5252
static PassManager *Create();
5353
virtual ~PassManager() {}
54+
template <typename PassBuilderT> bool registerFunctionAnalysis(PassBuilderT &&PassBuilder) {
55+
return functionAnalysisManager.registerPass(std::forward<PassBuilderT>(PassBuilder));
56+
}
5457
virtual void run(llvm::Module &module) = 0;
5558
virtual void setPassIndex(unsigned *passIndex) = 0;
59+
60+
protected:
61+
llvm::FunctionAnalysisManager functionAnalysisManager;
5662
};
5763

5864
} // namespace lgc

lgc/state/LgcContext.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,25 @@ void LgcContext::preparePassManager(legacy::PassManager *passMgr) {
268268
passMgr->add(targetLibInfoPass);
269269
}
270270

271+
// =====================================================================================================================
272+
// Prepare a pass manager. This manually adds a target-aware TLI pass, so middle-end optimizations do not think that
273+
// we have library functions.
274+
//
275+
// @param [in/out] passMgr : Pass manager
276+
void LgcContext::preparePassManager(lgc::PassManager &passMgr) {
277+
TargetLibraryInfoImpl targetLibInfo(getTargetMachine()->getTargetTriple());
278+
279+
// Adjust it to allow memcpy and memset.
280+
// TODO: Investigate why the latter is necessary. I found that
281+
// test/shaderdb/ObjStorageBlock_TestMemCpyInt32.comp
282+
// got unrolled far too much, and at too late a stage for the descriptor loads to be commoned up. It might
283+
// be an unfortunate interaction between LoopIdiomRecognize and fat pointer laundering.
284+
targetLibInfo.setAvailable(LibFunc_memcpy);
285+
targetLibInfo.setAvailable(LibFunc_memset);
286+
287+
passMgr.registerFunctionAnalysis([&] { return TargetLibraryAnalysis(targetLibInfo); });
288+
}
289+
271290
// =====================================================================================================================
272291
// Adds target passes to pass manager, depending on "-filetype" and "-emit-llvm" options
273292
//

lgc/util/PassManager.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,11 @@ class PassManagerImpl final : public lgc::PassManager {
9898

9999
// -----------------------------------------------------------------------------------------------------------------
100100

101-
ModuleAnalysisManager analysisManager; // Analysis manager used when running the passes.
101+
ModuleAnalysisManager moduleAnalysisManager; // Module analysis manager used when running the passes.
102102
PassInstrumentationCallbacks instrCallbacks; // Instrumentation callbacks ran when running the passes.
103103
VerifyInstrumentation instrVerify; // Verify instrumentation, run module verifier after each pass.
104-
unsigned *m_passIndex = nullptr; // Pass Index
104+
unsigned *m_passIndex = nullptr; // Pass Index.
105+
bool initialized = false; // Wether the pass manager is initialized or not.
105106
};
106107

107108
} // namespace
@@ -167,16 +168,23 @@ PassManagerImpl::PassManagerImpl() : PassManager(), instrVerify(getLgcOuts()) {
167168
registerCallbacks();
168169
if (cl::VerifyIr)
169170
instrVerify.registerCallbacks(instrCallbacks);
170-
PassBuilder passBuilder(nullptr, PipelineTuningOptions(), None, &instrCallbacks);
171-
passBuilder.registerModuleAnalyses(analysisManager);
172171
}
173172

174173
// =====================================================================================================================
175174
// Run all the added passes with the pass managers's module analysis manager
176175
//
177176
// @param module : Module to run the passes on
178177
void PassManagerImpl::run(Module &module) {
179-
ModulePassManager::run(module, analysisManager);
178+
// We register LLVM's default analysis sets late to be sure our custom
179+
// analyses are added beforehand.
180+
if (!initialized) {
181+
PassBuilder passBuilder(nullptr, PipelineTuningOptions(), None, &instrCallbacks);
182+
passBuilder.registerModuleAnalyses(moduleAnalysisManager);
183+
passBuilder.registerFunctionAnalyses(functionAnalysisManager);
184+
moduleAnalysisManager.registerPass([&] { return FunctionAnalysisManagerModuleProxy(functionAnalysisManager); });
185+
initialized = true;
186+
}
187+
ModulePassManager::run(module, moduleAnalysisManager);
180188
}
181189

182190
// =====================================================================================================================

llpc/context/llpcCompiler.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,13 +1304,22 @@ Result Compiler::buildPipelineInternal(Context *context, ArrayRef<const Pipeline
13041304
}
13051305

13061306
context->getBuilder()->setShaderStage(getLgcShaderStage(entryStage));
1307-
std::unique_ptr<lgc::LegacyPassManager> lowerPassMgr(lgc::LegacyPassManager::Create());
1308-
lowerPassMgr->setPassIndex(&passIndex);
1307+
bool success;
1308+
if (cl::NewPassManager) {
1309+
std::unique_ptr<lgc::PassManager> lowerPassMgr(lgc::PassManager::Create());
1310+
lowerPassMgr->setPassIndex(&passIndex);
1311+
1312+
SpirvLower::addPasses(context, entryStage, *lowerPassMgr, timerProfiler.getTimer(TimerLower));
1313+
// Run the passes.
1314+
success = runPasses(&*lowerPassMgr, modules[shaderIndex]);
1315+
} else {
1316+
std::unique_ptr<lgc::LegacyPassManager> lowerPassMgr(lgc::LegacyPassManager::Create());
1317+
lowerPassMgr->setPassIndex(&passIndex);
13091318

1310-
LegacySpirvLower::addPasses(context, entryStage, *lowerPassMgr, timerProfiler.getTimer(TimerLower)
1311-
);
1312-
// Run the passes.
1313-
bool success = runPasses(&*lowerPassMgr, modules[shaderIndex]);
1319+
LegacySpirvLower::addPasses(context, entryStage, *lowerPassMgr, timerProfiler.getTimer(TimerLower));
1320+
// Run the passes.
1321+
success = runPasses(&*lowerPassMgr, modules[shaderIndex]);
1322+
}
13141323
if (!success) {
13151324
LLPC_ERRS("Failed to translate SPIR-V or run per-shader passes\n");
13161325
result = Result::ErrorInvalidShader;
@@ -1970,6 +1979,9 @@ bool Compiler::runPasses(lgc::PassManager *passMgr, Module *module) const {
19701979
{
19711980
passMgr->run(*module);
19721981
success = true;
1982+
// TODO Only some passes have been ported to the new pass manager. So running
1983+
// the lowering passes with the new pass manager results in a fatal error for now.
1984+
report_fatal_error("The new pass manager is not fully implemented yet.");
19731985
}
19741986
#if LLPC_ENABLE_EXCEPTION
19751987
catch (const char *) {

llpc/lower/llpcSpirvLower.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llpcSpirvLower.h"
3232
#include "llpcContext.h"
3333
#include "llpcDebug.h"
34+
#include "llpcSpirvLowerAccessChain.h"
3435
#include "llpcSpirvLowerUtil.h"
3536
#include "lgc/Builder.h"
3637
#include "lgc/LgcContext.h"
@@ -44,6 +45,7 @@
4445
#include "llvm/Transforms/IPO/AlwaysInliner.h"
4546
#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
4647
#include "llvm/Transforms/IPO/FunctionAttrs.h"
48+
#include "llvm/Transforms/IPO/GlobalDCE.h"
4749
#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
4850
#include "llvm/Transforms/InstCombine/InstCombine.h"
4951
#include "llvm/Transforms/Instrumentation.h"
@@ -138,6 +140,30 @@ void SpirvLower::removeConstantExpr(Context *context, GlobalVariable *global) {
138140
replaceConstWithInsts(context, constVal);
139141
}
140142

143+
// =====================================================================================================================
144+
// Add per-shader lowering passes to pass manager
145+
//
146+
// @param context : LLPC context
147+
// @param stage : Shader stage
148+
// @param [in/out] passMgr : Pass manager to add passes to
149+
// @param lowerTimer : Timer to time lower passes with, nullptr if not timing
150+
void SpirvLower::addPasses(Context *context, ShaderStage stage, lgc::PassManager &passMgr, Timer *lowerTimer) {
151+
// Manually add a target-aware TLI pass, so optimizations do not think that we have library functions.
152+
context->getLgcContext()->preparePassManager(passMgr);
153+
154+
// Start timer for lowering passes.
155+
if (lowerTimer)
156+
LgcContext::createAndAddStartStopTimer(passMgr, lowerTimer, true);
157+
158+
// Function inlining. Use the "always inline" pass, since we want to inline all functions, and
159+
// we marked (non-entrypoint) functions as "always inline" just after SPIR-V reading.
160+
passMgr.addPass(AlwaysInlinerPass());
161+
passMgr.addPass(GlobalDCEPass());
162+
163+
// Lower SPIR-V access chain
164+
passMgr.addPass(SpirvLowerAccessChain());
165+
}
166+
141167
// =====================================================================================================================
142168
// Add per-shader lowering passes to pass manager
143169
//
@@ -160,7 +186,7 @@ void LegacySpirvLower::addPasses(Context *context, ShaderStage stage, legacy::Pa
160186
passMgr.add(createGlobalDCEPass());
161187

162188
// Lower SPIR-V access chain
163-
passMgr.add(createSpirvLowerAccessChain());
189+
passMgr.add(createLegacySpirvLowerAccessChain());
164190

165191
// Lower SPIR-V terminators
166192
passMgr.add(createSpirvLowerTerminator());

llpc/lower/llpcSpirvLower.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class PassManager;
4747
} // namespace legacy
4848

4949
class PassRegistry;
50-
void initializeSpirvLowerAccessChainPass(PassRegistry &);
50+
void initializeLegacySpirvLowerAccessChainPass(PassRegistry &);
5151
void initializeSpirvLowerMathConstFoldingPass(PassRegistry &);
5252
void initializeSpirvLowerMathFloatOpPass(PassRegistry &);
5353
void initializeSpirvLowerConstImmediateStorePass(PassRegistry &);
@@ -62,6 +62,7 @@ void initializeLegacySpirvLowerTranslatorPass(PassRegistry &);
6262
namespace lgc {
6363

6464
class Builder;
65+
class PassManager;
6566

6667
} // namespace lgc
6768

@@ -71,7 +72,7 @@ namespace Llpc {
7172
//
7273
// @param passRegistry : Pass registry
7374
inline static void initializeLowerPasses(llvm::PassRegistry &passRegistry) {
74-
initializeSpirvLowerAccessChainPass(passRegistry);
75+
initializeLegacySpirvLowerAccessChainPass(passRegistry);
7576
initializeSpirvLowerConstImmediateStorePass(passRegistry);
7677
initializeSpirvLowerMathConstFoldingPass(passRegistry);
7778
initializeSpirvLowerMathFloatOpPass(passRegistry);
@@ -85,7 +86,7 @@ inline static void initializeLowerPasses(llvm::PassRegistry &passRegistry) {
8586

8687
class Context;
8788

88-
llvm::ModulePass *createSpirvLowerAccessChain();
89+
llvm::ModulePass *createLegacySpirvLowerAccessChain();
8990
llvm::ModulePass *createSpirvLowerConstImmediateStore();
9091
llvm::ModulePass *createSpirvLowerMathConstFolding();
9192
llvm::ModulePass *createSpirvLowerMathFloatOp();
@@ -103,6 +104,9 @@ class SpirvLower {
103104
explicit SpirvLower()
104105
: m_module(nullptr), m_context(nullptr), m_shaderStage(ShaderStageInvalid), m_entryPoint(nullptr) {}
105106

107+
// Add per-shader lowering passes to pass manager
108+
static void addPasses(Context *context, ShaderStage stage, lgc::PassManager &passMgr, llvm::Timer *lowerTimer);
109+
106110
static void removeConstantExpr(Context *context, llvm::GlobalVariable *global);
107111
static void replaceConstWithInsts(Context *context, llvm::Constant *const constVal);
108112

llpc/lower/llpcSpirvLowerAccessChain.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,41 @@ namespace Llpc {
4545

4646
// =====================================================================================================================
4747
// Initializes static members.
48-
char SpirvLowerAccessChain::ID = 0;
48+
char LegacySpirvLowerAccessChain::ID = 0;
4949

5050
// =====================================================================================================================
5151
// Pass creator, creates the pass of SPIR-V lowering operations for access chain
52-
ModulePass *createSpirvLowerAccessChain() {
53-
return new SpirvLowerAccessChain();
52+
ModulePass *createLegacySpirvLowerAccessChain() {
53+
return new LegacySpirvLowerAccessChain();
5454
}
5555

5656
// =====================================================================================================================
57-
SpirvLowerAccessChain::SpirvLowerAccessChain() : LegacySpirvLower(ID) {
57+
LegacySpirvLowerAccessChain::LegacySpirvLowerAccessChain() : LegacySpirvLower(ID) {
5858
}
5959

6060
// =====================================================================================================================
6161
// Executes this SPIR-V lowering pass on the specified LLVM module.
6262
//
6363
// @param [in/out] module : LLVM module to be run on
64-
bool SpirvLowerAccessChain::runOnModule(Module &module) {
64+
bool LegacySpirvLowerAccessChain::runOnModule(Module &module) {
65+
return Impl.runImpl(module);
66+
}
67+
68+
// =====================================================================================================================
69+
// Executes this SPIR-V lowering pass on the specified LLVM module.
70+
//
71+
// @param [in/out] module : LLVM module to be run on
72+
// @param [in/out] analysisManager : Analysis manager to use for this transformation
73+
PreservedAnalyses SpirvLowerAccessChain::run(llvm::Module &module, llvm::ModuleAnalysisManager &analysisManager) {
74+
runImpl(module);
75+
return PreservedAnalyses::none();
76+
}
77+
78+
// =====================================================================================================================
79+
// Executes this SPIR-V lowering pass on the specified LLVM module.
80+
//
81+
// @param [in/out] module : LLVM module to be run on
82+
bool SpirvLowerAccessChain::runImpl(llvm::Module &module) {
6583
LLVM_DEBUG(dbgs() << "Run the pass Spirv-Lower-Access-Chain\n");
6684

6785
SpirvLower::init(&module);
@@ -170,4 +188,4 @@ GetElementPtrInst *SpirvLowerAccessChain::tryToCoalesceChain(GetElementPtrInst *
170188

171189
// =====================================================================================================================
172190
// Initializes the pass of SPIR-V lowering opertions for access chain.
173-
INITIALIZE_PASS(SpirvLowerAccessChain, DEBUG_TYPE, "Lower SPIR-V access chain", false, false)
191+
INITIALIZE_PASS(LegacySpirvLowerAccessChain, DEBUG_TYPE, "Lower SPIR-V access chain", false, false)

llpc/lower/llpcSpirvLowerAccessChain.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,40 @@
3232

3333
#include "llpcSpirvLower.h"
3434
#include "llvm/IR/InstVisitor.h"
35+
#include "llvm/IR/PassManager.h"
3536

3637
namespace Llpc {
3738

3839
// =====================================================================================================================
3940
// Represents the pass of SPIR-V lowering opertions for access chain.
40-
class SpirvLowerAccessChain : public LegacySpirvLower, public llvm::InstVisitor<SpirvLowerAccessChain> {
41+
class SpirvLowerAccessChain : public SpirvLower, public llvm::InstVisitor<SpirvLowerAccessChain> {
4142
public:
42-
SpirvLowerAccessChain();
43+
llvm::PreservedAnalyses run(llvm::Module &module, llvm::ModuleAnalysisManager &analysisManager);
44+
virtual void visitGetElementPtrInst(llvm::GetElementPtrInst &getElemPtrInst);
45+
46+
bool runImpl(llvm::Module &module);
47+
48+
static llvm::StringRef name() { return "Lower SPIR-V access chain"; }
49+
50+
private:
51+
llvm::GetElementPtrInst *tryToCoalesceChain(llvm::GetElementPtrInst *getElemPtr, unsigned addrSpace);
52+
};
53+
54+
// =====================================================================================================================
55+
// Represents the pass of SPIR-V lowering opertions for access chain.
56+
class LegacySpirvLowerAccessChain : public LegacySpirvLower {
57+
public:
58+
LegacySpirvLowerAccessChain();
4359

4460
virtual bool runOnModule(llvm::Module &module);
45-
virtual void visitGetElementPtrInst(llvm::GetElementPtrInst &getElemPtrInst);
4661

4762
static char ID; // ID of this pass
4863

4964
private:
50-
SpirvLowerAccessChain(const SpirvLowerAccessChain &) = delete;
51-
SpirvLowerAccessChain &operator=(const SpirvLowerAccessChain &) = delete;
65+
LegacySpirvLowerAccessChain(const LegacySpirvLowerAccessChain &) = delete;
66+
LegacySpirvLowerAccessChain &operator=(const LegacySpirvLowerAccessChain &) = delete;
5267

53-
llvm::GetElementPtrInst *tryToCoalesceChain(llvm::GetElementPtrInst *getElemPtr, unsigned addrSpace);
68+
SpirvLowerAccessChain Impl;
5469
};
5570

5671
} // namespace Llpc

0 commit comments

Comments
 (0)