1//===--- IRPrintingPasses.cpp - Module and Function printing passes -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// PrintModulePass and PrintFunctionPass implementations.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/IR/IRPrintingPasses.h"
14#include "llvm/IR/Function.h"
15#include "llvm/IR/Module.h"
16#include "llvm/IR/PassManager.h"
17#include "llvm/InitializePasses.h"
18#include "llvm/Pass.h"
19#include "llvm/Support/Debug.h"
20#include "llvm/Support/raw_ostream.h"
21using namespace llvm;
22
23PrintModulePass::PrintModulePass() : OS(dbgs()) {}
24PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
25                                 bool ShouldPreserveUseListOrder)
26    : OS(OS), Banner(Banner),
27      ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
28
29PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &) {
30  if (llvm::isFunctionInPrintList("*")) {
31    if (!Banner.empty())
32      OS << Banner << "\n";
33    M.print(OS, nullptr, ShouldPreserveUseListOrder);
34  }
35  else {
36    bool BannerPrinted = false;
37    for(const auto &F : M.functions()) {
38      if (llvm::isFunctionInPrintList(F.getName())) {
39        if (!BannerPrinted && !Banner.empty()) {
40          OS << Banner << "\n";
41          BannerPrinted = true;
42        }
43        F.print(OS);
44      }
45    }
46  }
47  return PreservedAnalyses::all();
48}
49
50PrintFunctionPass::PrintFunctionPass() : OS(dbgs()) {}
51PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner)
52    : OS(OS), Banner(Banner) {}
53
54PreservedAnalyses PrintFunctionPass::run(Function &F,
55                                         FunctionAnalysisManager &) {
56  if (isFunctionInPrintList(F.getName())) {
57    if (forcePrintModuleIR())
58      OS << Banner << " (function: " << F.getName() << ")\n" << *F.getParent();
59    else
60      OS << Banner << '\n' << static_cast<Value &>(F);
61  }
62  return PreservedAnalyses::all();
63}
64
65namespace {
66
67class PrintModulePassWrapper : public ModulePass {
68  PrintModulePass P;
69
70public:
71  static char ID;
72  PrintModulePassWrapper() : ModulePass(ID) {}
73  PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
74                         bool ShouldPreserveUseListOrder)
75      : ModulePass(ID), P(OS, Banner, ShouldPreserveUseListOrder) {}
76
77  bool runOnModule(Module &M) override {
78    ModuleAnalysisManager DummyMAM;
79    P.run(M, DummyMAM);
80    return false;
81  }
82
83  void getAnalysisUsage(AnalysisUsage &AU) const override {
84    AU.setPreservesAll();
85  }
86
87  StringRef getPassName() const override { return "Print Module IR"; }
88};
89
90class PrintFunctionPassWrapper : public FunctionPass {
91  PrintFunctionPass P;
92
93public:
94  static char ID;
95  PrintFunctionPassWrapper() : FunctionPass(ID) {}
96  PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner)
97      : FunctionPass(ID), P(OS, Banner) {}
98
99  // This pass just prints a banner followed by the function as it's processed.
100  bool runOnFunction(Function &F) override {
101    FunctionAnalysisManager DummyFAM;
102    P.run(F, DummyFAM);
103    return false;
104  }
105
106  void getAnalysisUsage(AnalysisUsage &AU) const override {
107    AU.setPreservesAll();
108  }
109
110  StringRef getPassName() const override { return "Print Function IR"; }
111};
112
113}
114
115char PrintModulePassWrapper::ID = 0;
116INITIALIZE_PASS(PrintModulePassWrapper, "print-module",
117                "Print module to stderr", false, true)
118char PrintFunctionPassWrapper::ID = 0;
119INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
120                "Print function to stderr", false, true)
121
122ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
123                                        const std::string &Banner,
124                                        bool ShouldPreserveUseListOrder) {
125  return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
126}
127
128FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
129                                            const std::string &Banner) {
130  return new PrintFunctionPassWrapper(OS, Banner);
131}
132
133bool llvm::isIRPrintingPass(Pass *P) {
134  const char *PID = (const char*)P->getPassID();
135
136  return (PID == &PrintModulePassWrapper::ID) ||
137         (PID == &PrintFunctionPassWrapper::ID);
138}
139