llvm-project/llvm/lib/IR/IRPrintingPasses.cpp
Jeremy Morse 10a9e7442c [DebugInfo][RemoveDIs] Add conversion utilities for new-debug-info format
This patch plumbs the command line --experimental-debuginfo-iterators flag
in to the pass managers, so that modules can be converted to the new
format, passes run, then converted back to the old format. That allows
developers to test-out the new debuginfo representation across some part of
LLVM with no further work, and from the command line. It also installs
flag-catchers at the various points that bitcode and textual IR can egress
from a process, and temporarily convert the module to dbg.value format when
doing so.

No tests alas as it's designed to be transparent.

Differential Revision: https://reviews.llvm.org/D154372
2023-11-09 22:30:49 +00:00

143 lines
4.4 KiB
C++

//===--- IRPrintingPasses.cpp - Module and Function printing passes -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// PrintModulePass and PrintFunctionPass implementations for the legacy pass
// manager.
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class PrintModulePassWrapper : public ModulePass {
raw_ostream &OS;
std::string Banner;
bool ShouldPreserveUseListOrder;
public:
static char ID;
PrintModulePassWrapper() : ModulePass(ID), OS(dbgs()) {}
PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
bool ShouldPreserveUseListOrder)
: ModulePass(ID), OS(OS), Banner(Banner),
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
bool runOnModule(Module &M) override {
// RemoveDIs: there's no textual representation of the DPValue debug-info,
// convert to dbg.values before writing out.
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
if (IsNewDbgInfoFormat)
M.convertFromNewDbgValues();
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
OS << Banner << "\n";
M.print(OS, nullptr, ShouldPreserveUseListOrder);
} else {
bool BannerPrinted = false;
for (const auto &F : M.functions()) {
if (llvm::isFunctionInPrintList(F.getName())) {
if (!BannerPrinted && !Banner.empty()) {
OS << Banner << "\n";
BannerPrinted = true;
}
F.print(OS);
}
}
}
if (IsNewDbgInfoFormat)
M.convertToNewDbgValues();
return false;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
StringRef getPassName() const override { return "Print Module IR"; }
};
class PrintFunctionPassWrapper : public FunctionPass {
raw_ostream &OS;
std::string Banner;
public:
static char ID;
PrintFunctionPassWrapper() : FunctionPass(ID), OS(dbgs()) {}
PrintFunctionPassWrapper(raw_ostream &OS, const std::string &Banner)
: FunctionPass(ID), OS(OS), Banner(Banner) {}
// This pass just prints a banner followed by the function as it's processed.
bool runOnFunction(Function &F) override {
// RemoveDIs: there's no textual representation of the DPValue debug-info,
// convert to dbg.values before writing out.
bool IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
if (IsNewDbgInfoFormat)
F.convertFromNewDbgValues();
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR())
OS << Banner << " (function: " << F.getName() << ")\n"
<< *F.getParent();
else
OS << Banner << '\n' << static_cast<Value &>(F);
}
if (IsNewDbgInfoFormat)
F.convertToNewDbgValues();
return false;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
StringRef getPassName() const override { return "Print Function IR"; }
};
} // namespace
char PrintModulePassWrapper::ID = 0;
INITIALIZE_PASS(PrintModulePassWrapper, "print-module",
"Print module to stderr", false, true)
char PrintFunctionPassWrapper::ID = 0;
INITIALIZE_PASS(PrintFunctionPassWrapper, "print-function",
"Print function to stderr", false, true)
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);
}
bool llvm::isIRPrintingPass(Pass *P) {
const char *PID = (const char *)P->getPassID();
return (PID == &PrintModulePassWrapper::ID) ||
(PID == &PrintFunctionPassWrapper::ID);
}