Skip to content

Commit

Permalink
[Instrumentation] Support MachineFunction in ChangeReporter (#80946)
Browse files Browse the repository at this point in the history
  • Loading branch information
paperchalice authored Apr 11, 2024
1 parent 75edf0c commit 026165f
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 12 deletions.
13 changes: 12 additions & 1 deletion llvm/include/llvm/Passes/StandardInstrumentations.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassTimingInfo.h"
Expand All @@ -33,6 +35,7 @@ namespace llvm {

class Module;
class Function;
class MachineFunction;
class PassInstrumentationCallbacks;

/// Instrumentation to print IR before/after passes.
Expand Down Expand Up @@ -313,6 +316,11 @@ template <typename T> class BlockDataT {
B.print(SS, nullptr, true, true);
}

BlockDataT(const MachineBasicBlock &B) : Label(B.getName().str()), Data(B) {
raw_string_ostream SS(Body);
B.print(SS);
}

bool operator==(const BlockDataT &That) const { return Body == That.Body; }
bool operator!=(const BlockDataT &That) const { return Body != That.Body; }

Expand Down Expand Up @@ -364,6 +372,7 @@ template <typename T> class OrderedChangedData {
class EmptyData {
public:
EmptyData(const BasicBlock &) {}
EmptyData(const MachineBasicBlock &) {}
};

// The data saved for comparing functions.
Expand Down Expand Up @@ -405,7 +414,8 @@ template <typename T> class IRComparer {

protected:
// Generate the data for \p F into \p Data.
static bool generateFunctionData(IRDataT<T> &Data, const Function &F);
template <typename FunctionT>
static bool generateFunctionData(IRDataT<T> &Data, const FunctionT &F);

const IRDataT<T> &Before;
const IRDataT<T> &After;
Expand Down Expand Up @@ -475,6 +485,7 @@ class DCData {
public:
// Fill the map with the transitions from basic block \p B.
DCData(const BasicBlock &B);
DCData(const MachineBasicBlock &B);

// Return an iterator to the names of the successor blocks.
StringMap<std::string>::const_iterator begin() const {
Expand Down
82 changes: 71 additions & 11 deletions llvm/lib/Passes/StandardInstrumentations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/MIRPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
Expand Down Expand Up @@ -180,6 +182,12 @@ const Module *unwrapModule(Any IR, bool Force = false) {
return F->getParent();
}

if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
if (!Force && !isFunctionInPrintList(MF->getName()))
return nullptr;
return MF->getFunction().getParent();
}

llvm_unreachable("Unknown IR unit");
}

Expand Down Expand Up @@ -215,6 +223,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
printLoop(const_cast<Loop &>(*L), OS);
}

void printIR(raw_ostream &OS, const MachineFunction *MF) {
if (!isFunctionInPrintList(MF->getName()))
return;
MF->print(OS);
}

std::string getIRName(Any IR) {
if (unwrapIR<Module>(IR))
return "[module]";
Expand Down Expand Up @@ -262,6 +276,9 @@ bool shouldPrintIR(Any IR) {

if (const auto *L = unwrapIR<Loop>(IR))
return isFunctionInPrintList(L->getHeader()->getParent()->getName());

if (const auto *MF = unwrapIR<MachineFunction>(IR))
return isFunctionInPrintList(MF->getName());
llvm_unreachable("Unknown wrapped IR type");
}

Expand All @@ -275,6 +292,14 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
auto *M = unwrapModule(IR);
assert(M && "should have unwrapped module");
printIR(OS, M);

if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
auto &MMI = MF->getMMI();
for (const auto &F : *M) {
if (auto *MF = MMI.getMachineFunction(F))
MF->print(OS);
}
}
return;
}

Expand All @@ -297,6 +322,11 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
printIR(OS, L);
return;
}

if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
printIR(OS, MF);
return;
}
llvm_unreachable("Unknown wrapped IR type");
}

Expand All @@ -305,7 +335,8 @@ bool isIgnored(StringRef PassID) {
return isSpecialPass(PassID,
{"PassManager", "PassAdaptor", "AnalysisManagerProxy",
"DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass",
"VerifierPass", "PrintModulePass"});
"VerifierPass", "PrintModulePass", "PrintMIRPass",
"PrintMIRPreparePass"});
}

std::string makeHTMLReady(StringRef SR) {
Expand Down Expand Up @@ -664,20 +695,38 @@ template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
return;
}

const auto *F = unwrapIR<Function>(IR);
if (!F) {
const auto *L = unwrapIR<Loop>(IR);
assert(L && "Unknown IR unit.");
F = L->getHeader()->getParent();
if (const auto *F = unwrapIR<Function>(IR)) {
generateFunctionData(Data, *F);
return;
}

if (const auto *L = unwrapIR<Loop>(IR)) {
auto *F = L->getHeader()->getParent();
generateFunctionData(Data, *F);
return;
}
assert(F && "Unknown IR unit.");
generateFunctionData(Data, *F);

if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
generateFunctionData(Data, *MF);
return;
}

llvm_unreachable("Unknown IR unit");
}

static bool shouldGenerateData(const Function &F) {
return !F.isDeclaration() && isFunctionInPrintList(F.getName());
}

static bool shouldGenerateData(const MachineFunction &MF) {
return isFunctionInPrintList(MF.getName());
}

template <typename T>
bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const Function &F) {
if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
FuncDataT<T> FD(F.getEntryBlock().getName().str());
template <typename FunctionT>
bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const FunctionT &F) {
if (shouldGenerateData(F)) {
FuncDataT<T> FD(F.front().getName().str());
int I = 0;
for (const auto &B : F) {
std::string BBName = B.getName().str();
Expand Down Expand Up @@ -722,6 +771,12 @@ static SmallString<32> getIRFileDisplayName(Any IR) {
ResultStream << "-loop-";
stable_hash LoopNameHash = stable_hash_combine_string(L->getName());
write_hex(ResultStream, LoopNameHash, HexPrintStyle::Lower, MaxHashWidth);
} else if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
ResultStream << "-machine-function-";
stable_hash MachineFunctionNameHash =
stable_hash_combine_string(MF->getName());
write_hex(ResultStream, MachineFunctionNameHash, HexPrintStyle::Lower,
MaxHashWidth);
} else {
llvm_unreachable("Unknown wrapped IR type");
}
Expand Down Expand Up @@ -2122,6 +2177,11 @@ DCData::DCData(const BasicBlock &B) {
addSuccessorLabel(Succ->getName().str(), "");
}

DCData::DCData(const MachineBasicBlock &B) {
for (const MachineBasicBlock *Succ : successors(&B))
addSuccessorLabel(Succ->getName().str(), "");
}

DotCfgChangeReporter::DotCfgChangeReporter(bool Verbose)
: ChangeReporter<IRDataT<DCData>>(Verbose) {}

Expand Down
24 changes: 24 additions & 0 deletions llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# REQUIRES: x86-registered-target
# Simple functionality check.
# RUN: rm -rf %t && mkdir -p %t
# RUN: llc -filetype=null -print-changed=dot-cfg -passes=no-op-machine-function -dot-cfg-dir=%t %s
# RUN: ls %t/*.pdf %t/passes.html | count 3

---
name: g
body: |
bb.0.entry:
%0:gr32 = MOV32ri 5
$eax = COPY %0
RET 0, $eax
...
---
name: f
body: |
bb.0.entry:
%0:gr32 = MOV32ri 7
$eax = COPY %0
RET 0, $eax
...
21 changes: 21 additions & 0 deletions llvm/test/Other/change-printer.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# REQUIRES: x86-registered-target
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
# RUN: -p no-op-machine-function -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OP

# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
# RUN: -p dead-mi-elimination -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-SIMPLE

---
name: test
body: |
bb.0:
%1:gr64 = MOV64ri 0
%2:gr64 = MOV64ri 0
$eax = COPY %1
RET64 implicit $eax
...

# CHECK-NO-OP: *** IR Dump After NoOpMachineFunctionPass on test omitted because no change ***

# CHECK-SIMPLE: *** IR Dump After DeadMachineInstructionElimPass on test ***
# CHECK-SIMPLE-NOT: %2:gr64 = MOV64ri 0

0 comments on commit 026165f

Please sign in to comment.