LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02...
Transcript of LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02...
![Page 1: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/1.jpg)
T H E L LV M PA S S M A N A G E R PA R T 2
C H A N D L E R C A R R U T H L LV M D E V M T G 2 0 1 4
![Page 2: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/2.jpg)
F R O M T H E P R E V I O U S TA L K :
• A pass operates on some “unit” of IR (Function, Module, …)
• Generally to transform it from one form to another
• Alternatively to analyze its properties and expose higher-level information
![Page 3: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/3.jpg)
L E T T H E C O D E M O D E L T H I S
![Page 4: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/4.jpg)
A PA S S F O R M S A S I M P L E C O N C E P T:
class MyPass { // ... !
MyPass(Module *M, bool EnableFoo, unsigned BarThreshold) { // Set things up... } !
void run(Function *F) { // Do stuff to F... } };
![Page 5: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/5.jpg)
H O W S I M P L E C A N A PA S S M A N A G E R G E T ?
![Page 6: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/6.jpg)
class FunctionPassManager { typedef detail::PassConcept<Function *> FunctionPassConcept; !
template <typename PassT> struct FunctionPassModel : detail::PassModel<Function *, PassT> { FunctionPassModel(PassT Pass) : detail::PassModel<Function *, PassT>(std::move(Pass)) {} }; !
std::vector<std::unique_ptr<FunctionPassConcept>> Passes; !
public: template <typename FunctionPassT> void addPass(FunctionPassT Pass) { Passes.emplace_back( new FunctionPassModel<FunctionPassT>(std::move(Pass))); } !
void run(Function *F) { for (const auto &P : Passes) P->run(F); } };
![Page 7: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/7.jpg)
W H AT I S T H I S C O N C E P T / M O D E L T H I N G ?
template <typename IRUnitT> struct PassConcept { virtual ~PassConcept() {} virtual void run(IRUnitT IR) = 0; }; !
template <typename IRUnitT, typename PassT> struct PassModel : PassConcept<IRUnitT> { explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {} !
void run(IRUnitT IR) override { Pass.run(IR); } PassT Pass; };
![Page 8: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/8.jpg)
A D A P T I N G PA S S M A P S A C R O S S I R U N I T S :
template <typename FunctionPassT> class ModuleToFunctionPassAdaptor { FunctionPassT Pass; public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} !
/// \brief Runs the function pass across every function in the module. void run(Module *M) { for (Function *F : *M) Pass.run(F); } };
![Page 9: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/9.jpg)
S O W E ’ R E D O N E ! ; ]
![Page 10: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/10.jpg)
W H AT A B O U T A N A LY S E S ? T H O S E A R E W H AT M A K E T H I S C O M P L E X
![Page 11: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/11.jpg)
A N A N A LY S I S PA S S I S “J U S T ” A S P E C I A L K I N D O F PA S S …
![Page 12: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/12.jpg)
A N AT O M Y O F A N A N A LY S I S PA S S :
• Immutable view of IR
• Produces some result which can be queried
• Result may actually be a lazy-computing interface
![Page 13: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/13.jpg)
L E T ’ S L O O K AT A C O N C R E T E E X A M P L E …
![Page 14: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/14.jpg)
class DominatorTree : public DominatorTreeBase<BasicBlock> { public: typedef DominatorTreeBase<BasicBlock> Base; !
DominatorTree() : DominatorTreeBase<BasicBlock>(false) {} !
inline bool compare(const DominatorTree &Other) const; !
using Base::dominates; bool dominates(const Instruction *Def, const Use &U) const; bool dominates(const Instruction *Def, const Instruction *User) const; bool dominates(const Instruction *Def, const BasicBlock *BB) const; bool dominates(const BasicBlockEdge &BBE, const Use &U) const; bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const; !
using Base::isReachableFromEntry; bool isReachableFromEntry(const Use &U) const; !
void verifyDomTree() const; };
![Page 15: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/15.jpg)
class DominatorTreeAnalysis { public: typedef DominatorTree Result; !
/// \brief Returns an opaque, unique ID for this pass type. static void *ID() { return (void *)&PassID; } !
DominatorTreeAnalysis() {} !
DominatorTree run(Function *F) { DominatorTree DT; DT.recalculate(F); return std::move(DT); } !
private: /// \brief Private static data to provide unique ID. static char PassID; };
![Page 16: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/16.jpg)
T H E Q U E S T I O N I S , W H E N D O W E R U N T H E A N A LY S I S PA S S ?
![Page 17: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/17.jpg)
H I S T O R I C A L LY: U P- F R O N T D E P E N D E N C Y- B A S E D S C H E D U L I N G
• Slow to compute schedule due to multitude of abstractions
• Schedule is wasteful as it must conservatively assume each pass trashes the IR and thus invalidates the analysis
• Hard to lazily run analyses for sub-units of IR
![Page 18: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/18.jpg)
I N S T E A D, T H I N K O F T H I S A S A C A C H I N G P R O B L E M
![Page 19: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/19.jpg)
A N A LY S I S “ S C H E D U L E ” B Y C A C H I N G R E S U LT S O F L A Z Y R U N S
• Because analysis passes cannot mutate IR, we can never hit a cycle
• Can cache each result of an analysis pass on the unit of IR it pertains to, allowing easy access across IR units
• Need some interface for querying (and populating) the cache
![Page 20: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/20.jpg)
class FunctionAnalysisManager { typedef detail::AnalysisResultConcept<Function *> ResultConceptT; typedef detail::AnalysisPassConcept<Function *, FunctionAnalysisManager> PassConceptT; !
public: template <typename PassT> typename PassT::Result &getResult(Function *F); template <typename PassT> typename PassT::Result *getCachedResult(Function *F) const; !
template <typename PassT> void registerPass(PassT Pass); !
template <typename PassT> void invalidate(Module *M); void invalidate(Function *F); !
private: // ... details ... };
![Page 21: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/21.jpg)
N AT U R A L LY, T H E P R O B L E M B E C O M E S C A C H E I N V A L I D AT I O N
![Page 22: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/22.jpg)
class PreservedAnalyses { public: static PreservedAnalyses none() { return PreservedAnalyses(); } static PreservedAnalyses all() { PreservedAnalyses PA; PA.PreservedPassIDs.insert((void *)AllPassesID); return PA; } ! template <typename PassT> void preserve() { if (!areAllPreserved()) PreservedPassIDs.insert(PassT::ID()); } ! template <typename PassT> bool preserved() const { return areAllPreserved() || PreservedPassIDs.count(Pass::ID()); } !private: static const uintptr_t AllPassesID = (intptr_t)(-3); bool areAllPreserved() const { return PreservedPassIDs.count((void *)AllPassesID); } ! SmallPtrSet<void *, 2> PreservedPassIDs; };
![Page 23: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/23.jpg)
class FunctionPassManager { public: // ... !
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = nullptr) { PreservedAnalyses PA = PreservedAnalyses::all(); !
for (auto &P : Passes) { PreservedAnalyses PassPA = P->run(F, AM); if (AM) AM->invalidate(F, PassPA); PA.intersect(std::move(PassPA)); } !
return PA; } !
private: // ... };
![Page 24: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/24.jpg)
class FunctionPassManager { public: // ... !
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = nullptr) { PreservedAnalyses PA = PreservedAnalyses::all(); !
for (auto &P : Passes) { PreservedAnalyses PassPA = P->run(F, AM); if (AM) AM->invalidate(F, PassPA); PA.intersect(std::move(PassPA)); } !
return PA; } !
private: // ... };
![Page 25: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/25.jpg)
class FunctionPassManager { public: // ... !
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = nullptr) { PreservedAnalyses PA = PreservedAnalyses::all(); !
for (auto &P : Passes) { PreservedAnalyses PassPA = P->run(F, AM); if (AM) AM->invalidate(F, PassPA); PA.intersect(std::move(PassPA)); } !
return PA; } !
private: // ... };
![Page 26: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/26.jpg)
A N A LY S I S M A N A G E R S U S E U N I T S O F I R
• Unlike normal passes, these can be bi-directional
• Lower level IR analyses can always be run on demand
• Higher level IR analysis cannot be run on demand, it could conflict with some sibling transformation
• Invalidation must also be propagated bi-directionally!
![Page 27: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/27.jpg)
class FunctionAnalysisManagerModuleProxy { public: class FunctionAnalysisManagerModuleProxy::Result { public: explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {} ~Result(); FunctionAnalysisManager &getManager() { return *FAM; } ! bool invalidate(Module *M, const PreservedAnalyses &PA) { if (!PA.preserved(ID())) FAM->clear(); return false; } ! private: FunctionAnalysisManager *FAM; }; ! static void *ID() { return (void *)&PassID; } explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM) : FAM(&FAM) {} Result run(Module *M) { return Result(*FAM); } !private: static char PassID; FunctionAnalysisManager *FAM; };
![Page 28: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/28.jpg)
class FunctionAnalysisManagerModuleProxy { public: class FunctionAnalysisManagerModuleProxy::Result { public: explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {} ~Result(); FunctionAnalysisManager &getManager() { return *FAM; } ! bool invalidate(Module *M, const PreservedAnalyses &PA) { if (!PA.preserved(ID())) FAM->clear(); return false; } ! private: FunctionAnalysisManager *FAM; }; ! static void *ID() { return (void *)&PassID; } explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM) : FAM(&FAM) {} Result run(Module *M) { return Result(*FAM); } !private: static char PassID; FunctionAnalysisManager *FAM; };
![Page 29: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/29.jpg)
class FunctionAnalysisManagerModuleProxy { public: class FunctionAnalysisManagerModuleProxy::Result { public: explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {} ~Result(); FunctionAnalysisManager &getManager() { return *FAM; } ! bool invalidate(Module *M, const PreservedAnalyses &PA) { if (!PA.preserved(ID())) FAM->clear(); return false; } ! private: FunctionAnalysisManager *FAM; }; ! static void *ID() { return (void *)&PassID; } explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM) : FAM(&FAM) {} Result run(Module *M) { return Result(*FAM); } !private: static char PassID; FunctionAnalysisManager *FAM; };
![Page 30: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/30.jpg)
class FunctionAnalysisManagerModuleProxy { public: class FunctionAnalysisManagerModuleProxy::Result { public: explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {} ~Result(); FunctionAnalysisManager &getManager() { return *FAM; } ! bool invalidate(Module *M, const PreservedAnalyses &PA) { if (!PA.preserved(ID())) FAM->clear(); return false; } ! private: FunctionAnalysisManager *FAM; }; ! static void *ID() { return (void *)&PassID; } explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM) : FAM(&FAM) {} Result run(Module *M) { return Result(*FAM); } !private: static char PassID; FunctionAnalysisManager *FAM; };
![Page 31: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/31.jpg)
class ModuleAnalysisManagerFunctionProxy { public: class Result { public: explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {} !
const ModuleAnalysisManager &getManager() const { return *MAM; } !
bool invalidate(Function *) { return false; } !
private: const ModuleAnalysisManager *MAM; }; !
static void *ID() { return (void *)&PassID; } ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM) : MAM(&MAM) {} Result run(Function *) { return Result(*MAM); } !
private: static char PassID; const ModuleAnalysisManager *MAM; };
![Page 32: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/32.jpg)
class ModuleAnalysisManagerFunctionProxy { public: class Result { public: explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {} !
const ModuleAnalysisManager &getManager() const { return *MAM; } !
bool invalidate(Function *) { return false; } !
private: const ModuleAnalysisManager *MAM; }; !
static void *ID() { return (void *)&PassID; } ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM) : MAM(&MAM) {} Result run(Function *) { return Result(*MAM); } !
private: static char PassID; const ModuleAnalysisManager *MAM; };
![Page 33: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/33.jpg)
class ModuleAnalysisManagerFunctionProxy { public: class Result { public: explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {} !
const ModuleAnalysisManager &getManager() const { return *MAM; } !
bool invalidate(Function *) { return false; } !
private: const ModuleAnalysisManager *MAM; }; !
static void *ID() { return (void *)&PassID; } ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM) : MAM(&MAM) {} Result run(Function *) { return Result(*MAM); } !
private: static char PassID; const ModuleAnalysisManager *MAM; };
![Page 34: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/34.jpg)
template <typename FunctionPassT> class ModuleToFunctionPassAdaptor { public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} ! PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) { FunctionAnalysisManager *FAM = nullptr; if (AM) FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); ! PreservedAnalyses PA = PreservedAnalyses::all(); for (Function *F : *M) { PreservedAnalyses PassPA = Pass.run(F, FAM); ! if (FAM) FAM->invalidate(I, PassPA); ! PA.intersect(std::move(PassPA)); } ! PA.preserve<FunctionAnalysisManagerModuleProxy>(); return PA; } !private: FunctionPassT Pass; };
![Page 35: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/35.jpg)
template <typename FunctionPassT> class ModuleToFunctionPassAdaptor { public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} ! PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) { FunctionAnalysisManager *FAM = nullptr; if (AM) FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); ! PreservedAnalyses PA = PreservedAnalyses::all(); for (Function *F : *M) { PreservedAnalyses PassPA = Pass.run(F, FAM); ! if (FAM) FAM->invalidate(F, PassPA); ! PA.intersect(std::move(PassPA)); } ! PA.preserve<FunctionAnalysisManagerModuleProxy>(); return PA; } !private: FunctionPassT Pass; };
![Page 36: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/36.jpg)
template <typename FunctionPassT> class ModuleToFunctionPassAdaptor { public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} ! PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) { FunctionAnalysisManager *FAM = nullptr; if (AM) FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); ! PreservedAnalyses PA = PreservedAnalyses::all(); for (Function *F : *M) { PreservedAnalyses PassPA = Pass.run(F, FAM); ! if (FAM) FAM->invalidate(I, PassPA); ! PA.intersect(std::move(PassPA)); } ! PA.preserve<FunctionAnalysisManagerModuleProxy>(); return PA; } !private: FunctionPassT Pass; };
![Page 37: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/37.jpg)
H O W D O W E USE T H E S E A P I S ?
![Page 38: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/38.jpg)
class TestFunctionAnalysis { public: struct Result { /* ... */ }; static void *ID() { return (void *)&PassID; } TestFunctionAnalysis() {} !
Result run(Function *F, FunctionAnalysisManager *AM) { return Result(); } !
private: static char PassID; }; !
class TestModuleAnalysis { public: struct Result { /* ... */ }; static void *ID() { return (void *)&PassID; } TestModuleAnalysis() {} !
Result run(Module *M, ModuleAnalysisManager *AM) { return Result(); } !
private: static char PassID; };
![Page 39: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/39.jpg)
struct TestModulePass { TestModulePass() {} PreservedAnalyses run(Module *M) { return PreservedAnalyses::none(); } }; !
struct TestFunctionPass { TestFunctionPass() {} !
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) { const ModuleAnalysisManager &MAM = AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager(); if (TestModuleAnalysis::Result *TMA = MAM.getCachedResult<TestModuleAnalysis>(F->getParent())) // Do stuff... !
TestFunctionAnalysis::Result &AR = AM->getResult<TestFunctionAnalysis>(F); !
return PreservedAnalyses::all(); } };
![Page 40: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/40.jpg)
void optimize(Module *M) { FunctionAnalysisManager FAM; FAM.registerPass(TestFunctionAnalysis()); ! ModuleAnalysisManager MAM; MAM.registerPass(TestModuleAnalysis()); MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM)); FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM)); ! ModulePassManager MPM; ! { ModulePassManager NestedMPM; FunctionPassManager FPM; { FunctionPassManager NestedFPM; NestedFPM.addPass(TestFunctionPass()); FPM = std::move(NestedFPM); } NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); MPM = std::move(NestedMPM); } ! MPM.addPass(TestModulePass()); ! MPM.run(M.get(), &MAM); // ...
![Page 41: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/41.jpg)
L E T ’ S T I E U P S O M E L O O S E E N D S
![Page 42: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/42.jpg)
A U T O M AT I C R E G I S T R AT I O N : N O P E .
• Cumbersome without global constructors
• Easily replaced by explicit registration and simple tools to reduce boiler plate
• Plan is to have in-tree passes register with a line in a .def file
• Eventually, need a reasonably rich API to allow plugins access
![Page 43: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/43.jpg)
C O M M A N D L I N E N E E D S M O R E S T R U C T U R E
• Can’t use a flat list of flags
• Instead, parse a very simple textual string
• Expose parsing library for use in other tools
• (future) Expose plugin hooks to parsing code
![Page 44: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/44.jpg)
W H AT A B O U T R E - U S I N G PA S S E S ?
• Compile time hit of re-building pass pipelines largely obviated by avoiding expensive scheduling
• If necessary, passes can expose a pass context that can be leveraged to share data structure allocations
• Unlikely to be the common case
![Page 45: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/45.jpg)
W H E R E D O T H I N G S S TA N D ?
![Page 46: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/46.jpg)
I N F R A S T R U C T U R E I S I N -T R E E , F U N C T I O N I N G
• A few passes are even ported and usable with it
• Most analysis passes aren’t available
• No wiring for machine level passes, need separate llc-style pipeline
• Still is enough to play around with if interested =]
![Page 47: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/47.jpg)
S U P P O R T F O R I R C O N S T R U C T S
• Currently, supports Modules, Functions, and SCCs in the call graph.
• No support for Loops yet.
• No support planned for basic blocks, instructions, or regions.
![Page 48: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/48.jpg)
W H AT ’ S N E X T ?
![Page 49: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/49.jpg)
F I R S T: P O R T T H E E X I S T I N G PA S S P I P E L I N E ( S )• Involves porting each pass within todays pipelines to new
infrastructure
• Requires them to have really accurate invalidation information
• Requires using some new base analyses, ex. the call graph
• Needs generic analysis API shared between the two systems
• Lots of plumbing of flags, frontend options, etc.
![Page 50: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/50.jpg)
S E C O N D : S O LV E L O N G - S TA N D I N G P R O B L E M S• Use loop nest and profile info in the inliner
• Teach the inline cost analysis to forward stores to loads across the call site
• Add a cold region outliner based on dominator trees and profile information
• Lazy-loading-friendly LTO DCE
![Page 51: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/51.jpg)
T H I R D : PA R A L L E L I Z E T H E O P T I M I Z E R
• Allow adaptors to spin up passes over smaller units of IR in parallel where the IR data structures allow
• Needs rich parallelization APIs in LLVM
• Needs low-synchronization thread-safe use lists for globals
• Many constraints of the new pass manager are designed to enable and facilitate this
![Page 52: LLVM DevMtg 2014 · 2019. 10. 30. · Title: LLVM DevMtg 2014.key Created Date: 10/29/2014 5:47:02 PM](https://reader036.fdocuments.in/reader036/viewer/2022071403/60f7052dc3394a7127321151/html5/thumbnails/52.jpg)
Q U E S T I O N S ?T H A N K Y O U !