[llvm] [Kaleidoscope] Switch to the new PassManager. (PR #69032)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 16 11:15:27 PDT 2023
================
@@ -127,44 +119,91 @@ in. If we wanted to make a "static Kaleidoscope compiler", we would use
exactly the code we have now, except that we would defer running the
optimizer until the entire file has been parsed.
+In addition to the distinction between function and module passes, passes can be
+divided into transform and analysis passes. Transform passes mutate the IR, and
+analysis passes compute information that other passes can use. In order to add
+a transform pass, all analysis passes it depends upon must be registered in
+advance.
+
In order to get per-function optimizations going, we need to set up a
`FunctionPassManager <../../WritingAnLLVMPass.html#what-passmanager-doesr>`_ to hold
and organize the LLVM optimizations that we want to run. Once we have
that, we can add a set of optimizations to run. We'll need a new
FunctionPassManager for each module that we want to optimize, so we'll
-write a function to create and initialize both the module and pass manager
-for us:
+add to a function created in the previous chapter (``InitializeModule()``):
.. code-block:: c++
- void InitializeModuleAndPassManager(void) {
+ void InitializeModuleAndManagers(void) {
// Open a new context and module.
- TheModule = std::make_unique<Module>("my cool jit", *TheContext);
+ TheContext = std::make_unique<LLVMContext>();
+ TheModule = std::make_unique<Module>("KaleidoscopeJIT", *TheContext);
+ TheModule->setDataLayout(TheJIT->getDataLayout());
- // Create a new pass manager attached to it.
- TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
+ // Create a new builder for the module.
+ Builder = std::make_unique<IRBuilder<>>(*TheContext);
+
+ // Create new pass and analysis managers.
+ TheFPM = std::make_unique<FunctionPassManager>();
+ TheFAM = std::make_unique<FunctionAnalysisManager>();
+ TheMAM = std::make_unique<ModuleAnalysisManager>();
+ ThePIC = std::make_unique<PassInstrumentationCallbacks>();
+ TheSI = std::make_unique<StandardInstrumentations>(*TheContext,
+ /*DebugLogging*/ true);
+ TheSI->registerCallbacks(*ThePIC, TheMAM.get());
+ ...
+After initializing the global module ``TheModule`` and the FunctionPassManager,
+we need to initialize other parts of the framework. The FunctionAnalysisManager
+and ModuleAnalysisManager allow us to add analysis passes that run across the
+function and the whole module, respectively. PassInstrumentationCallbacks
+and StandardInstrumentations are required for the pass instrumentation
+framework, which allows developers to customize what
+happens between passes.
+
+Once these managers are set up, we use a series of "addPass" calls to add a
+bunch of LLVM transform passes:
+
+.. code-block:: c++
+
+ // Add transform passes.
// Do simple "peephole" optimizations and bit-twiddling optzns.
- TheFPM->add(createInstructionCombiningPass());
+ TheFPM->addPass(InstCombinePass());
// Reassociate expressions.
- TheFPM->add(createReassociatePass());
+ TheFPM->addPass(ReassociatePass());
// Eliminate Common SubExpressions.
- TheFPM->add(createGVNPass());
+ TheFPM->addPass(GVNPass());
// Simplify the control flow graph (deleting unreachable blocks, etc).
- TheFPM->add(createCFGSimplificationPass());
-
- TheFPM->doInitialization();
- }
-
-This code initializes the global module ``TheModule``, and the function pass
-manager ``TheFPM``, which is attached to ``TheModule``. Once the pass manager is
-set up, we use a series of "add" calls to add a bunch of LLVM passes.
+ TheFPM->addPass(SimplifyCFGPass());
In this case, we choose to add four optimization passes.
The passes we choose here are a pretty standard set
of "cleanup" optimizations that are useful for a wide variety of code. I won't
delve into what they do but, believe me, they are a good starting place :).
+Next, we register the analysis passes used by the transform passes.
----------------
aeubanks wrote:
I think we should mention as an aside that this is typically done by `PassBuilder::register*Analyses()` rather than manually.
https://github.com/llvm/llvm-project/pull/69032
More information about the llvm-commits
mailing list