Skip to content

Commit

Permalink
[CallPrinter] Port CallPrinter passes to new pass manager
Browse files Browse the repository at this point in the history
Port the legacy CallGraphViewer and CallGraphDOTPrinter to work with the new pass manager.

Addresses issue #54323
Adds back related tests that were removed in commits d53a4e7 and 9e9d9ab

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D122989
  • Loading branch information
aeubanks committed Apr 18, 2022
1 parent 17f6cba commit a7e20a8
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 28 deletions.
14 changes: 14 additions & 0 deletions llvm/include/llvm/Analysis/CallPrinter.h
Expand Up @@ -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();

Expand Down
91 changes: 67 additions & 24 deletions llvm/lib/Analysis/CallPrinter.cpp
Expand Up @@ -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 {
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Expand Up @@ -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"
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Passes/PassRegistry.def
Expand Up @@ -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())
Expand Down Expand Up @@ -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({}))
Expand Down
10 changes: 6 additions & 4 deletions llvm/test/Other/heat-colors-graphs.ll
@@ -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:
Expand Down
16 changes: 16 additions & 0 deletions llvm/test/Other/heat-colors-multigraph.ll
@@ -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
}

0 comments on commit a7e20a8

Please sign in to comment.