xo-jit: move IR improvement pipeline to dedicated class
This commit is contained in:
parent
537e178e09
commit
f3af5d27bf
5 changed files with 126 additions and 40 deletions
75
include/xo/jit/IrPipeline.hpp
Normal file
75
include/xo/jit/IrPipeline.hpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/** @file IrPipeline.hpp
|
||||
*
|
||||
* Author: Roland Conybeare
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xo/refcnt/Refcounted.hpp"
|
||||
|
||||
/* stuff from kaleidoscope.cpp */
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/STLExtras.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/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 <cstdint>
|
||||
|
||||
namespace xo {
|
||||
namespace jit {
|
||||
/** @class IrPipeline
|
||||
* @brief represent an LLVM IR pipeline
|
||||
*
|
||||
* Represents analysis/transformation short of generating
|
||||
* machine-code. For now pipeline stages are hardwired;
|
||||
* adapted from the LLVM Kaleidoscope example project.
|
||||
*
|
||||
* Conversely, pipeline *starts* with code already that has
|
||||
* already been expressed in LLVM IR
|
||||
**/
|
||||
class IrPipeline : public ref::Refcount {
|
||||
public:
|
||||
explicit IrPipeline(llvm::LLVMContext & llvm_cx);
|
||||
|
||||
void run_pipeline(llvm::Function & fn);
|
||||
|
||||
private:
|
||||
// ----- transforms (also adapted from kaleidescope.cpp) ------
|
||||
|
||||
/** manages all the passes+analaysis (?) **/
|
||||
std::unique_ptr<llvm::FunctionPassManager> llvm_fpmgr_;
|
||||
/** loop analysis (?) **/
|
||||
std::unique_ptr<llvm::LoopAnalysisManager> llvm_lamgr_;
|
||||
/** function-level analysis (?) **/
|
||||
std::unique_ptr<llvm::FunctionAnalysisManager> llvm_famgr_;
|
||||
/** cgscc (?) analysis **/
|
||||
std::unique_ptr<llvm::CGSCCAnalysisManager> llvm_cgamgr_;
|
||||
/** module analsyis (?) **/
|
||||
std::unique_ptr<llvm::ModuleAnalysisManager> llvm_mamgr_;
|
||||
/** pass instrumentation **/
|
||||
std::unique_ptr<llvm::PassInstrumentationCallbacks> llvm_pic_;
|
||||
/** standard instrumentation **/
|
||||
std::unique_ptr<llvm::StandardInstrumentations> llvm_si_;
|
||||
}; /*IrPipeline*/
|
||||
} /*namespace jit*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/** end IrPipeline.hpp **/
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
//#include <cstdint>
|
||||
|
||||
#include "xo/refcnt/Refcounted.hpp"
|
||||
#include "IrPipeline.hpp"
|
||||
#include "xo/expression/Expression.hpp"
|
||||
#include "xo/expression/ConstantInterface.hpp"
|
||||
#include "xo/expression/PrimitiveInterface.hpp"
|
||||
|
|
@ -150,6 +151,7 @@ namespace xo {
|
|||
* kal_jit_.addModule()
|
||||
* Note that this makes the module itself unavailable to us
|
||||
**/
|
||||
xo::ref::rp<IrPipeline> ir_pipeline_;
|
||||
|
||||
/** owns + manages core "global" llvm data,
|
||||
* including type- and constant- unique-ing tables.
|
||||
|
|
@ -176,22 +178,6 @@ namespace xo {
|
|||
**/
|
||||
std::map<std::string, llvm::Value*> nested_env_;
|
||||
|
||||
// ----- transforms (also adapted from kaleidescope.cpp) ------
|
||||
|
||||
/** manages all the passes+analaysis (?) **/
|
||||
std::unique_ptr<llvm::FunctionPassManager> llvm_fpmgr_;
|
||||
/** loop analysis (?) **/
|
||||
std::unique_ptr<llvm::LoopAnalysisManager> llvm_lamgr_;
|
||||
/** function-level analysis (?) **/
|
||||
std::unique_ptr<llvm::FunctionAnalysisManager> llvm_famgr_;
|
||||
/** cgscc (?) analysis **/
|
||||
std::unique_ptr<llvm::CGSCCAnalysisManager> llvm_cgamgr_;
|
||||
/** module analsyis (?) **/
|
||||
std::unique_ptr<llvm::ModuleAnalysisManager> llvm_mamgr_;
|
||||
/** pass instrumentation **/
|
||||
std::unique_ptr<llvm::PassInstrumentationCallbacks> llvm_pic_;
|
||||
/** standard instrumentation **/
|
||||
std::unique_ptr<llvm::StandardInstrumentations> llvm_si_;
|
||||
}; /*Jit*/
|
||||
|
||||
inline std::ostream &
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set(SELF_LIB xo_jit)
|
||||
set(SELF_SRCS
|
||||
IrPipeline.cpp
|
||||
Jit.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
45
src/jit/IrPipeline.cpp
Normal file
45
src/jit/IrPipeline.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* @file IrPipeline.cpp */
|
||||
|
||||
#include "IrPipeline.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace jit {
|
||||
IrPipeline::IrPipeline(llvm::LLVMContext & llvm_cx)
|
||||
{
|
||||
using std::make_unique;
|
||||
|
||||
this->llvm_fpmgr_ = make_unique<llvm::FunctionPassManager>();
|
||||
this->llvm_lamgr_ = std::make_unique<llvm::LoopAnalysisManager>();
|
||||
this->llvm_famgr_ = std::make_unique<llvm::FunctionAnalysisManager>();
|
||||
this->llvm_cgamgr_ = std::make_unique<llvm::CGSCCAnalysisManager>();
|
||||
this->llvm_mamgr_ = std::make_unique<llvm::ModuleAnalysisManager>();
|
||||
this->llvm_pic_ = std::make_unique<llvm::PassInstrumentationCallbacks>();
|
||||
this->llvm_si_ = std::make_unique<llvm::StandardInstrumentations>(llvm_cx,
|
||||
/*DebugLogging*/ true);
|
||||
|
||||
this->llvm_si_->registerCallbacks(*llvm_pic_, llvm_mamgr_.get());
|
||||
|
||||
/** transform passes **/
|
||||
this->llvm_fpmgr_->addPass(llvm::InstCombinePass());
|
||||
this->llvm_fpmgr_->addPass(llvm::ReassociatePass());
|
||||
this->llvm_fpmgr_->addPass(llvm::GVNPass());
|
||||
this->llvm_fpmgr_->addPass(llvm::SimplifyCFGPass());
|
||||
|
||||
/** tracking for analysis passes that share info? **/
|
||||
llvm::PassBuilder llvm_pass_builder;
|
||||
llvm_pass_builder.registerModuleAnalyses(*llvm_mamgr_);
|
||||
llvm_pass_builder.registerFunctionAnalyses(*llvm_famgr_);
|
||||
llvm_pass_builder.crossRegisterProxies(*llvm_lamgr_, *llvm_famgr_, *llvm_cgamgr_, *llvm_mamgr_);
|
||||
} /*ctor*/
|
||||
|
||||
void
|
||||
IrPipeline::run_pipeline(llvm::Function & fn)
|
||||
{
|
||||
llvm_fpmgr_->run(fn, *llvm_famgr_);
|
||||
} /*run_pipeline*/
|
||||
} /*namespace jit*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
|
||||
/* end IrPipeline.cpp */
|
||||
|
|
@ -148,28 +148,7 @@ namespace xo {
|
|||
throw std::runtime_error("Jit::ctor: expected non-empty llvm module");
|
||||
}
|
||||
|
||||
this->llvm_fpmgr_ = std::make_unique<llvm::FunctionPassManager>();
|
||||
this->llvm_lamgr_ = std::make_unique<llvm::LoopAnalysisManager>();
|
||||
this->llvm_famgr_ = std::make_unique<llvm::FunctionAnalysisManager>();
|
||||
this->llvm_cgamgr_ = std::make_unique<llvm::CGSCCAnalysisManager>();
|
||||
this->llvm_mamgr_ = std::make_unique<llvm::ModuleAnalysisManager>();
|
||||
this->llvm_pic_ = std::make_unique<llvm::PassInstrumentationCallbacks>();
|
||||
this->llvm_si_ = std::make_unique<llvm::StandardInstrumentations>(*llvm_cx_,
|
||||
/*DebugLogging*/ true);
|
||||
|
||||
this->llvm_si_->registerCallbacks(*llvm_pic_, llvm_mamgr_.get());
|
||||
|
||||
/** transform passes **/
|
||||
this->llvm_fpmgr_->addPass(llvm::InstCombinePass());
|
||||
this->llvm_fpmgr_->addPass(llvm::ReassociatePass());
|
||||
this->llvm_fpmgr_->addPass(llvm::GVNPass());
|
||||
this->llvm_fpmgr_->addPass(llvm::SimplifyCFGPass());
|
||||
|
||||
/** tracking for analysis passes that share info? **/
|
||||
llvm::PassBuilder llvm_pass_builder;
|
||||
llvm_pass_builder.registerModuleAnalyses(*llvm_mamgr_);
|
||||
llvm_pass_builder.registerFunctionAnalyses(*llvm_famgr_);
|
||||
llvm_pass_builder.crossRegisterProxies(*llvm_lamgr_, *llvm_famgr_, *llvm_cgamgr_, *llvm_mamgr_);
|
||||
ir_pipeline_ = new IrPipeline(*llvm_cx_);
|
||||
} /*recreate_llvm_ir_pipeline*/
|
||||
|
||||
const std::string &
|
||||
|
|
@ -420,8 +399,8 @@ namespace xo {
|
|||
/* validate! always validate! */
|
||||
llvm::verifyFunction(*fn);
|
||||
|
||||
/* optimize! does this generate code? */
|
||||
llvm_fpmgr_->run(*fn, *llvm_famgr_);
|
||||
/* optimize! improves IR */
|
||||
ir_pipeline_->run_pipeline(*fn); // llvm_fpmgr_->run(*fn, *llvm_famgr_);
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue