mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 09:01:19 +00:00
[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
|
||||
========================
|
||||
|
||||
.. 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,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
|
||||
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. 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
|
||||
running it after our newly created function is constructed (in
|
||||
``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);
|
||||
|
||||
// Optimize the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
|
@ -1,21 +1,32 @@
|
||||
#include "../include/KaleidoscopeJIT.h"
|
||||
#include "llvm/ADT/APFloat.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/Constants.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#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 +424,12 @@ 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<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 ExitOnError ExitOnErr;
|
||||
|
||||
@ -535,7 +550,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -549,28 +564,51 @@ 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>();
|
||||
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.
|
||||
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.
|
||||
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() {
|
||||
@ -581,7 +619,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 +651,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 +737,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
@ -1,6 +1,13 @@
|
||||
#include "../include/KaleidoscopeJIT.h"
|
||||
#include "llvm/ADT/APFloat.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/Constants.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
@ -8,15 +15,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 +551,12 @@ 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<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 ExitOnError ExitOnErr;
|
||||
|
||||
@ -809,7 +824,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -823,28 +838,51 @@ 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>();
|
||||
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.
|
||||
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.
|
||||
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() {
|
||||
@ -855,7 +893,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 +925,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 +1011,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
@ -1,6 +1,13 @@
|
||||
#include "../include/KaleidoscopeJIT.h"
|
||||
#include "llvm/ADT/APFloat.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/Constants.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
@ -8,15 +15,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 +643,12 @@ 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<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 ExitOnError ExitOnErr;
|
||||
|
||||
@ -925,7 +940,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -942,28 +957,51 @@ 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>();
|
||||
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.
|
||||
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.
|
||||
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() {
|
||||
@ -974,7 +1012,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 +1044,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 +1130,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
@ -1,6 +1,13 @@
|
||||
#include "../include/KaleidoscopeJIT.h"
|
||||
#include "llvm/ADT/APFloat.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/Constants.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
@ -8,15 +15,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 +716,12 @@ 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<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 ExitOnError ExitOnErr;
|
||||
|
||||
@ -1094,7 +1109,7 @@ Function *FunctionAST::codegen() {
|
||||
verifyFunction(*TheFunction);
|
||||
|
||||
// Run the optimizer on the function.
|
||||
TheFPM->run(*TheFunction);
|
||||
TheFPM->run(*TheFunction, *TheFAM);
|
||||
|
||||
return TheFunction;
|
||||
}
|
||||
@ -1111,30 +1126,51 @@ 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>();
|
||||
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.
|
||||
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.
|
||||
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() {
|
||||
@ -1145,7 +1181,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 +1213,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 +1300,7 @@ int main() {
|
||||
|
||||
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
|
||||
|
||||
InitializeModuleAndPassManager();
|
||||
InitializeModuleAndManagers();
|
||||
|
||||
// Run the main "interpreter loop" now.
|
||||
MainLoop();
|
||||
|
Loading…
Reference in New Issue
Block a user