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/Compiler.h" |
22 | #include "llvm/Support/Debug.h" |
23 | #include "llvm/Support/raw_ostream.h" |
24 | |
25 | using namespace llvm; |
26 | |
27 | namespace { |
28 | |
29 | class PrintModulePassWrapper : public ModulePass { |
30 | raw_ostream &OS; |
31 | std::string Banner; |
32 | bool ShouldPreserveUseListOrder; |
33 | |
34 | public: |
35 | static char ID; |
36 | PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {} |
37 | PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner, |
38 | bool ShouldPreserveUseListOrder) |
39 | : ModulePass(ID), OS(OS), Banner(Banner), |
40 | ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} |
41 | |
42 | bool runOnModule(Module &M) override { |
43 | // Remove intrinsic declarations when printing in the new format. |
44 | // TODO: consider removing this as debug-intrinsics are gone. |
45 | M.removeDebugIntrinsicDeclarations(); |
46 | |
47 | if (llvm::isFunctionInPrintList(FunctionName: "*" )) { |
48 | if (!Banner.empty()) |
49 | OS << Banner << "\n" ; |
50 | M.print(OS, AAW: nullptr, ShouldPreserveUseListOrder); |
51 | } else { |
52 | bool BannerPrinted = false; |
53 | for (const auto &F : M.functions()) { |
54 | if (llvm::isFunctionInPrintList(FunctionName: F.getName())) { |
55 | if (!BannerPrinted && !Banner.empty()) { |
56 | OS << Banner << "\n" ; |
57 | BannerPrinted = true; |
58 | } |
59 | F.print(OS); |
60 | } |
61 | } |
62 | } |
63 | |
64 | return false; |
65 | } |
66 | |
67 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
68 | AU.setPreservesAll(); |
69 | } |
70 | |
71 | StringRef getPassName() const override { return "Print Module IR" ; } |
72 | }; |
73 | |
74 | class PrintFunctionPassWrapper : public FunctionPass { |
75 | raw_ostream &OS; |
76 | std::string Banner; |
77 | |
78 | public: |
79 | static char ID; |
80 | PrintFunctionPassWrapper() : FunctionPass(ID), OS(dbgs()) {} |
81 | PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner) |
82 | : FunctionPass(ID), OS(OS), Banner(Banner) {} |
83 | |
84 | // This pass just prints a banner followed by the function as it's processed. |
85 | bool runOnFunction(Function &F) override { |
86 | if (isFunctionInPrintList(FunctionName: F.getName())) { |
87 | if (forcePrintModuleIR()) |
88 | OS << Banner << " (function: " << F.getName() << ")\n" |
89 | << *F.getParent(); |
90 | else |
91 | OS << Banner << '\n' << static_cast<Value &>(F); |
92 | } |
93 | |
94 | return false; |
95 | } |
96 | |
97 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
98 | AU.setPreservesAll(); |
99 | } |
100 | |
101 | StringRef getPassName() const override { return "Print Function IR" ; } |
102 | }; |
103 | |
104 | } // namespace |
105 | |
106 | char PrintModulePassWrapper::ID = 0; |
107 | INITIALIZE_PASS(PrintModulePassWrapper, "print-module" , |
108 | "Print module to stderr" , false, true) |
109 | char PrintFunctionPassWrapper::ID = 0; |
110 | INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function" , |
111 | "Print function to stderr" , false, true) |
112 | |
113 | ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS, |
114 | const std::string &Banner, |
115 | bool ShouldPreserveUseListOrder) { |
116 | return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder); |
117 | } |
118 | |
119 | FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS, |
120 | const std::string &Banner) { |
121 | return new PrintFunctionPassWrapper(OS, Banner); |
122 | } |
123 | |
124 | bool llvm::isIRPrintingPass(Pass *P) { |
125 | const char *PID = (const char *)P->getPassID(); |
126 | |
127 | return (PID == &PrintModulePassWrapper::ID) || |
128 | (PID == &PrintFunctionPassWrapper::ID); |
129 | } |
130 | |