[PassManager] Implement DOTGraphTraitsViewer under NPM

Rename the legacy `DOTGraphTraits{Module,}{Viewer,Printer}` to the corresponding `DOTGraphTraits...WrapperPass`, and implement a new `DOTGraphTraitsViewer` with new pass manager.

Reviewed By: Meinersbur

Differential Revision: https://reviews.llvm.org/D123677
This commit is contained in:
Michael Kruse 2022-05-09 13:38:16 -05:00
parent f5d054cdc1
commit a6b399ad79
4 changed files with 215 additions and 124 deletions

View File

@ -19,20 +19,127 @@
namespace llvm {
/// Default traits class for extracting a graph from an analysis pass.
///
/// This assumes that 'GraphT' is 'AnalysisT::Result *', and pass it through
template <typename Result, typename GraphT = Result *>
struct DefaultAnalysisGraphTraits {
static GraphT getGraph(Result R) { return &R; }
};
template <typename GraphT>
void viewGraphForFunction(Function &F, GraphT Graph, StringRef Name,
bool IsSimple) {
std::string GraphName = DOTGraphTraits<GraphT *>::getGraphName(&Graph);
ViewGraph(Graph, Name, IsSimple,
GraphName + " for '" + F.getName() + "' function");
}
template <typename AnalysisT, bool IsSimple,
typename GraphT = typename AnalysisT::Result *,
typename AnalysisGraphTraitsT =
DefaultAnalysisGraphTraits<typename AnalysisT::Result &, GraphT>>
struct DOTGraphTraitsViewer
: public PassInfoMixin<DOTGraphTraitsViewer<AnalysisT, IsSimple, GraphT,
AnalysisGraphTraitsT>> {
DOTGraphTraitsViewer(StringRef GraphName) : Name(GraphName) {}
/// Return true if this function should be processed.
///
/// An implementation of this class my override this function to indicate that
/// only certain functions should be viewed.
///
/// @param Result The current analysis result for this function.
virtual bool processFunction(Function &F,
const typename AnalysisT::Result &Result) {
return true;
}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
auto &Result = FAM.getResult<AnalysisT>(F);
if (!processFunction(F, Result))
return PreservedAnalyses::all();
GraphT Graph = AnalysisGraphTraitsT::getGraph(Result);
viewGraphForFunction(F, Graph, Name, IsSimple);
return PreservedAnalyses::all();
};
private:
StringRef Name;
};
template <typename GraphT>
void printGraphForFunction(Function &F, GraphT Graph, StringRef Name,
bool IsSimple) {
std::string Filename = Name.str() + "." + F.getName().str() + ".dot";
std::error_code EC;
errs() << "Writing '" << Filename << "'...";
raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);
std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
if (!EC)
WriteGraph(File, Graph, IsSimple,
GraphName + " for '" + F.getName() + "' function");
else
errs() << " error opening file for writing!";
errs() << "\n";
}
template <typename AnalysisT, bool IsSimple,
typename GraphT = typename AnalysisT::Result *,
typename AnalysisGraphTraitsT =
DefaultAnalysisGraphTraits<typename AnalysisT::Result &, GraphT>>
struct DOTGraphTraitsPrinter
: public PassInfoMixin<DOTGraphTraitsPrinter<AnalysisT, IsSimple, GraphT,
AnalysisGraphTraitsT>> {
DOTGraphTraitsPrinter(StringRef GraphName) : Name(GraphName) {}
/// Return true if this function should be processed.
///
/// An implementation of this class my override this function to indicate that
/// only certain functions should be viewed.
///
/// @param Analysis The current analysis result for this function.
virtual bool processFunction(Function &F,
const typename AnalysisT::Result &Result) {
return true;
}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
auto &Result = FAM.getResult<AnalysisT>(F);
if (!processFunction(F, Result))
return PreservedAnalyses::all();
GraphT Graph = AnalysisGraphTraitsT::getGraph(Result);
printGraphForFunction(F, Graph, Name, IsSimple);
return PreservedAnalyses::all();
};
private:
StringRef Name;
};
/// Default traits class for extracting a graph from an analysis pass.
///
/// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
template <typename AnalysisT, typename GraphT = AnalysisT *>
struct DefaultAnalysisGraphTraits {
struct LegacyDefaultAnalysisGraphTraits {
static GraphT getGraph(AnalysisT *A) { return A; }
};
template <
typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
class DOTGraphTraitsViewer : public FunctionPass {
template <typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT =
LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsViewerWrapperPass : public FunctionPass {
public:
DOTGraphTraitsViewer(StringRef GraphName, char &ID)
DOTGraphTraitsViewerWrapperPass(StringRef GraphName, char &ID)
: FunctionPass(ID), Name(GraphName) {}
/// Return true if this function should be processed.
@ -52,10 +159,7 @@ public:
return false;
GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis);
std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
ViewGraph(Graph, Name, IsSimple, Title);
viewGraphForFunction(F, Graph, Name, IsSimple);
return false;
}
@ -69,12 +173,12 @@ private:
std::string Name;
};
template <
typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
class DOTGraphTraitsPrinter : public FunctionPass {
template <typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT =
LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsPrinterWrapperPass : public FunctionPass {
public:
DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
DOTGraphTraitsPrinterWrapperPass(StringRef GraphName, char &ID)
: FunctionPass(ID), Name(GraphName) {}
/// Return true if this function should be processed.
@ -94,20 +198,7 @@ public:
return false;
GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis);
std::string Filename = Name + "." + F.getName().str() + ".dot";
std::error_code EC;
errs() << "Writing '" << Filename << "'...";
raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);
std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
if (!EC)
WriteGraph(File, Graph, IsSimple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
printGraphForFunction(F, Graph, Name, IsSimple);
return false;
}
@ -121,12 +212,12 @@ private:
std::string Name;
};
template <
typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
class DOTGraphTraitsModuleViewer : public ModulePass {
template <typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT =
LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsModuleViewerWrapperPass : public ModulePass {
public:
DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
DOTGraphTraitsModuleViewerWrapperPass(StringRef GraphName, char &ID)
: ModulePass(ID), Name(GraphName) {}
bool runOnModule(Module &M) override {
@ -147,12 +238,12 @@ private:
std::string Name;
};
template <
typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT, GraphT> >
class DOTGraphTraitsModulePrinter : public ModulePass {
template <typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
typename AnalysisGraphTraitsT =
LegacyDefaultAnalysisGraphTraits<AnalysisT, GraphT>>
class DOTGraphTraitsModulePrinterWrapperPass : public ModulePass {
public:
DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
DOTGraphTraitsModulePrinterWrapperPass(StringRef GraphName, char &ID)
: ModulePass(ID), Name(GraphName) {}
bool runOnModule(Module &M) override {

View File

@ -116,26 +116,26 @@ struct DominatorTreeWrapperPassAnalysisGraphTraits {
}
};
struct DomViewer : public DOTGraphTraitsViewer<
struct DomViewer : public DOTGraphTraitsViewerWrapperPass<
DominatorTreeWrapperPass, false, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
DomViewer()
: DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>(
"dom", ID) {
: DOTGraphTraitsViewerWrapperPass<
DominatorTreeWrapperPass, false, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {
initializeDomViewerPass(*PassRegistry::getPassRegistry());
}
};
struct DomOnlyViewer : public DOTGraphTraitsViewer<
struct DomOnlyViewer : public DOTGraphTraitsViewerWrapperPass<
DominatorTreeWrapperPass, true, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
DomOnlyViewer()
: DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>(
"domonly", ID) {
: DOTGraphTraitsViewerWrapperPass<
DominatorTreeWrapperPass, true, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {
initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
}
};
@ -146,32 +146,31 @@ struct PostDominatorTreeWrapperPassAnalysisGraphTraits {
}
};
struct PostDomViewer : public DOTGraphTraitsViewer<
PostDominatorTreeWrapperPass, false,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
struct PostDomViewer
: public DOTGraphTraitsViewerWrapperPass<
PostDominatorTreeWrapperPass, false, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
PostDomViewer() :
DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>(
"postdom", ID){
initializePostDomViewerPass(*PassRegistry::getPassRegistry());
}
PostDomViewer()
: DOTGraphTraitsViewerWrapperPass<
PostDominatorTreeWrapperPass, false, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom", ID) {
initializePostDomViewerPass(*PassRegistry::getPassRegistry());
}
};
struct PostDomOnlyViewer : public DOTGraphTraitsViewer<
PostDominatorTreeWrapperPass, true,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
struct PostDomOnlyViewer
: public DOTGraphTraitsViewerWrapperPass<
PostDominatorTreeWrapperPass, true, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
PostDomOnlyViewer() :
DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>(
"postdomonly", ID){
initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
}
PostDomOnlyViewer()
: DOTGraphTraitsViewerWrapperPass<
PostDominatorTreeWrapperPass, true, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdomonly",
ID) {
initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
}
};
} // end anonymous namespace
@ -195,58 +194,55 @@ INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
false, false)
namespace {
struct DomPrinter : public DOTGraphTraitsPrinter<
struct DomPrinter : public DOTGraphTraitsPrinterWrapperPass<
DominatorTreeWrapperPass, false, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
DomPrinter()
: DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>(
"dom", ID) {
: DOTGraphTraitsPrinterWrapperPass<
DominatorTreeWrapperPass, false, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {
initializeDomPrinterPass(*PassRegistry::getPassRegistry());
}
};
struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
struct DomOnlyPrinter : public DOTGraphTraitsPrinterWrapperPass<
DominatorTreeWrapperPass, true, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
DomOnlyPrinter()
: DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>(
"domonly", ID) {
: DOTGraphTraitsPrinterWrapperPass<
DominatorTreeWrapperPass, true, DominatorTree *,
DominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {
initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
}
};
struct PostDomPrinter
: public DOTGraphTraitsPrinter<
PostDominatorTreeWrapperPass, false,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
: public DOTGraphTraitsPrinterWrapperPass<
PostDominatorTreeWrapperPass, false, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
PostDomPrinter() :
DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>(
"postdom", ID) {
initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
}
PostDomPrinter()
: DOTGraphTraitsPrinterWrapperPass<
PostDominatorTreeWrapperPass, false, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom", ID) {
initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
}
};
struct PostDomOnlyPrinter
: public DOTGraphTraitsPrinter<
PostDominatorTreeWrapperPass, true,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
: public DOTGraphTraitsPrinterWrapperPass<
PostDominatorTreeWrapperPass, true, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits> {
static char ID;
PostDomOnlyPrinter() :
DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>(
"postdomonly", ID) {
initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
}
PostDomOnlyPrinter()
: DOTGraphTraitsPrinterWrapperPass<
PostDominatorTreeWrapperPass, true, PostDominatorTree *,
PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdomonly",
ID) {
initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
}
};
} // end anonymous namespace

View File

@ -145,48 +145,49 @@ struct RegionInfoPassGraphTraits {
};
struct RegionPrinter
: public DOTGraphTraitsPrinter<RegionInfoPass, false, RegionInfo *,
RegionInfoPassGraphTraits> {
: public DOTGraphTraitsPrinterWrapperPass<
RegionInfoPass, false, RegionInfo *, RegionInfoPassGraphTraits> {
static char ID;
RegionPrinter()
: DOTGraphTraitsPrinter<RegionInfoPass, false, RegionInfo *,
RegionInfoPassGraphTraits>("reg", ID) {
: DOTGraphTraitsPrinterWrapperPass<RegionInfoPass, false, RegionInfo *,
RegionInfoPassGraphTraits>("reg", ID) {
initializeRegionPrinterPass(*PassRegistry::getPassRegistry());
}
};
char RegionPrinter::ID = 0;
struct RegionOnlyPrinter
: public DOTGraphTraitsPrinter<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits> {
: public DOTGraphTraitsPrinterWrapperPass<
RegionInfoPass, true, RegionInfo *, RegionInfoPassGraphTraits> {
static char ID;
RegionOnlyPrinter()
: DOTGraphTraitsPrinter<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits>("reg", ID) {
: DOTGraphTraitsPrinterWrapperPass<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits>("reg", ID) {
initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry());
}
};
char RegionOnlyPrinter::ID = 0;
struct RegionViewer
: public DOTGraphTraitsViewer<RegionInfoPass, false, RegionInfo *,
RegionInfoPassGraphTraits> {
: public DOTGraphTraitsViewerWrapperPass<
RegionInfoPass, false, RegionInfo *, RegionInfoPassGraphTraits> {
static char ID;
RegionViewer()
: DOTGraphTraitsViewer<RegionInfoPass, false, RegionInfo *,
RegionInfoPassGraphTraits>("reg", ID) {
: DOTGraphTraitsViewerWrapperPass<RegionInfoPass, false, RegionInfo *,
RegionInfoPassGraphTraits>("reg", ID) {
initializeRegionViewerPass(*PassRegistry::getPassRegistry());
}
};
char RegionViewer::ID = 0;
struct RegionOnlyViewer
: public DOTGraphTraitsViewer<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits> {
: public DOTGraphTraitsViewerWrapperPass<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits> {
static char ID;
RegionOnlyViewer()
: DOTGraphTraitsViewer<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits>("regonly", ID) {
: DOTGraphTraitsViewerWrapperPass<RegionInfoPass, true, RegionInfo *,
RegionInfoPassGraphTraits>("regonly",
ID) {
initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry());
}
};

View File

@ -198,10 +198,11 @@ struct DOTGraphTraits<ScopDetectionWrapperPass *>
} // end namespace llvm
struct ScopViewer
: public DOTGraphTraitsViewer<ScopDetectionWrapperPass, false> {
: public DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false> {
static char ID;
ScopViewer()
: DOTGraphTraitsViewer<ScopDetectionWrapperPass, false>("scops", ID) {}
: DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false>(
"scops", ID) {}
bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override {
if (ViewFilter != "" && !F.getName().count(ViewFilter))
return false;
@ -216,27 +217,29 @@ struct ScopViewer
char ScopViewer::ID = 0;
struct ScopOnlyViewer
: public DOTGraphTraitsViewer<ScopDetectionWrapperPass, true> {
: public DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, true> {
static char ID;
ScopOnlyViewer()
: DOTGraphTraitsViewer<ScopDetectionWrapperPass, true>("scopsonly", ID) {}
: DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, true>(
"scopsonly", ID) {}
};
char ScopOnlyViewer::ID = 0;
struct ScopPrinter
: public DOTGraphTraitsPrinter<ScopDetectionWrapperPass, false> {
: public DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false> {
static char ID;
ScopPrinter()
: DOTGraphTraitsPrinter<ScopDetectionWrapperPass, false>("scops", ID) {}
: DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false>(
"scops", ID) {}
};
char ScopPrinter::ID = 0;
struct ScopOnlyPrinter
: public DOTGraphTraitsPrinter<ScopDetectionWrapperPass, true> {
: public DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true> {
static char ID;
ScopOnlyPrinter()
: DOTGraphTraitsPrinter<ScopDetectionWrapperPass, true>("scopsonly", ID) {
}
: DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true>(
"scopsonly", ID) {}
};
char ScopOnlyPrinter::ID = 0;