Index: include/llvm/CodeGen/RegisterMIRPasses.h =================================================================== --- /dev/null +++ include/llvm/CodeGen/RegisterMIRPasses.h @@ -0,0 +1,17 @@ +#ifndef LLVM_REGISTER_MACHINE_PASS_H +#define LLVM_REGISTER_MACHINE_PASS_H + +#include "llvm/CodeGen/TargetPassConfig.h" + +namespace llvm { + +struct RegisterMIRPasses { + RegisterMIRPasses(TargetPassConfig::ExtensionPointTy Ty, + TargetPassConfig::ExtensionFn Fn) { + TargetPassConfig::addGlobalExtension(Ty, Fn); + } +}; + +} // llvm + +#endif Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -15,6 +15,7 @@ #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" +#include "llvm/ADT/DenseMap.h" #include #include @@ -81,7 +82,32 @@ /// This is an ImmutablePass solely for the purpose of exposing CodeGen options /// to the internals of other CodeGen passes. class TargetPassConfig : public ImmutablePass { +public: + typedef void(*ExtensionFn)(const TargetPassConfig& Builder, + legacy::PassManagerBase &PM); + + enum ExtensionPointTy { + /// This extension point allows adding passes before + /// any other transformations. + EP_EarlyAsPossible, + + /// This extension point allows adding passes before register allocation. + EP_BeforeRA, + /// This extension point allows adding passes after register allocation. + EP_AfterRA, + /// This extension point allows adding passes that / run after everything + //else. + EP_OptimizerLast, + }; + static constexpr size_t EP_EnumSize = EP_OptimizerLast+1; + + static void addGlobalExtension(ExtensionPointTy Ty, ExtensionFn Fn); + void addExtension(ExtensionPointTy Ty, ExtensionFn Fn); + void addExtensionsToPM(ExtensionPointTy ETy) const; + private: + SmallVector Extensions[EP_EnumSize]; + PassManagerBase *PM = nullptr; AnalysisID StartBefore = nullptr; AnalysisID StartAfter = nullptr; Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -203,6 +203,31 @@ cl::desc("Stop compilation before a specific pass"), cl::value_desc("pass-name"), cl::init(""), cl::Hidden); +static ManagedStatic, + TargetPassConfig::EP_EnumSize>> GlobalExtensions; + +void TargetPassConfig::addGlobalExtension( + TargetPassConfig::ExtensionPointTy Ty, + TargetPassConfig::ExtensionFn Fn) { + (*GlobalExtensions)[Ty].push_back(Fn); +} + +void TargetPassConfig::addExtension(ExtensionPointTy Ty, ExtensionFn Fn) { + Extensions[Ty].push_back(Fn); +} + +void TargetPassConfig::addExtensionsToPM(ExtensionPointTy ETy) const { + if (GlobalExtensions.isConstructed()) { + for (auto Fn: (*GlobalExtensions)[ETy]) { + Fn(*this, *PM); + } + } + for (auto Fn: Extensions[ETy]) { + Fn(*this, *PM); + } +} + + /// Allow standard passes to be disabled by command line options. This supports /// simple binary flags that either suppress the pass or do nothing. /// i.e. -disable-mypass=false has no effect. @@ -884,6 +909,8 @@ } } + addExtensionsToPM(EP_EarlyAsPossible); + // Add passes that optimize machine instructions in SSA form. if (getOptLevel() != CodeGenOpt::None) { addMachineSSAOptimization(); @@ -896,6 +923,8 @@ if (TM->Options.EnableIPRA) addPass(createRegUsageInfoPropPass()); + addExtensionsToPM(EP_BeforeRA); + // Run pre-ra passes. addPreRegAlloc(); @@ -909,6 +938,8 @@ // Run post-ra passes. addPostRegAlloc(); + addExtensionsToPM(EP_AfterRA); + // Insert prolog/epilog code. Eliminate abstract frame index references... if (getOptLevel() != CodeGenOpt::None) { addPass(&PostRAMachineSinkingID); @@ -984,6 +1015,8 @@ // Add passes that directly emit MI after all other MI passes. addPreEmitPass2(); + addExtensionsToPM(EP_OptimizerLast); + AddingMachinePasses = false; }