Skip to content

Commit 49364eb

Browse files
nhaehnlegithub-actions[bot]
authored andcommitted
Automerge: CFGPrinter: fix accidentally quadratic behavior (#125396)
Initialize a ModuleStateTracker at most once per BasicBlock instead of once per Instruction. When the CFG info is provided, it is initialized once per function.
2 parents f9bb727 + 15fbe08 commit 49364eb

File tree

2 files changed

+63
-20
lines changed

2 files changed

+63
-20
lines changed

llvm/include/llvm/Analysis/CFGPrinter.h

+11-20
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "llvm/Support/FormatVariadic.h"
3232

3333
namespace llvm {
34+
class ModuleSlotTracker;
35+
3436
template <class GraphType> struct GraphTraits;
3537
class CFGViewerPass : public PassInfoMixin<CFGViewerPass> {
3638
public:
@@ -61,28 +63,27 @@ class DOTFuncInfo {
6163
const Function *F;
6264
const BlockFrequencyInfo *BFI;
6365
const BranchProbabilityInfo *BPI;
66+
std::unique_ptr<ModuleSlotTracker> MSTStorage;
6467
uint64_t MaxFreq;
6568
bool ShowHeat;
6669
bool EdgeWeights;
6770
bool RawWeights;
6871

6972
public:
7073
DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
74+
~DOTFuncInfo();
7175

7276
DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
73-
const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
74-
: F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) {
75-
ShowHeat = false;
76-
EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available.
77-
RawWeights = !!BFI; // Print RawWeights when BFI is available.
78-
}
77+
const BranchProbabilityInfo *BPI, uint64_t MaxFreq);
7978

8079
const BlockFrequencyInfo *getBFI() const { return BFI; }
8180

8281
const BranchProbabilityInfo *getBPI() const { return BPI; }
8382

8483
const Function *getFunction() const { return this->F; }
8584

85+
ModuleSlotTracker *getModuleSlotTracker();
86+
8687
uint64_t getMaxFreq() const { return MaxFreq; }
8788

8889
uint64_t getFreq(const BasicBlock *BB) const {
@@ -203,22 +204,12 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
203204
return SimpleNodeLabelString(Node);
204205
}
205206

206-
static void printBasicBlock(raw_string_ostream &OS, const BasicBlock &Node) {
207-
// Prepend label name
208-
Node.printAsOperand(OS, false);
209-
OS << ":\n";
210-
for (const Instruction &Inst : Node)
211-
OS << Inst << "\n";
212-
}
213-
214207
static std::string getCompleteNodeLabel(
215208
const BasicBlock *Node, DOTFuncInfo *,
216209
function_ref<void(raw_string_ostream &, const BasicBlock &)>
217-
HandleBasicBlock = printBasicBlock,
218-
function_ref<void(std::string &, unsigned &, unsigned)>
219-
HandleComment = eraseComment) {
220-
return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
221-
}
210+
HandleBasicBlock = {},
211+
function_ref<void(std::string &, unsigned &, unsigned)> HandleComment =
212+
eraseComment);
222213

223214
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
224215

@@ -337,6 +328,6 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
337328
bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
338329
void computeDeoptOrUnreachablePaths(const Function *F);
339330
};
340-
} // End llvm namespace
331+
} // namespace llvm
341332

342333
#endif

llvm/lib/Analysis/CFGPrinter.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "llvm/Analysis/CFGPrinter.h"
2121
#include "llvm/ADT/PostOrderIterator.h"
22+
#include "llvm/IR/ModuleSlotTracker.h"
2223
#include "llvm/Support/CommandLine.h"
2324
#include "llvm/Support/FileSystem.h"
2425
#include "llvm/Support/GraphWriter.h"
@@ -90,6 +91,22 @@ static void viewCFG(Function &F, const BlockFrequencyInfo *BFI,
9091
ViewGraph(&CFGInfo, "cfg." + F.getName(), CFGOnly);
9192
}
9293

94+
DOTFuncInfo::DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
95+
const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
96+
: F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) {
97+
ShowHeat = false;
98+
EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available.
99+
RawWeights = !!BFI; // Print RawWeights when BFI is available.
100+
}
101+
102+
DOTFuncInfo::~DOTFuncInfo() = default;
103+
104+
ModuleSlotTracker *DOTFuncInfo::getModuleSlotTracker() {
105+
if (!MSTStorage)
106+
MSTStorage = std::make_unique<ModuleSlotTracker>(F->getParent());
107+
return &*MSTStorage;
108+
}
109+
93110
PreservedAnalyses CFGViewerPass::run(Function &F, FunctionAnalysisManager &AM) {
94111
if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
95112
return PreservedAnalyses::all();
@@ -208,3 +225,38 @@ bool DOTGraphTraits<DOTFuncInfo *>::isNodeHidden(const BasicBlock *Node,
208225
}
209226
return false;
210227
}
228+
229+
std::string DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(
230+
const BasicBlock *Node, DOTFuncInfo *CFGInfo,
231+
function_ref<void(raw_string_ostream &, const BasicBlock &)>
232+
HandleBasicBlock,
233+
function_ref<void(std::string &, unsigned &, unsigned)> HandleComment) {
234+
if (HandleBasicBlock)
235+
return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
236+
237+
// Default basic block printing
238+
std::optional<ModuleSlotTracker> MSTStorage;
239+
ModuleSlotTracker *MST = nullptr;
240+
241+
if (CFGInfo) {
242+
MST = CFGInfo->getModuleSlotTracker();
243+
} else {
244+
MSTStorage.emplace(Node->getModule());
245+
MST = &*MSTStorage;
246+
}
247+
248+
return CompleteNodeLabelString(
249+
Node,
250+
function_ref<void(raw_string_ostream &, const BasicBlock &)>(
251+
[MST](raw_string_ostream &OS, const BasicBlock &Node) -> void {
252+
// Prepend label name
253+
Node.printAsOperand(OS, false, *MST);
254+
OS << ":\n";
255+
256+
for (const Instruction &Inst : Node) {
257+
Inst.print(OS, *MST, /* IsForDebug */ false);
258+
OS << '\n';
259+
}
260+
}),
261+
HandleComment);
262+
}

0 commit comments

Comments
 (0)