109467b48Spatrick //===--- IRPrintingPasses.cpp - Module and Function printing passes -------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
9*d415bd75Srobert // PrintModulePass and PrintFunctionPass implementations for the legacy pass
10*d415bd75Srobert // manager.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick
1409467b48Spatrick #include "llvm/IR/IRPrintingPasses.h"
1573471bf0Spatrick #include "llvm/ADT/StringRef.h"
1609467b48Spatrick #include "llvm/IR/Function.h"
1709467b48Spatrick #include "llvm/IR/Module.h"
1873471bf0Spatrick #include "llvm/IR/PrintPasses.h"
1909467b48Spatrick #include "llvm/InitializePasses.h"
2009467b48Spatrick #include "llvm/Pass.h"
2109467b48Spatrick #include "llvm/Support/Debug.h"
2209467b48Spatrick #include "llvm/Support/raw_ostream.h"
2373471bf0Spatrick
2409467b48Spatrick using namespace llvm;
2509467b48Spatrick
26*d415bd75Srobert namespace {
27*d415bd75Srobert
28*d415bd75Srobert class PrintModulePassWrapper : public ModulePass {
29*d415bd75Srobert raw_ostream &OS;
30*d415bd75Srobert std::string Banner;
31*d415bd75Srobert bool ShouldPreserveUseListOrder;
32*d415bd75Srobert
33*d415bd75Srobert public:
34*d415bd75Srobert static char ID;
PrintModulePassWrapper()35*d415bd75Srobert PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {}
PrintModulePassWrapper(raw_ostream & OS,const std::string & Banner,bool ShouldPreserveUseListOrder)36*d415bd75Srobert PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
3709467b48Spatrick bool ShouldPreserveUseListOrder)
38*d415bd75Srobert : ModulePass(ID), OS(OS), Banner(Banner),
3909467b48Spatrick ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
4009467b48Spatrick
runOnModule(Module & M)41*d415bd75Srobert bool runOnModule(Module &M) override {
4209467b48Spatrick if (llvm::isFunctionInPrintList("*")) {
4309467b48Spatrick if (!Banner.empty())
4409467b48Spatrick OS << Banner << "\n";
4509467b48Spatrick M.print(OS, nullptr, ShouldPreserveUseListOrder);
46*d415bd75Srobert } else {
4709467b48Spatrick bool BannerPrinted = false;
4809467b48Spatrick for (const auto &F : M.functions()) {
4909467b48Spatrick if (llvm::isFunctionInPrintList(F.getName())) {
5009467b48Spatrick if (!BannerPrinted && !Banner.empty()) {
5109467b48Spatrick OS << Banner << "\n";
5209467b48Spatrick BannerPrinted = true;
5309467b48Spatrick }
5409467b48Spatrick F.print(OS);
5509467b48Spatrick }
5609467b48Spatrick }
5709467b48Spatrick }
5809467b48Spatrick return false;
5909467b48Spatrick }
6009467b48Spatrick
getAnalysisUsage(AnalysisUsage & AU) const6109467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override {
6209467b48Spatrick AU.setPreservesAll();
6309467b48Spatrick }
6409467b48Spatrick
getPassName() const6509467b48Spatrick StringRef getPassName() const override { return "Print Module IR"; }
6609467b48Spatrick };
6709467b48Spatrick
6809467b48Spatrick class PrintFunctionPassWrapper : public FunctionPass {
69*d415bd75Srobert raw_ostream &OS;
70*d415bd75Srobert std::string Banner;
7109467b48Spatrick
7209467b48Spatrick public:
7309467b48Spatrick static char ID;
PrintFunctionPassWrapper()74*d415bd75Srobert PrintFunctionPassWrapper() : FunctionPass(ID), OS(dbgs()) {}
PrintFunctionPassWrapper(raw_ostream & OS,const std::string & Banner)7509467b48Spatrick PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner)
76*d415bd75Srobert : FunctionPass(ID), OS(OS), Banner(Banner) {}
7709467b48Spatrick
7809467b48Spatrick // This pass just prints a banner followed by the function as it's processed.
runOnFunction(Function & F)7909467b48Spatrick bool runOnFunction(Function &F) override {
80*d415bd75Srobert if (isFunctionInPrintList(F.getName())) {
81*d415bd75Srobert if (forcePrintModuleIR())
82*d415bd75Srobert OS << Banner << " (function: " << F.getName() << ")\n"
83*d415bd75Srobert << *F.getParent();
84*d415bd75Srobert else
85*d415bd75Srobert OS << Banner << '\n' << static_cast<Value &>(F);
86*d415bd75Srobert }
8709467b48Spatrick return false;
8809467b48Spatrick }
8909467b48Spatrick
getAnalysisUsage(AnalysisUsage & AU) const9009467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override {
9109467b48Spatrick AU.setPreservesAll();
9209467b48Spatrick }
9309467b48Spatrick
getPassName() const9409467b48Spatrick StringRef getPassName() const override { return "Print Function IR"; }
9509467b48Spatrick };
9609467b48Spatrick
97*d415bd75Srobert } // namespace
9809467b48Spatrick
9909467b48Spatrick char PrintModulePassWrapper::ID = 0;
10009467b48Spatrick INITIALIZE_PASS(PrintModulePassWrapper, "print-module",
10109467b48Spatrick "Print module to stderr", false, true)
10209467b48Spatrick char PrintFunctionPassWrapper::ID = 0;
10309467b48Spatrick INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
10409467b48Spatrick "Print function to stderr", false, true)
10509467b48Spatrick
createPrintModulePass(llvm::raw_ostream & OS,const std::string & Banner,bool ShouldPreserveUseListOrder)10609467b48Spatrick ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
10709467b48Spatrick const std::string &Banner,
10809467b48Spatrick bool ShouldPreserveUseListOrder) {
10909467b48Spatrick return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
11009467b48Spatrick }
11109467b48Spatrick
createPrintFunctionPass(llvm::raw_ostream & OS,const std::string & Banner)11209467b48Spatrick FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
11309467b48Spatrick const std::string &Banner) {
11409467b48Spatrick return new PrintFunctionPassWrapper(OS, Banner);
11509467b48Spatrick }
11609467b48Spatrick
isIRPrintingPass(Pass * P)11709467b48Spatrick bool llvm::isIRPrintingPass(Pass *P) {
11809467b48Spatrick const char *PID = (const char *)P->getPassID();
11909467b48Spatrick
12009467b48Spatrick return (PID == &PrintModulePassWrapper::ID) ||
12109467b48Spatrick (PID == &PrintFunctionPassWrapper::ID);
12209467b48Spatrick }
123