Skip to content

Commit

Permalink
[PassManager] Implement DOTGraphTraitsViewer under NPM
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Meinersbur committed May 9, 2022
1 parent f5d054c commit a6b399a
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 124 deletions.
169 changes: 130 additions & 39 deletions llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
Expand Up @@ -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.
Expand All @@ -52,10 +159,7 @@ class DOTGraphTraitsViewer : public FunctionPass {
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;
}
Expand All @@ -69,12 +173,12 @@ class DOTGraphTraitsViewer : public FunctionPass {
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.
Expand All @@ -94,20 +198,7 @@ class DOTGraphTraitsPrinter : public FunctionPass {
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;
}
Expand All @@ -121,12 +212,12 @@ class DOTGraphTraitsPrinter : public FunctionPass {
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 {
Expand All @@ -147,12 +238,12 @@ class DOTGraphTraitsModuleViewer : public ModulePass {
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 {
Expand Down
116 changes: 56 additions & 60 deletions llvm/lib/Analysis/DomPrinter.cpp
Expand Up @@ -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());
}
};
Expand All @@ -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

Expand All @@ -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

Expand Down

0 comments on commit a6b399a

Please sign in to comment.