diff options
Diffstat (limited to 'llvm/lib/IR/IRPrintingPasses.cpp')
-rw-r--r-- | llvm/lib/IR/IRPrintingPasses.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp new file mode 100644 index 000000000000..953cf9410162 --- /dev/null +++ b/llvm/lib/IR/IRPrintingPasses.cpp @@ -0,0 +1,168 @@ +//===--- IRPrintingPasses.cpp - Module and Function printing passes -------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// PrintModulePass and PrintFunctionPass implementations. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +PrintModulePass::PrintModulePass() : OS(dbgs()) {} +PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner, + bool ShouldPreserveUseListOrder) + : OS(OS), Banner(Banner), + ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} + +PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &) { + if (llvm::isFunctionInPrintList("*")) { + if (!Banner.empty()) + OS << Banner << "\n"; + M.print(OS, nullptr, ShouldPreserveUseListOrder); + } + else { + bool BannerPrinted = false; + for(const auto &F : M.functions()) { + if (llvm::isFunctionInPrintList(F.getName())) { + if (!BannerPrinted && !Banner.empty()) { + OS << Banner << "\n"; + BannerPrinted = true; + } + F.print(OS); + } + } + } + return PreservedAnalyses::all(); +} + +PrintFunctionPass::PrintFunctionPass() : OS(dbgs()) {} +PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner) + : OS(OS), Banner(Banner) {} + +PreservedAnalyses PrintFunctionPass::run(Function &F, + FunctionAnalysisManager &) { + if (isFunctionInPrintList(F.getName())) { + if (forcePrintModuleIR()) + OS << Banner << " (function: " << F.getName() << ")\n" << *F.getParent(); + else + OS << Banner << static_cast<Value &>(F); + } + return PreservedAnalyses::all(); +} + +namespace { + +class PrintModulePassWrapper : public ModulePass { + PrintModulePass P; + +public: + static char ID; + PrintModulePassWrapper() : ModulePass(ID) {} + PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner, + bool ShouldPreserveUseListOrder) + : ModulePass(ID), P(OS, Banner, ShouldPreserveUseListOrder) {} + + bool runOnModule(Module &M) override { + ModuleAnalysisManager DummyMAM; + P.run(M, DummyMAM); + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + + StringRef getPassName() const override { return "Print Module IR"; } +}; + +class PrintFunctionPassWrapper : public FunctionPass { + PrintFunctionPass P; + +public: + static char ID; + PrintFunctionPassWrapper() : FunctionPass(ID) {} + PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner) + : FunctionPass(ID), P(OS, Banner) {} + + // This pass just prints a banner followed by the function as it's processed. + bool runOnFunction(Function &F) override { + FunctionAnalysisManager DummyFAM; + P.run(F, DummyFAM); + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + + StringRef getPassName() const override { return "Print Function IR"; } +}; + +class PrintBasicBlockPass : public BasicBlockPass { + raw_ostream &Out; + std::string Banner; + +public: + static char ID; + PrintBasicBlockPass() : BasicBlockPass(ID), Out(dbgs()) {} + PrintBasicBlockPass(raw_ostream &Out, const std::string &Banner) + : BasicBlockPass(ID), Out(Out), Banner(Banner) {} + + bool runOnBasicBlock(BasicBlock &BB) override { + Out << Banner << BB; + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + + StringRef getPassName() const override { return "Print BasicBlock IR"; } +}; + +} + +char PrintModulePassWrapper::ID = 0; +INITIALIZE_PASS(PrintModulePassWrapper, "print-module", + "Print module to stderr", false, true) +char PrintFunctionPassWrapper::ID = 0; +INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function", + "Print function to stderr", false, true) +char PrintBasicBlockPass::ID = 0; +INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false, + true) + +ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, + const std::string &Banner, + bool ShouldPreserveUseListOrder) { + return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder); +} + +FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, + const std::string &Banner) { + return new PrintFunctionPassWrapper(OS, Banner); +} + +BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream &OS, + const std::string &Banner) { + return new PrintBasicBlockPass(OS, Banner); +} + +bool llvm::isIRPrintingPass(Pass *P) { + const char *PID = (const char*)P->getPassID(); + + return (PID == &PrintModulePassWrapper::ID) + || (PID == &PrintFunctionPassWrapper::ID) + || (PID == &PrintBasicBlockPass::ID); +} |