2018-09-25 00:08:15 +08:00
|
|
|
//===- Standard pass instrumentations handling ----------------*- C++ -*--===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// \file
|
|
|
|
///
|
|
|
|
/// This file defines IR-printing pass instrumentation callbacks as well as
|
|
|
|
/// StandardInstrumentations class that manages standard pass instrumentations.
|
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/Passes/StandardInstrumentations.h"
|
|
|
|
#include "llvm/Analysis/CallGraphSCCPass.h"
|
|
|
|
#include "llvm/Analysis/LazyCallGraph.h"
|
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
|
|
|
#include "llvm/IR/IRPrintingPasses.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
|
|
|
#include "llvm/IR/PassInstrumentation.h"
|
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
namespace PrintIR {
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IR-printing instrumentation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
|
|
|
|
/// llvm::Any and does actual print job.
|
|
|
|
void unwrapAndPrint(StringRef Banner, Any IR) {
|
|
|
|
SmallString<40> Extra{"\n"};
|
|
|
|
const Module *M = nullptr;
|
|
|
|
if (any_isa<const Module *>(IR)) {
|
|
|
|
M = any_cast<const Module *>(IR);
|
|
|
|
} else if (any_isa<const Function *>(IR)) {
|
|
|
|
const Function *F = any_cast<const Function *>(IR);
|
|
|
|
if (!llvm::isFunctionInPrintList(F->getName()))
|
|
|
|
return;
|
|
|
|
if (!llvm::forcePrintModuleIR()) {
|
|
|
|
dbgs() << Banner << Extra << static_cast<const Value &>(*F);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
M = F->getParent();
|
|
|
|
Extra = formatv(" (function: {0})\n", F->getName());
|
2018-10-15 18:46:35 +08:00
|
|
|
} else if (any_isa<const LazyCallGraph::SCC *>(IR)) {
|
|
|
|
const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
|
|
|
|
if (!llvm::forcePrintModuleIR()) {
|
|
|
|
Extra = formatv(" (scc: {0})\n", C->getName());
|
|
|
|
bool BannerPrinted = false;
|
|
|
|
for (const LazyCallGraph::Node &N : *C) {
|
|
|
|
const Function &F = N.getFunction();
|
|
|
|
if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
|
|
|
|
if (!BannerPrinted) {
|
|
|
|
dbgs() << Banner << Extra;
|
|
|
|
BannerPrinted = true;
|
|
|
|
}
|
|
|
|
F.print(dbgs());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (const LazyCallGraph::Node &N : *C) {
|
|
|
|
const Function &F = N.getFunction();
|
|
|
|
if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
|
|
|
|
M = F.getParent();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!M)
|
|
|
|
return;
|
|
|
|
Extra = formatv(" (for scc: {0})\n", C->getName());
|
2018-09-25 00:08:15 +08:00
|
|
|
} else if (any_isa<const Loop *>(IR)) {
|
|
|
|
const Loop *L = any_cast<const Loop *>(IR);
|
|
|
|
const Function *F = L->getHeader()->getParent();
|
|
|
|
if (!isFunctionInPrintList(F->getName()))
|
|
|
|
return;
|
|
|
|
if (!llvm::forcePrintModuleIR()) {
|
|
|
|
llvm::printLoop(const_cast<Loop &>(*L), dbgs(), Banner);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
M = F->getParent();
|
|
|
|
{
|
|
|
|
std::string LoopName;
|
|
|
|
raw_string_ostream ss(LoopName);
|
|
|
|
L->getHeader()->printAsOperand(ss, false);
|
|
|
|
Extra = formatv(" (loop: {0})\n", ss.str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (M) {
|
|
|
|
dbgs() << Banner << Extra;
|
|
|
|
M->print(dbgs(), nullptr, false);
|
|
|
|
} else {
|
|
|
|
llvm_unreachable("Unknown wrapped IR type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool printBeforePass(StringRef PassID, Any IR) {
|
|
|
|
if (!llvm::shouldPrintBeforePass(PassID))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID);
|
|
|
|
unwrapAndPrint(Banner, IR);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void printAfterPass(StringRef PassID, Any IR) {
|
|
|
|
if (!llvm::shouldPrintAfterPass(PassID))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID);
|
|
|
|
unwrapAndPrint(Banner, IR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} // namespace PrintIR
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
void StandardInstrumentations::registerCallbacks(
|
|
|
|
PassInstrumentationCallbacks &PIC) {
|
|
|
|
if (llvm::shouldPrintBeforePass())
|
|
|
|
PIC.registerBeforePassCallback(PrintIR::printBeforePass);
|
|
|
|
if (llvm::shouldPrintAfterPass())
|
|
|
|
PIC.registerAfterPassCallback(PrintIR::printAfterPass);
|
2018-10-06 06:32:01 +08:00
|
|
|
TimePasses.registerCallbacks(PIC);
|
2018-09-25 00:08:15 +08:00
|
|
|
}
|