[CallPrinter] Port CallPrinter passes to new pass manager
Port the legacy CallGraphViewer and CallGraphDOTPrinter to work with the new pass manager. Addresses issue https://github.com/llvm/llvm-project/issues/54323 Adds back related tests that were removed in commitsd53a4e7b4a
and9e9d9aba14
Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D122989
This commit is contained in:
parent
17f6cba30d
commit
a7e20a8a7a
|
@ -14,10 +14,24 @@
|
|||
#ifndef LLVM_ANALYSIS_CALLPRINTER_H
|
||||
#define LLVM_ANALYSIS_CALLPRINTER_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ModulePass;
|
||||
|
||||
/// Pass for printing the call graph to a dot file
|
||||
class CallGraphDOTPrinterPass : public PassInfoMixin<CallGraphDOTPrinterPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// Pass for viewing the call graph
|
||||
class CallGraphViewerPass : public PassInfoMixin<CallGraphViewerPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
};
|
||||
|
||||
ModulePass *createCallGraphViewerPass();
|
||||
ModulePass *createCallGraphDOTPrinterPass();
|
||||
|
||||
|
|
|
@ -217,6 +217,71 @@ struct DOTGraphTraits<CallGraphDOTInfo *> : public DefaultDOTGraphTraits {
|
|||
|
||||
} // end llvm namespace
|
||||
|
||||
namespace {
|
||||
void doCallGraphDOTPrinting(
|
||||
Module &M, function_ref<BlockFrequencyInfo *(Function &)> LookupBFI) {
|
||||
std::string Filename;
|
||||
if (!CallGraphDotFilenamePrefix.empty())
|
||||
Filename = (CallGraphDotFilenamePrefix + ".callgraph.dot");
|
||||
else
|
||||
Filename = (std::string(M.getModuleIdentifier()) + ".callgraph.dot");
|
||||
errs() << "Writing '" << Filename << "'...";
|
||||
|
||||
std::error_code EC;
|
||||
raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
|
||||
|
||||
CallGraph CG(M);
|
||||
CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
|
||||
|
||||
if (!EC)
|
||||
WriteGraph(File, &CFGInfo);
|
||||
else
|
||||
errs() << " error opening file for writing!";
|
||||
errs() << "\n";
|
||||
}
|
||||
|
||||
void viewCallGraph(Module &M,
|
||||
function_ref<BlockFrequencyInfo *(Function &)> LookupBFI) {
|
||||
CallGraph CG(M);
|
||||
CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
|
||||
|
||||
std::string Title =
|
||||
DOTGraphTraits<CallGraphDOTInfo *>::getGraphName(&CFGInfo);
|
||||
ViewGraph(&CFGInfo, "callgraph", true, Title);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace llvm {
|
||||
PreservedAnalyses CallGraphDOTPrinterPass::run(Module &M,
|
||||
ModuleAnalysisManager &AM) {
|
||||
FunctionAnalysisManager &FAM =
|
||||
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
|
||||
auto LookupBFI = [&FAM](Function &F) {
|
||||
return &FAM.getResult<BlockFrequencyAnalysis>(F);
|
||||
};
|
||||
|
||||
doCallGraphDOTPrinting(M, LookupBFI);
|
||||
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
PreservedAnalyses CallGraphViewerPass::run(Module &M,
|
||||
ModuleAnalysisManager &AM) {
|
||||
|
||||
FunctionAnalysisManager &FAM =
|
||||
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
|
||||
auto LookupBFI = [&FAM](Function &F) {
|
||||
return &FAM.getResult<BlockFrequencyAnalysis>(F);
|
||||
};
|
||||
|
||||
viewCallGraph(M, LookupBFI);
|
||||
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
} // namespace llvm
|
||||
|
||||
namespace {
|
||||
// Viewer
|
||||
class CallGraphViewer : public ModulePass {
|
||||
|
@ -239,12 +304,7 @@ bool CallGraphViewer::runOnModule(Module &M) {
|
|||
return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
|
||||
};
|
||||
|
||||
CallGraph CG(M);
|
||||
CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
|
||||
|
||||
std::string Title =
|
||||
DOTGraphTraits<CallGraphDOTInfo *>::getGraphName(&CFGInfo);
|
||||
ViewGraph(&CFGInfo, "callgraph", true, Title);
|
||||
viewCallGraph(M, LookupBFI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -271,24 +331,7 @@ bool CallGraphDOTPrinter::runOnModule(Module &M) {
|
|||
return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
|
||||
};
|
||||
|
||||
std::string Filename;
|
||||
if (!CallGraphDotFilenamePrefix.empty())
|
||||
Filename = (CallGraphDotFilenamePrefix + ".callgraph.dot");
|
||||
else
|
||||
Filename = (std::string(M.getModuleIdentifier()) + ".callgraph.dot");
|
||||
errs() << "Writing '" << Filename << "'...";
|
||||
|
||||
std::error_code EC;
|
||||
raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
|
||||
|
||||
CallGraph CG(M);
|
||||
CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
|
||||
|
||||
if (!EC)
|
||||
WriteGraph(File, &CFGInfo);
|
||||
else
|
||||
errs() << " error opening file for writing!";
|
||||
errs() << "\n";
|
||||
doCallGraphDOTPrinting(M, LookupBFI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CallPrinter.h"
|
||||
#include "llvm/Analysis/CostModel.h"
|
||||
#include "llvm/Analysis/CycleAnalysis.h"
|
||||
#include "llvm/Analysis/DDG.h"
|
||||
|
|
|
@ -53,6 +53,7 @@ MODULE_PASS("constmerge", ConstantMergePass())
|
|||
MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
|
||||
MODULE_PASS("deadargelim", DeadArgumentEliminationPass())
|
||||
MODULE_PASS("debugify", NewPMDebugifyPass())
|
||||
MODULE_PASS("dot-callgraph", CallGraphDOTPrinterPass())
|
||||
MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass())
|
||||
MODULE_PASS("extract-blocks", BlockExtractorPass())
|
||||
MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
|
||||
|
@ -112,6 +113,7 @@ MODULE_PASS("strip-nondebug", StripNonDebugSymbolsPass())
|
|||
MODULE_PASS("strip-nonlinetable-debuginfo", StripNonLineTableDebugInfoPass())
|
||||
MODULE_PASS("synthetic-counts-propagation", SyntheticCountsPropagation())
|
||||
MODULE_PASS("verify", VerifierPass())
|
||||
MODULE_PASS("view-callgraph", CallGraphViewerPass())
|
||||
MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass())
|
||||
MODULE_PASS("dfsan", DataFlowSanitizerPass())
|
||||
MODULE_PASS("msan-module", ModuleMemorySanitizerPass({}))
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
; RUN: opt %s -dot-cfg -cfg-heat-colors -cfg-dot-filename-prefix=%t -disable-output
|
||||
; RUN: FileCheck %s -input-file=%t.f.dot
|
||||
; RUN: FileCheck %s -input-file=%t.f.dot --check-prefixes=CHECK-CFG,CHECK-BOTH
|
||||
; RUN: opt %s -dot-callgraph -callgraph-heat-colors -callgraph-dot-filename-prefix=%t -disable-output
|
||||
; RUN: FileCheck %s -input-file=%t.callgraph.dot --check-prefix=CHECK-BOTH
|
||||
|
||||
; CHECK: color="#[[#%x,]]", style={{[a-z]+}}, fillcolor="#[[#%x,]]"
|
||||
; CHECK: color="#[[#%x,]]", style={{[a-z]+}}, fillcolor="#[[#%x,]]"
|
||||
; CHECK: color="#[[#%x,]]", style={{[a-z]+}}, fillcolor="#[[#%x,]]"
|
||||
; CHECK-BOTH: color="#[[#%x,]]", style={{[a-z]+}}, fillcolor="#[[#%x,]]"
|
||||
; CHECK-CFG: color="#[[#%x,]]", style={{[a-z]+}}, fillcolor="#[[#%x,]]"
|
||||
; CHECK-CFG: color="#[[#%x,]]", style={{[a-z]+}}, fillcolor="#[[#%x,]]"
|
||||
|
||||
define void @f(i32) {
|
||||
entry:
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
; RUN: opt %s -dot-callgraph -callgraph-multigraph -callgraph-dot-filename-prefix=%t -disable-output
|
||||
; RUN: FileCheck %s -input-file=%t.callgraph.dot --check-prefix=CHECK-MULTIGRAPH
|
||||
; RUN: opt %s -dot-callgraph -callgraph-dot-filename-prefix=%t -disable-output
|
||||
; RUN: FileCheck %s -input-file=%t.callgraph.dot --check-prefix=CHECK
|
||||
|
||||
; CHECK-MULTIGRAPH: {external caller}
|
||||
; CHECK-NOT: {external caller}
|
||||
|
||||
define void @bar() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo() {
|
||||
call void @bar()
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue