[Kaleidoscope] Switch to the new PassManager. (#69032)
Using the new pass manager is more verbose; let me know if the tutorial doesn't flow well with all the additions.
This commit is contained in:
parent
47ed921985
commit
7b94744e77
@ -94,14 +94,6 @@ use, in the form of "passes".
|
|||||||
LLVM Optimization 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
|
LLVM provides many optimization passes, which do many different sorts of
|
||||||
things and have different tradeoffs. Unlike other systems, LLVM doesn't
|
things and have different tradeoffs. Unlike other systems, LLVM doesn't
|
||||||
hold to the mistaken notion that one set of optimizations is right for
|
hold to the mistaken notion that one set of optimizations is right for
|
||||||
@ -127,44 +119,93 @@ 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
|
exactly the code we have now, except that we would defer running the
|
||||||
optimizer until the entire file has been parsed.
|
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
|
In order to get per-function optimizations going, we need to set up a
|
||||||
`FunctionPassManager <../../WritingAnLLVMPass.html#what-passmanager-doesr>`_ to hold
|
`FunctionPassManager <../../WritingAnLLVMPass.html#what-passmanager-doesr>`_ to hold
|
||||||
and organize the LLVM optimizations that we want to run. Once we have
|
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
|
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
|
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
|
add to a function created in the previous chapter (``InitializeModule()``):
|
||||||
for us:
|
|
||||||
|
|
||||||
.. code-block:: c++
|
.. code-block:: c++
|
||||||
|
|
||||||
void InitializeModuleAndPassManager(void) {
|
void InitializeModuleAndManagers(void) {
|
||||||
// Open a new context and module.
|
// 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.
|
// Create a new builder for the module.
|
||||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
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.
|
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
||||||
TheFPM->add(createInstructionCombiningPass());
|
TheFPM->addPass(InstCombinePass());
|
||||||
// Reassociate expressions.
|
// Reassociate expressions.
|
||||||
TheFPM->add(createReassociatePass());
|
TheFPM->addPass(ReassociatePass());
|
||||||
// Eliminate Common SubExpressions.
|
// Eliminate Common SubExpressions.
|
||||||
TheFPM->add(createGVNPass());
|
TheFPM->addPass(GVNPass());
|
||||||
// Simplify the control flow graph (deleting unreachable blocks, etc).
|
// Simplify the control flow graph (deleting unreachable blocks, etc).
|
||||||
TheFPM->add(createCFGSimplificationPass());
|
TheFPM->addPass(SimplifyCFGPass());
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
In this case, we choose to add four optimization passes.
|
In this case, we choose to add four optimization passes.
|
||||||
The passes we choose here are a pretty standard set
|
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
|
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 :).
|
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. This is
|
||||||
|
generally done using ``PassBuilder::register...Analyses()``, but we'll do it
|
||||||
|
manually to make clearer what's under the hood.
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
// Register analysis passes used in these transform passes.
|
||||||
|
TheFAM->registerPass([&] { return AAManager(); });
|
||||||
|
TheFAM->registerPass([&] { return AssumptionAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return DominatorTreeAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return LoopAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemoryDependenceAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemorySSAAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return OptimizationRemarkEmitterAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] {
|
||||||
|
return OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>(*TheMAM);
|
||||||
|
});
|
||||||
|
TheFAM->registerPass(
|
||||||
|
[&] { return PassInstrumentationAnalysis(ThePIC.get()); });
|
||||||
|
TheFAM->registerPass([&] { return TargetIRAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return TargetLibraryAnalysis(); });
|
||||||
|
|
||||||
|
TheMAM->registerPass([&] { return ProfileSummaryAnalysis(); });
|
||||||
|
}
|
||||||
|
|
||||||
Once the PassManager is set up, we need to make use of it. We do this by
|
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
|
running it after our newly created function is constructed (in
|
||||||
``FunctionAST::codegen()``), but before it is returned to the client:
|
``FunctionAST::codegen()``), but before it is returned to the client:
|
||||||
@ -179,7 +220,7 @@ running it after our newly created function is constructed (in
|
|||||||
verifyFunction(*TheFunction);
|
verifyFunction(*TheFunction);
|
||||||
|
|
||||||
// Optimize the function.
|
// Optimize the function.
|
||||||
TheFPM->run(*TheFunction);
|
TheFPM->run(*TheFunction, *TheFAM);
|
||||||
|
|
||||||
return TheFunction;
|
return TheFunction;
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,32 @@
|
|||||||
#include "../include/KaleidoscopeJIT.h"
|
#include "../include/KaleidoscopeJIT.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/AssumptionCache.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemorySSA.h"
|
||||||
|
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||||
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/IR/Type.h"
|
#include "llvm/IR/Type.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
|
#include "llvm/Passes/PassBuilder.h"
|
||||||
|
#include "llvm/Passes/StandardInstrumentations.h"
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Scalar/GVN.h"
|
#include "llvm/Transforms/Scalar/GVN.h"
|
||||||
|
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||||
|
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@ -413,8 +424,12 @@ static std::unique_ptr<LLVMContext> TheContext;
|
|||||||
static std::unique_ptr<Module> TheModule;
|
static std::unique_ptr<Module> TheModule;
|
||||||
static std::unique_ptr<IRBuilder<>> Builder;
|
static std::unique_ptr<IRBuilder<>> Builder;
|
||||||
static std::map<std::string, Value *> NamedValues;
|
static std::map<std::string, Value *> NamedValues;
|
||||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
|
||||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||||
|
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||||
|
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||||
|
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 std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||||
static ExitOnError ExitOnErr;
|
static ExitOnError ExitOnErr;
|
||||||
|
|
||||||
@ -535,7 +550,7 @@ Function *FunctionAST::codegen() {
|
|||||||
verifyFunction(*TheFunction);
|
verifyFunction(*TheFunction);
|
||||||
|
|
||||||
// Run the optimizer on the function.
|
// Run the optimizer on the function.
|
||||||
TheFPM->run(*TheFunction);
|
TheFPM->run(*TheFunction, *TheFAM);
|
||||||
|
|
||||||
return TheFunction;
|
return TheFunction;
|
||||||
}
|
}
|
||||||
@ -549,28 +564,51 @@ Function *FunctionAST::codegen() {
|
|||||||
// Top-Level parsing and JIT Driver
|
// Top-Level parsing and JIT Driver
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void InitializeModuleAndPassManager() {
|
static void InitializeModuleAndManagers() {
|
||||||
// Open a new context and module.
|
// Open a new context and module.
|
||||||
TheContext = std::make_unique<LLVMContext>();
|
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());
|
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||||
|
|
||||||
// Create a new builder for the module.
|
// Create a new builder for the module.
|
||||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||||
|
|
||||||
// Create a new pass manager attached to it.
|
// Create new pass and analysis managers.
|
||||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
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());
|
||||||
|
|
||||||
|
// Add transform passes.
|
||||||
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
||||||
TheFPM->add(createInstructionCombiningPass());
|
TheFPM->addPass(InstCombinePass());
|
||||||
// Reassociate expressions.
|
// Reassociate expressions.
|
||||||
TheFPM->add(createReassociatePass());
|
TheFPM->addPass(ReassociatePass());
|
||||||
// Eliminate Common SubExpressions.
|
// Eliminate Common SubExpressions.
|
||||||
TheFPM->add(createGVNPass());
|
TheFPM->addPass(GVNPass());
|
||||||
// Simplify the control flow graph (deleting unreachable blocks, etc).
|
// 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.
|
||||||
|
TheFAM->registerPass([&] { return AAManager(); });
|
||||||
|
TheFAM->registerPass([&] { return AssumptionAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return DominatorTreeAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return LoopAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemoryDependenceAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemorySSAAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return OptimizationRemarkEmitterAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] {
|
||||||
|
return OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>(*TheMAM);
|
||||||
|
});
|
||||||
|
TheFAM->registerPass(
|
||||||
|
[&] { return PassInstrumentationAnalysis(ThePIC.get()); });
|
||||||
|
TheFAM->registerPass([&] { return TargetIRAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return TargetLibraryAnalysis(); });
|
||||||
|
|
||||||
|
TheMAM->registerPass([&] { return ProfileSummaryAnalysis(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleDefinition() {
|
static void HandleDefinition() {
|
||||||
@ -581,7 +619,7 @@ static void HandleDefinition() {
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
ExitOnErr(TheJIT->addModule(
|
ExitOnErr(TheJIT->addModule(
|
||||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Skip token for error recovery.
|
// Skip token for error recovery.
|
||||||
@ -613,7 +651,7 @@ static void HandleTopLevelExpression() {
|
|||||||
|
|
||||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Search the JIT for the __anon_expr symbol.
|
// Search the JIT for the __anon_expr symbol.
|
||||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||||
@ -699,7 +737,7 @@ int main() {
|
|||||||
|
|
||||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||||
|
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Run the main "interpreter loop" now.
|
// Run the main "interpreter loop" now.
|
||||||
MainLoop();
|
MainLoop();
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
#include "../include/KaleidoscopeJIT.h"
|
#include "../include/KaleidoscopeJIT.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/AssumptionCache.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemorySSA.h"
|
||||||
|
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||||
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
@ -8,15 +15,19 @@
|
|||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/IR/Type.h"
|
#include "llvm/IR/Type.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
|
#include "llvm/Passes/PassBuilder.h"
|
||||||
|
#include "llvm/Passes/StandardInstrumentations.h"
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Scalar/GVN.h"
|
#include "llvm/Transforms/Scalar/GVN.h"
|
||||||
|
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||||
|
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@ -540,8 +551,12 @@ static std::unique_ptr<LLVMContext> TheContext;
|
|||||||
static std::unique_ptr<Module> TheModule;
|
static std::unique_ptr<Module> TheModule;
|
||||||
static std::unique_ptr<IRBuilder<>> Builder;
|
static std::unique_ptr<IRBuilder<>> Builder;
|
||||||
static std::map<std::string, Value *> NamedValues;
|
static std::map<std::string, Value *> NamedValues;
|
||||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
|
||||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||||
|
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||||
|
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||||
|
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 std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||||
static ExitOnError ExitOnErr;
|
static ExitOnError ExitOnErr;
|
||||||
|
|
||||||
@ -809,7 +824,7 @@ Function *FunctionAST::codegen() {
|
|||||||
verifyFunction(*TheFunction);
|
verifyFunction(*TheFunction);
|
||||||
|
|
||||||
// Run the optimizer on the function.
|
// Run the optimizer on the function.
|
||||||
TheFPM->run(*TheFunction);
|
TheFPM->run(*TheFunction, *TheFAM);
|
||||||
|
|
||||||
return TheFunction;
|
return TheFunction;
|
||||||
}
|
}
|
||||||
@ -823,28 +838,51 @@ Function *FunctionAST::codegen() {
|
|||||||
// Top-Level parsing and JIT Driver
|
// Top-Level parsing and JIT Driver
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void InitializeModuleAndPassManager() {
|
static void InitializeModuleAndManagers() {
|
||||||
// Open a new module.
|
// Open a new context and module.
|
||||||
TheContext = std::make_unique<LLVMContext>();
|
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());
|
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||||
|
|
||||||
// Create a new builder for the module.
|
// Create a new builder for the module.
|
||||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||||
|
|
||||||
// Create a new pass manager attached to it.
|
// Create new pass and analysis managers.
|
||||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
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());
|
||||||
|
|
||||||
|
// Add transform passes.
|
||||||
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
||||||
TheFPM->add(createInstructionCombiningPass());
|
TheFPM->addPass(InstCombinePass());
|
||||||
// Reassociate expressions.
|
// Reassociate expressions.
|
||||||
TheFPM->add(createReassociatePass());
|
TheFPM->addPass(ReassociatePass());
|
||||||
// Eliminate Common SubExpressions.
|
// Eliminate Common SubExpressions.
|
||||||
TheFPM->add(createGVNPass());
|
TheFPM->addPass(GVNPass());
|
||||||
// Simplify the control flow graph (deleting unreachable blocks, etc).
|
// 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.
|
||||||
|
TheFAM->registerPass([&] { return AAManager(); });
|
||||||
|
TheFAM->registerPass([&] { return AssumptionAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return DominatorTreeAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return LoopAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemoryDependenceAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemorySSAAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return OptimizationRemarkEmitterAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] {
|
||||||
|
return OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>(*TheMAM);
|
||||||
|
});
|
||||||
|
TheFAM->registerPass(
|
||||||
|
[&] { return PassInstrumentationAnalysis(ThePIC.get()); });
|
||||||
|
TheFAM->registerPass([&] { return TargetIRAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return TargetLibraryAnalysis(); });
|
||||||
|
|
||||||
|
TheMAM->registerPass([&] { return ProfileSummaryAnalysis(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleDefinition() {
|
static void HandleDefinition() {
|
||||||
@ -855,7 +893,7 @@ static void HandleDefinition() {
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
ExitOnErr(TheJIT->addModule(
|
ExitOnErr(TheJIT->addModule(
|
||||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Skip token for error recovery.
|
// Skip token for error recovery.
|
||||||
@ -887,7 +925,7 @@ static void HandleTopLevelExpression() {
|
|||||||
|
|
||||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Search the JIT for the __anon_expr symbol.
|
// Search the JIT for the __anon_expr symbol.
|
||||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||||
@ -973,7 +1011,7 @@ int main() {
|
|||||||
|
|
||||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||||
|
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Run the main "interpreter loop" now.
|
// Run the main "interpreter loop" now.
|
||||||
MainLoop();
|
MainLoop();
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
#include "../include/KaleidoscopeJIT.h"
|
#include "../include/KaleidoscopeJIT.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/AssumptionCache.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemorySSA.h"
|
||||||
|
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||||
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
@ -8,15 +15,19 @@
|
|||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/IR/Type.h"
|
#include "llvm/IR/Type.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
|
#include "llvm/Passes/PassBuilder.h"
|
||||||
|
#include "llvm/Passes/StandardInstrumentations.h"
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Scalar/GVN.h"
|
#include "llvm/Transforms/Scalar/GVN.h"
|
||||||
|
#include "llvm/Transforms/Scalar/Reassociate.h"
|
||||||
|
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@ -632,8 +643,12 @@ static std::unique_ptr<LLVMContext> TheContext;
|
|||||||
static std::unique_ptr<Module> TheModule;
|
static std::unique_ptr<Module> TheModule;
|
||||||
static std::unique_ptr<IRBuilder<>> Builder;
|
static std::unique_ptr<IRBuilder<>> Builder;
|
||||||
static std::map<std::string, Value *> NamedValues;
|
static std::map<std::string, Value *> NamedValues;
|
||||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
|
||||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||||
|
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||||
|
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||||
|
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 std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||||
static ExitOnError ExitOnErr;
|
static ExitOnError ExitOnErr;
|
||||||
|
|
||||||
@ -925,7 +940,7 @@ Function *FunctionAST::codegen() {
|
|||||||
verifyFunction(*TheFunction);
|
verifyFunction(*TheFunction);
|
||||||
|
|
||||||
// Run the optimizer on the function.
|
// Run the optimizer on the function.
|
||||||
TheFPM->run(*TheFunction);
|
TheFPM->run(*TheFunction, *TheFAM);
|
||||||
|
|
||||||
return TheFunction;
|
return TheFunction;
|
||||||
}
|
}
|
||||||
@ -942,28 +957,51 @@ Function *FunctionAST::codegen() {
|
|||||||
// Top-Level parsing and JIT Driver
|
// Top-Level parsing and JIT Driver
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void InitializeModuleAndPassManager() {
|
static void InitializeModuleAndManagers() {
|
||||||
// Open a new module.
|
// Open a new context and module.
|
||||||
TheContext = std::make_unique<LLVMContext>();
|
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());
|
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||||
|
|
||||||
// Create a new builder for the module.
|
// Create a new builder for the module.
|
||||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||||
|
|
||||||
// Create a new pass manager attached to it.
|
// Create new pass and analysis managers.
|
||||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
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());
|
||||||
|
|
||||||
|
// Add transform passes.
|
||||||
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
||||||
TheFPM->add(createInstructionCombiningPass());
|
TheFPM->addPass(InstCombinePass());
|
||||||
// Reassociate expressions.
|
// Reassociate expressions.
|
||||||
TheFPM->add(createReassociatePass());
|
TheFPM->addPass(ReassociatePass());
|
||||||
// Eliminate Common SubExpressions.
|
// Eliminate Common SubExpressions.
|
||||||
TheFPM->add(createGVNPass());
|
TheFPM->addPass(GVNPass());
|
||||||
// Simplify the control flow graph (deleting unreachable blocks, etc).
|
// 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.
|
||||||
|
TheFAM->registerPass([&] { return AAManager(); });
|
||||||
|
TheFAM->registerPass([&] { return AssumptionAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return DominatorTreeAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return LoopAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemoryDependenceAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemorySSAAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return OptimizationRemarkEmitterAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] {
|
||||||
|
return OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>(*TheMAM);
|
||||||
|
});
|
||||||
|
TheFAM->registerPass(
|
||||||
|
[&] { return PassInstrumentationAnalysis(ThePIC.get()); });
|
||||||
|
TheFAM->registerPass([&] { return TargetIRAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return TargetLibraryAnalysis(); });
|
||||||
|
|
||||||
|
TheMAM->registerPass([&] { return ProfileSummaryAnalysis(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleDefinition() {
|
static void HandleDefinition() {
|
||||||
@ -974,7 +1012,7 @@ static void HandleDefinition() {
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
ExitOnErr(TheJIT->addModule(
|
ExitOnErr(TheJIT->addModule(
|
||||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Skip token for error recovery.
|
// Skip token for error recovery.
|
||||||
@ -1006,7 +1044,7 @@ static void HandleTopLevelExpression() {
|
|||||||
|
|
||||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Search the JIT for the __anon_expr symbol.
|
// Search the JIT for the __anon_expr symbol.
|
||||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||||
@ -1092,7 +1130,7 @@ int main() {
|
|||||||
|
|
||||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||||
|
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Run the main "interpreter loop" now.
|
// Run the main "interpreter loop" now.
|
||||||
MainLoop();
|
MainLoop();
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
#include "../include/KaleidoscopeJIT.h"
|
#include "../include/KaleidoscopeJIT.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/AssumptionCache.h"
|
||||||
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
||||||
|
#include "llvm/Analysis/MemorySSA.h"
|
||||||
|
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||||
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
@ -8,15 +15,19 @@
|
|||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/IR/Type.h"
|
#include "llvm/IR/Type.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
|
#include "llvm/Passes/PassBuilder.h"
|
||||||
|
#include "llvm/Passes/StandardInstrumentations.h"
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Scalar/GVN.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 "llvm/Transforms/Utils.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -705,8 +716,12 @@ static std::unique_ptr<LLVMContext> TheContext;
|
|||||||
static std::unique_ptr<Module> TheModule;
|
static std::unique_ptr<Module> TheModule;
|
||||||
static std::unique_ptr<IRBuilder<>> Builder;
|
static std::unique_ptr<IRBuilder<>> Builder;
|
||||||
static std::map<std::string, AllocaInst *> NamedValues;
|
static std::map<std::string, AllocaInst *> NamedValues;
|
||||||
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
|
|
||||||
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
|
||||||
|
static std::unique_ptr<FunctionPassManager> TheFPM;
|
||||||
|
static std::unique_ptr<FunctionAnalysisManager> TheFAM;
|
||||||
|
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 std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
|
||||||
static ExitOnError ExitOnErr;
|
static ExitOnError ExitOnErr;
|
||||||
|
|
||||||
@ -1094,7 +1109,7 @@ Function *FunctionAST::codegen() {
|
|||||||
verifyFunction(*TheFunction);
|
verifyFunction(*TheFunction);
|
||||||
|
|
||||||
// Run the optimizer on the function.
|
// Run the optimizer on the function.
|
||||||
TheFPM->run(*TheFunction);
|
TheFPM->run(*TheFunction, *TheFAM);
|
||||||
|
|
||||||
return TheFunction;
|
return TheFunction;
|
||||||
}
|
}
|
||||||
@ -1111,30 +1126,51 @@ Function *FunctionAST::codegen() {
|
|||||||
// Top-Level parsing and JIT Driver
|
// Top-Level parsing and JIT Driver
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void InitializeModuleAndPassManager() {
|
static void InitializeModuleAndManagers() {
|
||||||
// Open a new module.
|
// Open a new context and module.
|
||||||
TheContext = std::make_unique<LLVMContext>();
|
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());
|
TheModule->setDataLayout(TheJIT->getDataLayout());
|
||||||
|
|
||||||
// Create a new builder for the module.
|
// Create a new builder for the module.
|
||||||
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
Builder = std::make_unique<IRBuilder<>>(*TheContext);
|
||||||
|
|
||||||
// Create a new pass manager attached to it.
|
// Create new pass and analysis managers.
|
||||||
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
|
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());
|
||||||
|
|
||||||
// Promote allocas to registers.
|
// Add transform passes.
|
||||||
TheFPM->add(createPromoteMemoryToRegisterPass());
|
|
||||||
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
// Do simple "peephole" optimizations and bit-twiddling optzns.
|
||||||
TheFPM->add(createInstructionCombiningPass());
|
TheFPM->addPass(InstCombinePass());
|
||||||
// Reassociate expressions.
|
// Reassociate expressions.
|
||||||
TheFPM->add(createReassociatePass());
|
TheFPM->addPass(ReassociatePass());
|
||||||
// Eliminate Common SubExpressions.
|
// Eliminate Common SubExpressions.
|
||||||
TheFPM->add(createGVNPass());
|
TheFPM->addPass(GVNPass());
|
||||||
// Simplify the control flow graph (deleting unreachable blocks, etc).
|
// 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.
|
||||||
|
TheFAM->registerPass([&] { return AAManager(); });
|
||||||
|
TheFAM->registerPass([&] { return AssumptionAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return DominatorTreeAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return LoopAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemoryDependenceAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return MemorySSAAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return OptimizationRemarkEmitterAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] {
|
||||||
|
return OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>(*TheMAM);
|
||||||
|
});
|
||||||
|
TheFAM->registerPass(
|
||||||
|
[&] { return PassInstrumentationAnalysis(ThePIC.get()); });
|
||||||
|
TheFAM->registerPass([&] { return TargetIRAnalysis(); });
|
||||||
|
TheFAM->registerPass([&] { return TargetLibraryAnalysis(); });
|
||||||
|
|
||||||
|
TheMAM->registerPass([&] { return ProfileSummaryAnalysis(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleDefinition() {
|
static void HandleDefinition() {
|
||||||
@ -1145,7 +1181,7 @@ static void HandleDefinition() {
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
ExitOnErr(TheJIT->addModule(
|
ExitOnErr(TheJIT->addModule(
|
||||||
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Skip token for error recovery.
|
// Skip token for error recovery.
|
||||||
@ -1177,7 +1213,7 @@ static void HandleTopLevelExpression() {
|
|||||||
|
|
||||||
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
|
||||||
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Search the JIT for the __anon_expr symbol.
|
// Search the JIT for the __anon_expr symbol.
|
||||||
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));
|
||||||
@ -1264,7 +1300,7 @@ int main() {
|
|||||||
|
|
||||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||||
|
|
||||||
InitializeModuleAndPassManager();
|
InitializeModuleAndManagers();
|
||||||
|
|
||||||
// Run the main "interpreter loop" now.
|
// Run the main "interpreter loop" now.
|
||||||
MainLoop();
|
MainLoop();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user