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 for the legacy pass
10 // manager.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/IRPrintingPasses.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/PrintPasses.h"
19 #include "llvm/InitializePasses.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.h"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 class PrintModulePassWrapper : public ModulePass {
29   raw_ostream &OS;
30   std::string Banner;
31   bool ShouldPreserveUseListOrder;
32 
33 public:
34   static char ID;
35   PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {}
36   PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
37                          bool ShouldPreserveUseListOrder)
38       : ModulePass(ID), OS(OS), Banner(Banner),
39         ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
40 
41   bool runOnModule(Module &M) override {
42     // RemoveDIs: there's no textual representation of the DPValue debug-info,
43     // convert to dbg.values before writing out.
44     bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
45     if (IsNewDbgInfoFormat)
46       M.convertFromNewDbgValues();
47 
48     if (llvm::isFunctionInPrintList("*")) {
49       if (!Banner.empty())
50         OS << Banner << "\n";
51       M.print(OS, nullptr, ShouldPreserveUseListOrder);
52     } else {
53       bool BannerPrinted = false;
54       for (const auto &F : M.functions()) {
55         if (llvm::isFunctionInPrintList(F.getName())) {
56           if (!BannerPrinted && !Banner.empty()) {
57             OS << Banner << "\n";
58             BannerPrinted = true;
59           }
60           F.print(OS);
61         }
62       }
63     }
64 
65     if (IsNewDbgInfoFormat)
66       M.convertToNewDbgValues();
67 
68     return false;
69   }
70 
71   void getAnalysisUsage(AnalysisUsage &AU) const override {
72     AU.setPreservesAll();
73   }
74 
75   StringRef getPassName() const override { return "Print Module IR"; }
76 };
77 
78 class PrintFunctionPassWrapper : public FunctionPass {
79   raw_ostream &OS;
80   std::string Banner;
81 
82 public:
83   static char ID;
84   PrintFunctionPassWrapper() : FunctionPass(ID), OS(dbgs()) {}
85   PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner)
86       : FunctionPass(ID), OS(OS), Banner(Banner) {}
87 
88   // This pass just prints a banner followed by the function as it's processed.
89   bool runOnFunction(Function &F) override {
90     // RemoveDIs: there's no textual representation of the DPValue debug-info,
91     // convert to dbg.values before writing out.
92     bool IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
93     if (IsNewDbgInfoFormat)
94       F.convertFromNewDbgValues();
95 
96     if (isFunctionInPrintList(F.getName())) {
97       if (forcePrintModuleIR())
98         OS << Banner << " (function: " << F.getName() << ")\n"
99            << *F.getParent();
100       else
101         OS << Banner << '\n' << static_cast<Value &>(F);
102     }
103 
104     if (IsNewDbgInfoFormat)
105       F.convertToNewDbgValues();
106 
107     return false;
108   }
109 
110   void getAnalysisUsage(AnalysisUsage &AU) const override {
111     AU.setPreservesAll();
112   }
113 
114   StringRef getPassName() const override { return "Print Function IR"; }
115 };
116 
117 } // namespace
118 
119 char PrintModulePassWrapper::ID = 0;
120 INITIALIZE_PASS(PrintModulePassWrapper, "print-module",
121                 "Print module to stderr", false, true)
122 char PrintFunctionPassWrapper::ID = 0;
123 INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
124                 "Print function to stderr", false, true)
125 
126 ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
127                                         const std::string &Banner,
128                                         bool ShouldPreserveUseListOrder) {
129   return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
130 }
131 
132 FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
133                                             const std::string &Banner) {
134   return new PrintFunctionPassWrapper(OS, Banner);
135 }
136 
137 bool llvm::isIRPrintingPass(Pass *P) {
138   const char *PID = (const char *)P->getPassID();
139 
140   return (PID == &PrintModulePassWrapper::ID) ||
141          (PID == &PrintFunctionPassWrapper::ID);
142 }
143