[Kaleidoscope] Switch to the new PassManager, revisited. (#72324)
Rollforward of #69032, which was reverted in
[63d19cf](63d19cfd85
).
New: implemented changes in
https://github.com/llvm/llvm-project/pull/69032#issuecomment-1809250162.
Given the PassBuilder is how we expect users to register passes, the
tutorial should reflect that.
This commit is contained in:
parent
4ac5b0da8d
commit
3d2527ebe3
@ -94,14 +94,6 @@ use, in the form of "passes".
|
||||
LLVM Optimization Passes
|
||||
========================
|
||||
|
||||
.. warning::
|
||||
|
||||
Due to the transition to the new PassManager infrastructure this tutorial
|
||||
is based on ``llvm::legacy::FunctionPassManager`` which can be found in
|
||||
`LegacyPassManager.h <https://llvm.org/doxygen/classllvm_1_1legacy_1_1FunctionPassManager.html>`_.
|
||||
For the purpose of the this tutorial the above should be used until
|
||||
the pass manager transition is complete.
|
||||
|
||||
LLVM provides many optimization passes, which do many different sorts of
|
||||
things and have different tradeoffs. Unlike other systems, LLVM doesn't
|
||||
hold to the mistaken notion that one set of optimizations is right for
|
||||
@ -127,44 +119,80 @@ 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>();
|
||||
TheLAM = std::make_unique<LoopAnalysisManager>();
|
||||
TheFAM = std::make_unique<FunctionAnalysisManager>();
|
||||
TheCGAM = std::make_unique<CGSCCAnalysisManager>();
|
||||
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 four AnalysisManagers
|
||||
allow us to add analysis passes that run across the four levels of the IR
|
||||
hierarchy. 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.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Register analysis passes used in these transform passes.
|
||||
PassBuilder PB;
|
||||
PB.registerModuleAnalyses(*TheMAM);
|
||||
PB.registerFunctionAnalyses(*TheFAM);
|
||||
PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
|
||||
}
|
||||
|
||||
Once the PassManager is set up, we need to make use of it. We do this by
|
||||
running it after our newly created function is constructed (in
|
||||
``FunctionAST::codegen()``), but before it is returned to the client:
|
||||
@ -179,7 +207,7 @@ running it after our newly created function is constructed (in
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Optimize the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
|
@ -7,15 +7,19 @@
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/Passes/StandardInstrumentations.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
@ -413,8 +417,14 @@ static std::unique_ptr<LLVMContext> TheContext;
|
||||
static std::unique_ptr<Module> TheModule;
|
||||
static std::unique_ptr<IRBuilder<>> Builder;
|
||||
static std::map<std::string, Value *> NamedValues;
|
||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<LoopAnalysisManager> TheLAM;
|
||||
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||
static std::unique_ptr<CGSCCAnalysisManager> TheCGAM;
|
||||
static std::unique_ptr<ModuleAnalysisManager> TheMAM;
|
||||
static std::unique_ptr<PassInstrumentationCallbacks> ThePIC;
|
||||
static std::unique_ptr<StandardInstrumentations> TheSI;
|
||||
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||
static ExitOnError ExitOnErr;
|
||||
|
||||
@ -535,7 +545,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -549,28 +559,41 @@ Function *FunctionAST::codegen() {
|
||||
// Top-Level parsing and JIT Driver
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void InitializeModuleAndPassManager() {
|
||||
static void InitializeModuleAndManagers() {
|
||||
// Open a new context and module.
|
||||
TheContext = std::make_unique<LLVMContext>();
|
||||
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
|
||||
TheModule = std::make_unique<Module>("KaleidoscopeJIT", *TheContext);
|
||||
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||
|
||||
// Create a new builder for the module.
|
||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||
|
||||
// Create a new pass manager attached to it.
|
||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
||||
// Create new pass and analysis managers.
|
||||
TheFPM = std::make_unique<FunctionPassManager>();
|
||||
TheLAM = std::make_unique<LoopAnalysisManager>();
|
||||
TheFAM = std::make_unique<FunctionAnalysisManager>();
|
||||
TheCGAM = std::make_unique<CGSCCAnalysisManager>();
|
||||
TheMAM = std::make_unique<ModuleAnalysisManager>();
|
||||
ThePIC = std::make_unique<PassInstrumentationCallbacks>();
|
||||
TheSI = std::make_unique<StandardInstrumentations>(*TheContext,
|
||||
/*DebugLogging*/ true);
|
||||
TheSI->registerCallbacks(*ThePIC, TheMAM.get());
|
||||
|
||||
// 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->addPass(SimplifyCFGPass());
|
||||
|
||||
TheFPM->doInitialization();
|
||||
// Register analysis passes used in these transform passes.
|
||||
PassBuilder PB;
|
||||
PB.registerModuleAnalyses(*TheMAM);
|
||||
PB.registerFunctionAnalyses(*TheFAM);
|
||||
PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
|
||||
}
|
||||
|
||||
static void HandleDefinition() {
|
||||
@ -581,7 +604,7 @@ static void HandleDefinition() {
|
||||
fprintf(stderr, "\n");
|
||||
ExitOnErr(TheJIT->addModule(
|
||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
}
|
||||
} else {
|
||||
// Skip token for error recovery.
|
||||
@ -613,7 +636,7 @@ static void HandleTopLevelExpression() {
|
||||
|
||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Search the JIT for the __anon_expr symbol.
|
||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||
@ -699,7 +722,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
@ -8,15 +8,19 @@
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/Passes/StandardInstrumentations.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
@ -540,8 +544,14 @@ static std::unique_ptr<LLVMContext> TheContext;
|
||||
static std::unique_ptr<Module> TheModule;
|
||||
static std::unique_ptr<IRBuilder<>> Builder;
|
||||
static std::map<std::string, Value *> NamedValues;
|
||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<LoopAnalysisManager> TheLAM;
|
||||
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||
static std::unique_ptr<CGSCCAnalysisManager> TheCGAM;
|
||||
static std::unique_ptr<ModuleAnalysisManager> TheMAM;
|
||||
static std::unique_ptr<PassInstrumentationCallbacks> ThePIC;
|
||||
static std::unique_ptr<StandardInstrumentations> TheSI;
|
||||
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||
static ExitOnError ExitOnErr;
|
||||
|
||||
@ -809,7 +819,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -823,28 +833,41 @@ Function *FunctionAST::codegen() {
|
||||
// Top-Level parsing and JIT Driver
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void InitializeModuleAndPassManager() {
|
||||
// Open a new module.
|
||||
static void InitializeModuleAndManagers() {
|
||||
// Open a new context and module.
|
||||
TheContext = std::make_unique<LLVMContext>();
|
||||
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
|
||||
TheModule = std::make_unique<Module>("KaleidoscopeJIT", *TheContext);
|
||||
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||
|
||||
// Create a new builder for the module.
|
||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||
|
||||
// Create a new pass manager attached to it.
|
||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
||||
// Create new pass and analysis managers.
|
||||
TheFPM = std::make_unique<FunctionPassManager>();
|
||||
TheLAM = std::make_unique<LoopAnalysisManager>();
|
||||
TheFAM = std::make_unique<FunctionAnalysisManager>();
|
||||
TheCGAM = std::make_unique<CGSCCAnalysisManager>();
|
||||
TheMAM = std::make_unique<ModuleAnalysisManager>();
|
||||
ThePIC = std::make_unique<PassInstrumentationCallbacks>();
|
||||
TheSI = std::make_unique<StandardInstrumentations>(*TheContext,
|
||||
/*DebugLogging*/ true);
|
||||
TheSI->registerCallbacks(*ThePIC, TheMAM.get());
|
||||
|
||||
// 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->addPass(SimplifyCFGPass());
|
||||
|
||||
TheFPM->doInitialization();
|
||||
// Register analysis passes used in these transform passes.
|
||||
PassBuilder PB;
|
||||
PB.registerModuleAnalyses(*TheMAM);
|
||||
PB.registerFunctionAnalyses(*TheFAM);
|
||||
PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
|
||||
}
|
||||
|
||||
static void HandleDefinition() {
|
||||
@ -855,7 +878,7 @@ static void HandleDefinition() {
|
||||
fprintf(stderr, "\n");
|
||||
ExitOnErr(TheJIT->addModule(
|
||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
}
|
||||
} else {
|
||||
// Skip token for error recovery.
|
||||
@ -887,7 +910,7 @@ static void HandleTopLevelExpression() {
|
||||
|
||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Search the JIT for the __anon_expr symbol.
|
||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||
@ -973,7 +996,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
@ -8,15 +8,19 @@
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/Passes/StandardInstrumentations.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
@ -632,8 +636,14 @@ static std::unique_ptr<LLVMContext> TheContext;
|
||||
static std::unique_ptr<Module> TheModule;
|
||||
static std::unique_ptr<IRBuilder<>> Builder;
|
||||
static std::map<std::string, Value *> NamedValues;
|
||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<LoopAnalysisManager> TheLAM;
|
||||
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||
static std::unique_ptr<CGSCCAnalysisManager> TheCGAM;
|
||||
static std::unique_ptr<ModuleAnalysisManager> TheMAM;
|
||||
static std::unique_ptr<PassInstrumentationCallbacks> ThePIC;
|
||||
static std::unique_ptr<StandardInstrumentations> TheSI;
|
||||
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||
static ExitOnError ExitOnErr;
|
||||
|
||||
@ -925,7 +935,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -942,28 +952,41 @@ Function *FunctionAST::codegen() {
|
||||
// Top-Level parsing and JIT Driver
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void InitializeModuleAndPassManager() {
|
||||
// Open a new module.
|
||||
static void InitializeModuleAndManagers() {
|
||||
// Open a new context and module.
|
||||
TheContext = std::make_unique<LLVMContext>();
|
||||
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
|
||||
TheModule = std::make_unique<Module>("KaleidoscopeJIT", *TheContext);
|
||||
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||
|
||||
// Create a new builder for the module.
|
||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||
|
||||
// Create a new pass manager attached to it.
|
||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
||||
// Create new pass and analysis managers.
|
||||
TheFPM = std::make_unique<FunctionPassManager>();
|
||||
TheLAM = std::make_unique<LoopAnalysisManager>();
|
||||
TheFAM = std::make_unique<FunctionAnalysisManager>();
|
||||
TheCGAM = std::make_unique<CGSCCAnalysisManager>();
|
||||
TheMAM = std::make_unique<ModuleAnalysisManager>();
|
||||
ThePIC = std::make_unique<PassInstrumentationCallbacks>();
|
||||
TheSI = std::make_unique<StandardInstrumentations>(*TheContext,
|
||||
/*DebugLogging*/ true);
|
||||
TheSI->registerCallbacks(*ThePIC, TheMAM.get());
|
||||
|
||||
// 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->addPass(SimplifyCFGPass());
|
||||
|
||||
TheFPM->doInitialization();
|
||||
// Register analysis passes used in these transform passes.
|
||||
PassBuilder PB;
|
||||
PB.registerModuleAnalyses(*TheMAM);
|
||||
PB.registerFunctionAnalyses(*TheFAM);
|
||||
PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
|
||||
}
|
||||
|
||||
static void HandleDefinition() {
|
||||
@ -974,7 +997,7 @@ static void HandleDefinition() {
|
||||
fprintf(stderr, "\n");
|
||||
ExitOnErr(TheJIT->addModule(
|
||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
}
|
||||
} else {
|
||||
// Skip token for error recovery.
|
||||
@ -1006,7 +1029,7 @@ static void HandleTopLevelExpression() {
|
||||
|
||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Search the JIT for the __anon_expr symbol.
|
||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||
@ -1092,7 +1115,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
@ -8,15 +8,19 @@
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/Passes/StandardInstrumentations.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||
#include "llvm/Transforms/Utils.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@ -705,8 +709,14 @@ static std::unique_ptr<LLVMContext> TheContext;
|
||||
static std::unique_ptr<Module> TheModule;
|
||||
static std::unique_ptr<IRBuilder<>> Builder;
|
||||
static std::map<std::string, AllocaInst *> NamedValues;
|
||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||
static std::unique_ptr<LoopAnalysisManager> TheLAM;
|
||||
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||
static std::unique_ptr<CGSCCAnalysisManager> TheCGAM;
|
||||
static std::unique_ptr<ModuleAnalysisManager> TheMAM;
|
||||
static std::unique_ptr<PassInstrumentationCallbacks> ThePIC;
|
||||
static std::unique_ptr<StandardInstrumentations> TheSI;
|
||||
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||
static ExitOnError ExitOnErr;
|
||||
|
||||
@ -1094,7 +1104,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -1111,30 +1121,41 @@ Function *FunctionAST::codegen() {
|
||||
// Top-Level parsing and JIT Driver
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void InitializeModuleAndPassManager() {
|
||||
// Open a new module.
|
||||
static void InitializeModuleAndManagers() {
|
||||
// Open a new context and module.
|
||||
TheContext = std::make_unique<LLVMContext>();
|
||||
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
|
||||
TheModule = std::make_unique<Module>("KaleidoscopeJIT", *TheContext);
|
||||
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||
|
||||
// Create a new builder for the module.
|
||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||
|
||||
// Create a new pass manager attached to it.
|
||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
||||
// Create new pass and analysis managers.
|
||||
TheFPM = std::make_unique<FunctionPassManager>();
|
||||
TheLAM = std::make_unique<LoopAnalysisManager>();
|
||||
TheFAM = std::make_unique<FunctionAnalysisManager>();
|
||||
TheCGAM = std::make_unique<CGSCCAnalysisManager>();
|
||||
TheMAM = std::make_unique<ModuleAnalysisManager>();
|
||||
ThePIC = std::make_unique<PassInstrumentationCallbacks>();
|
||||
TheSI = std::make_unique<StandardInstrumentations>(*TheContext,
|
||||
/*DebugLogging*/ true);
|
||||
TheSI->registerCallbacks(*ThePIC, TheMAM.get());
|
||||
|
||||
// Promote allocas to registers.
|
||||
TheFPM->add(createPromoteMemoryToRegisterPass());
|
||||
// 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->addPass(SimplifyCFGPass());
|
||||
|
||||
TheFPM->doInitialization();
|
||||
// Register analysis passes used in these transform passes.
|
||||
PassBuilder PB;
|
||||
PB.registerModuleAnalyses(*TheMAM);
|
||||
PB.registerFunctionAnalyses(*TheFAM);
|
||||
PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
|
||||
}
|
||||
|
||||
static void HandleDefinition() {
|
||||
@ -1145,7 +1166,7 @@ static void HandleDefinition() {
|
||||
fprintf(stderr, "\n");
|
||||
ExitOnErr(TheJIT->addModule(
|
||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
}
|
||||
} else {
|
||||
// Skip token for error recovery.
|
||||
@ -1177,7 +1198,7 @@ static void HandleTopLevelExpression() {
|
||||
|
||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Search the JIT for the __anon_expr symbol.
|
||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||
@ -1264,7 +1285,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
Loading…
x
Reference in New Issue
Block a user