diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/libs/llvm12/tools/opt/PrintSCC.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'contrib/libs/llvm12/tools/opt/PrintSCC.cpp')
-rw-r--r-- | contrib/libs/llvm12/tools/opt/PrintSCC.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/tools/opt/PrintSCC.cpp b/contrib/libs/llvm12/tools/opt/PrintSCC.cpp new file mode 100644 index 0000000000..1ca52745ff --- /dev/null +++ b/contrib/libs/llvm12/tools/opt/PrintSCC.cpp @@ -0,0 +1,111 @@ +//===- PrintSCC.cpp - Enumerate SCCs in some key graphs -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides passes to print out SCCs in a CFG or a CallGraph. +// Normally, you would not use these passes; instead, you would use the +// scc_iterator directly to enumerate SCCs and process them in some way. These +// passes serve three purposes: +// +// (1) As a reference for how to use the scc_iterator. +// (2) To print out the SCCs for a CFG or a CallGraph: +// analyze -print-cfg-sccs to print the SCCs in each CFG of a module. +// analyze -print-cfg-sccs -stats to print the #SCCs and the maximum SCC size. +// analyze -print-cfg-sccs -debug > /dev/null to watch the algorithm in action. +// +// and similarly: +// analyze -print-callgraph-sccs [-stats] [-debug] to print SCCs in the CallGraph +// +// (3) To test the scc_iterator. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/SCCIterator.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +namespace { + struct CFGSCC : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + CFGSCC() : FunctionPass(ID) {} + bool runOnFunction(Function& func) override; + + void print(raw_ostream &O, const Module* = nullptr) const override { } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + }; + + struct CallGraphSCC : public ModulePass { + static char ID; // Pass identification, replacement for typeid + CallGraphSCC() : ModulePass(ID) {} + + // run - Print out SCCs in the call graph for the specified module. + bool runOnModule(Module &M) override; + + void print(raw_ostream &O, const Module* = nullptr) const override { } + + // getAnalysisUsage - This pass requires the CallGraph. + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired<CallGraphWrapperPass>(); + } + }; +} + +char CFGSCC::ID = 0; +static RegisterPass<CFGSCC> +Y("print-cfg-sccs", "Print SCCs of each function CFG"); + +char CallGraphSCC::ID = 0; +static RegisterPass<CallGraphSCC> +Z("print-callgraph-sccs", "Print SCCs of the Call Graph"); + +bool CFGSCC::runOnFunction(Function &F) { + unsigned sccNum = 0; + errs() << "SCCs for Function " << F.getName() << " in PostOrder:"; + for (scc_iterator<Function*> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) { + const std::vector<BasicBlock *> &nextSCC = *SCCI; + errs() << "\nSCC #" << ++sccNum << " : "; + for (BasicBlock *BB : nextSCC) { + BB->printAsOperand(errs(), false); + errs() << ", "; + } + if (nextSCC.size() == 1 && SCCI.hasCycle()) + errs() << " (Has self-loop)."; + } + errs() << "\n"; + + return true; +} + + +// run - Print out SCCs in the call graph for the specified module. +bool CallGraphSCC::runOnModule(Module &M) { + CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph(); + unsigned sccNum = 0; + errs() << "SCCs for the program in PostOrder:"; + for (scc_iterator<CallGraph*> SCCI = scc_begin(&CG); !SCCI.isAtEnd(); + ++SCCI) { + const std::vector<CallGraphNode*> &nextSCC = *SCCI; + errs() << "\nSCC #" << ++sccNum << " : "; + for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(), + E = nextSCC.end(); I != E; ++I) + errs() << ((*I)->getFunction() ? (*I)->getFunction()->getName() + : "external node") << ", "; + if (nextSCC.size() == 1 && SCCI.hasCycle()) + errs() << " (Has self-loop)."; + } + errs() << "\n"; + + return true; +} |