mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-12 04:26:43 +00:00

This adds a -debugify-each mode to opt which, when enabled, wraps each {Module,Function}Pass in a pipeline with logic to add, check, and strip synthetic debug info for testing purposes. This mode can be used to test complex pipelines for debug info bugs, or to collect statistics about the number of debug values & locations lost throughout various stages of a pipeline. Patch by Son Tuan Vu! Differential Revision: https://reviews.llvm.org/D46525 llvm-svn: 332312
161 lines
5.0 KiB
C++
161 lines
5.0 KiB
C++
//===--- IRPrintingPasses.cpp - Module and Function printing passes -------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// PrintModulePass and PrintFunctionPass implementations.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/IR/IRPrintingPasses.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/PassManager.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
using namespace llvm;
|
|
|
|
PrintModulePass::PrintModulePass() : OS(dbgs()) {}
|
|
PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
|
|
bool ShouldPreserveUseListOrder)
|
|
: OS(OS), Banner(Banner),
|
|
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
|
|
|
|
PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &) {
|
|
OS << Banner;
|
|
if (llvm::isFunctionInPrintList("*"))
|
|
M.print(OS, nullptr, ShouldPreserveUseListOrder);
|
|
else {
|
|
for(const auto &F : M.functions())
|
|
if (llvm::isFunctionInPrintList(F.getName()))
|
|
F.print(OS);
|
|
}
|
|
return PreservedAnalyses::all();
|
|
}
|
|
|
|
PrintFunctionPass::PrintFunctionPass() : OS(dbgs()) {}
|
|
PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner)
|
|
: OS(OS), Banner(Banner) {}
|
|
|
|
PreservedAnalyses PrintFunctionPass::run(Function &F,
|
|
FunctionAnalysisManager &) {
|
|
if (isFunctionInPrintList(F.getName())) {
|
|
if (forcePrintModuleIR())
|
|
OS << Banner << " (function: " << F.getName() << ")\n" << *F.getParent();
|
|
else
|
|
OS << Banner << static_cast<Value &>(F);
|
|
}
|
|
return PreservedAnalyses::all();
|
|
}
|
|
|
|
namespace {
|
|
|
|
class PrintModulePassWrapper : public ModulePass {
|
|
PrintModulePass P;
|
|
|
|
public:
|
|
static char ID;
|
|
PrintModulePassWrapper() : ModulePass(ID) {}
|
|
PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
|
|
bool ShouldPreserveUseListOrder)
|
|
: ModulePass(ID), P(OS, Banner, ShouldPreserveUseListOrder) {}
|
|
|
|
bool runOnModule(Module &M) override {
|
|
ModuleAnalysisManager DummyMAM;
|
|
P.run(M, DummyMAM);
|
|
return false;
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
StringRef getPassName() const override { return "Print Module IR"; }
|
|
};
|
|
|
|
class PrintFunctionPassWrapper : public FunctionPass {
|
|
PrintFunctionPass P;
|
|
|
|
public:
|
|
static char ID;
|
|
PrintFunctionPassWrapper() : FunctionPass(ID) {}
|
|
PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner)
|
|
: FunctionPass(ID), P(OS, Banner) {}
|
|
|
|
// This pass just prints a banner followed by the function as it's processed.
|
|
bool runOnFunction(Function &F) override {
|
|
FunctionAnalysisManager DummyFAM;
|
|
P.run(F, DummyFAM);
|
|
return false;
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
StringRef getPassName() const override { return "Print Function IR"; }
|
|
};
|
|
|
|
class PrintBasicBlockPass : public BasicBlockPass {
|
|
raw_ostream &Out;
|
|
std::string Banner;
|
|
|
|
public:
|
|
static char ID;
|
|
PrintBasicBlockPass() : BasicBlockPass(ID), Out(dbgs()) {}
|
|
PrintBasicBlockPass(raw_ostream &Out, const std::string &Banner)
|
|
: BasicBlockPass(ID), Out(Out), Banner(Banner) {}
|
|
|
|
bool runOnBasicBlock(BasicBlock &BB) override {
|
|
Out << Banner << BB;
|
|
return false;
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
StringRef getPassName() const override { return "Print BasicBlock IR"; }
|
|
};
|
|
|
|
}
|
|
|
|
char PrintModulePassWrapper::ID = 0;
|
|
INITIALIZE_PASS(PrintModulePassWrapper, "print-module",
|
|
"Print module to stderr", false, false)
|
|
char PrintFunctionPassWrapper::ID = 0;
|
|
INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
|
|
"Print function to stderr", false, false)
|
|
char PrintBasicBlockPass::ID = 0;
|
|
INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false,
|
|
false)
|
|
|
|
ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
|
|
const std::string &Banner,
|
|
bool ShouldPreserveUseListOrder) {
|
|
return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
|
|
}
|
|
|
|
FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
|
|
const std::string &Banner) {
|
|
return new PrintFunctionPassWrapper(OS, Banner);
|
|
}
|
|
|
|
BasicBlockPass *llvm::createPrintBasicBlockPass(llvm::raw_ostream &OS,
|
|
const std::string &Banner) {
|
|
return new PrintBasicBlockPass(OS, Banner);
|
|
}
|
|
|
|
bool llvm::isIRPrintingPass(Pass *P) {
|
|
const char *PID = (const char*)P->getPassID();
|
|
|
|
return (PID == &PrintModulePassWrapper::ID)
|
|
|| (PID == &PrintFunctionPassWrapper::ID)
|
|
|| (PID == &PrintBasicBlockPass::ID);
|
|
}
|