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