diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2025-02-06 08:38:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-06 08:38:37 +0100 |
commit | 15fbe08f7c01763332f40f2018fcd70ecbf80e91 (patch) | |
tree | 31a969a80cc36dd0c5947a8ccb92260782e9f3b4 | |
parent | 6567122a057ab2992b9a68b674e14f073a3c9e59 (diff) | |
download | llvm-15fbe08f7c01763332f40f2018fcd70ecbf80e91.zip llvm-15fbe08f7c01763332f40f2018fcd70ecbf80e91.tar.gz llvm-15fbe08f7c01763332f40f2018fcd70ecbf80e91.tar.bz2 |
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.
-rw-r--r-- | llvm/include/llvm/Analysis/CFGPrinter.h | 31 | ||||
-rw-r--r-- | llvm/lib/Analysis/CFGPrinter.cpp | 52 |
2 files changed, 63 insertions, 20 deletions
diff --git a/llvm/include/llvm/Analysis/CFGPrinter.h b/llvm/include/llvm/Analysis/CFGPrinter.h index cd78533..b844e3f 100644 --- a/llvm/include/llvm/Analysis/CFGPrinter.h +++ b/llvm/include/llvm/Analysis/CFGPrinter.h @@ -31,6 +31,8 @@ #include "llvm/Support/FormatVariadic.h" namespace llvm { +class ModuleSlotTracker; + template <class GraphType> struct GraphTraits; class CFGViewerPass : public PassInfoMixin<CFGViewerPass> { public: @@ -61,6 +63,7 @@ private: const Function *F; const BlockFrequencyInfo *BFI; const BranchProbabilityInfo *BPI; + std::unique_ptr<ModuleSlotTracker> MSTStorage; uint64_t MaxFreq; bool ShowHeat; bool EdgeWeights; @@ -68,14 +71,10 @@ private: public: DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {} + ~DOTFuncInfo(); DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI, - const BranchProbabilityInfo *BPI, uint64_t MaxFreq) - : F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) { - ShowHeat = false; - EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available. - RawWeights = !!BFI; // Print RawWeights when BFI is available. - } + const BranchProbabilityInfo *BPI, uint64_t MaxFreq); const BlockFrequencyInfo *getBFI() const { return BFI; } @@ -83,6 +82,8 @@ public: const Function *getFunction() const { return this->F; } + ModuleSlotTracker *getModuleSlotTracker(); + uint64_t getMaxFreq() const { return MaxFreq; } uint64_t getFreq(const BasicBlock *BB) const { @@ -203,22 +204,12 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits { return SimpleNodeLabelString(Node); } - static void printBasicBlock(raw_string_ostream &OS, const BasicBlock &Node) { - // Prepend label name - Node.printAsOperand(OS, false); - OS << ":\n"; - for (const Instruction &Inst : Node) - OS << Inst << "\n"; - } - static std::string getCompleteNodeLabel( const BasicBlock *Node, DOTFuncInfo *, function_ref<void(raw_string_ostream &, const BasicBlock &)> - HandleBasicBlock = printBasicBlock, - function_ref<void(std::string &, unsigned &, unsigned)> - HandleComment = eraseComment) { - return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment); - } + HandleBasicBlock = {}, + function_ref<void(std::string &, unsigned &, unsigned)> HandleComment = + eraseComment); std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) { @@ -337,6 +328,6 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits { bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo); void computeDeoptOrUnreachablePaths(const Function *F); }; -} // End llvm namespace +} // namespace llvm #endif diff --git a/llvm/lib/Analysis/CFGPrinter.cpp b/llvm/lib/Analysis/CFGPrinter.cpp index af18fb6..38aad84 100644 --- a/llvm/lib/Analysis/CFGPrinter.cpp +++ b/llvm/lib/Analysis/CFGPrinter.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/CFGPrinter.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/IR/ModuleSlotTracker.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/GraphWriter.h" @@ -90,6 +91,22 @@ static void viewCFG(Function &F, const BlockFrequencyInfo *BFI, ViewGraph(&CFGInfo, "cfg." + F.getName(), CFGOnly); } +DOTFuncInfo::DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI, + const BranchProbabilityInfo *BPI, uint64_t MaxFreq) + : F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) { + ShowHeat = false; + EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available. + RawWeights = !!BFI; // Print RawWeights when BFI is available. +} + +DOTFuncInfo::~DOTFuncInfo() = default; + +ModuleSlotTracker *DOTFuncInfo::getModuleSlotTracker() { + if (!MSTStorage) + MSTStorage = std::make_unique<ModuleSlotTracker>(F->getParent()); + return &*MSTStorage; +} + PreservedAnalyses CFGViewerPass::run(Function &F, FunctionAnalysisManager &AM) { if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName)) return PreservedAnalyses::all(); @@ -208,3 +225,38 @@ bool DOTGraphTraits<DOTFuncInfo *>::isNodeHidden(const BasicBlock *Node, } return false; } + +std::string DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel( + const BasicBlock *Node, DOTFuncInfo *CFGInfo, + function_ref<void(raw_string_ostream &, const BasicBlock &)> + HandleBasicBlock, + function_ref<void(std::string &, unsigned &, unsigned)> HandleComment) { + if (HandleBasicBlock) + return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment); + + // Default basic block printing + std::optional<ModuleSlotTracker> MSTStorage; + ModuleSlotTracker *MST = nullptr; + + if (CFGInfo) { + MST = CFGInfo->getModuleSlotTracker(); + } else { + MSTStorage.emplace(Node->getModule()); + MST = &*MSTStorage; + } + + return CompleteNodeLabelString( + Node, + function_ref<void(raw_string_ostream &, const BasicBlock &)>( + [MST](raw_string_ostream &OS, const BasicBlock &Node) -> void { + // Prepend label name + Node.printAsOperand(OS, false, *MST); + OS << ":\n"; + + for (const Instruction &Inst : Node) { + Inst.print(OS, *MST, /* IsForDebug */ false); + OS << '\n'; + } + }), + HandleComment); +} |