Skip to content

Commit

Permalink
[SelectionDAG] Add support to filter SelectionDAG dumps during ISel b…
Browse files Browse the repository at this point in the history
…y function names (#72696)

`-debug-only=isel-dump` is the new debug type for printing SelectionDAG
after each ISel phase. This can be furthered filter by
`-filter-print-funcs=<function names>`.
Note that the existing `-debug-only=isel` will take precedence over the
new behavior and print SelectionDAG dumps of every single function
regardless of `-filter-print-funcs`'s values.
  • Loading branch information
mshockwave committed Nov 20, 2023
1 parent a1e2c65 commit 0e24179
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 43 deletions.
6 changes: 6 additions & 0 deletions llvm/docs/CodeGenerator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,12 @@ SelectionDAG-based instruction selection consists of the following steps:
After all of these steps are complete, the SelectionDAG is destroyed and the
rest of the code generation passes are run.

One of the most common ways to debug these steps is using ``-debug-only=isel``,
which prints out the DAG, along with other information like debug info,
after each of these steps. Alternatively, ``-debug-only=isel-dump`` shows only
the DAG dumps, but the results can be filtered by function names using
``-filter-print-funcs=<function names>``.

One great way to visualize what is going on here is to take advantage of a few
LLC command line options. The following options pop up a window displaying the
SelectionDAG at specific times (if you only get errors printed to the console
Expand Down
8 changes: 8 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ Changes to the C API
Changes to the CodeGen infrastructure
-------------------------------------

* A new debug type ``isel-dump`` is added to show only the SelectionDAG dumps
after each ISel phase (i.e. ``-debug-only=isel-dump``). This new debug type
can be filtered by function names using ``-filter-print-funcs=<function names>``,
the same flag used to filter IR dumps after each Pass. Note that the existing
``-debug-only=isel`` will take precedence over the new behavior and
print SelectionDAG dumps of every single function regardless of
``-filter-print-funcs``'s values.

* ``PrologEpilogInserter`` no longer supports register scavenging
during forwards frame index elimination. Targets should use
backwards frame index elimination instead.
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAGISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ class SelectionDAGISel : public MachineFunctionPass {
/// Used to report things like combines and FastISel failures.
std::unique_ptr<OptimizationRemarkEmitter> ORE;

/// True if the function currently processing is in the function printing list
/// (i.e. `-filter-print-funcs`).
/// This is primarily used by ISEL_DUMP, which spans in multiple member
/// functions. Storing the filter result here so that we only need to do the
/// filtering once.
bool MatchFilterFuncName = false;

explicit SelectionDAGISel(char &ID, TargetMachine &tm,
CodeGenOptLevel OL = CodeGenOptLevel::Default);
~SelectionDAGISel() override;
Expand Down
108 changes: 65 additions & 43 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
Expand Down Expand Up @@ -113,6 +114,7 @@
using namespace llvm;

#define DEBUG_TYPE "isel"
#define ISEL_DUMP_DEBUG_TYPE DEBUG_TYPE "-dump"

STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
STATISTIC(NumFastIselSuccess, "Number of instructions fast isel selected");
Expand Down Expand Up @@ -180,6 +182,19 @@ static const bool ViewDAGCombine1 = false, ViewLegalizeTypesDAGs = false,
ViewSchedDAGs = false, ViewSUnitDAGs = false;
#endif

#ifndef NDEBUG
#define ISEL_DUMP(X) \
do { \
if (llvm::DebugFlag && \
(isCurrentDebugType(DEBUG_TYPE) || \
(isCurrentDebugType(ISEL_DUMP_DEBUG_TYPE) && MatchFilterFuncName))) { \
X; \
} \
} while (false)
#else
#define ISEL_DUMP(X) do { } while (false)
#endif

//===---------------------------------------------------------------------===//
///
/// RegisterScheduler class - Track the registration of instruction schedulers.
Expand Down Expand Up @@ -403,6 +418,13 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
const Function &Fn = mf.getFunction();
MF = &mf;

#ifndef NDEBUG
StringRef FuncName = Fn.getName();
MatchFilterFuncName = isFunctionInPrintList(FuncName);
#else
(void)MatchFilterFuncName;
#endif

// Decide what flavour of variable location debug-info will be used, before
// we change the optimisation level.
bool InstrRef = mf.shouldUseDebugInstrRef();
Expand Down Expand Up @@ -436,7 +458,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
if (isAssignmentTrackingEnabled(*Fn.getParent()))
FnVarLocs = getAnalysis<AssignmentTrackingAnalysis>().getResults();

LLVM_DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << "\n");

UniformityInfo *UA = nullptr;
if (auto *UAPass = getAnalysisIfAvailable<UniformityInfoWrapperPass>())
Expand Down Expand Up @@ -668,8 +690,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// at this point.
FuncInfo->clear();

LLVM_DEBUG(dbgs() << "*** MachineFunction at end of ISel ***\n");
LLVM_DEBUG(MF->print(dbgs()));
ISEL_DUMP(dbgs() << "*** MachineFunction at end of ISel ***\n");
ISEL_DUMP(MF->print(dbgs()));

return true;
}
Expand Down Expand Up @@ -777,10 +799,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
BlockName =
(MF->getName() + ":" + FuncInfo->MBB->getBasicBlock()->getName()).str();
}
LLVM_DEBUG(dbgs() << "\nInitial selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nInitial selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -797,10 +819,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(BeforeLegalizeTypes, AA, OptLevel);
}

LLVM_DEBUG(dbgs() << "\nOptimized lowered selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nOptimized lowered selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -819,10 +841,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
Changed = CurDAG->LegalizeTypes();
}

LLVM_DEBUG(dbgs() << "\nType-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nType-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -843,10 +865,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeTypes, AA, OptLevel);
}

LLVM_DEBUG(dbgs() << "\nOptimized type-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nOptimized type-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -861,10 +883,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
}

if (Changed) {
LLVM_DEBUG(dbgs() << "\nVector-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nVector-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -877,10 +899,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->LegalizeTypes();
}

LLVM_DEBUG(dbgs() << "\nVector/type-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nVector/type-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -897,10 +919,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeVectorOps, AA, OptLevel);
}

LLVM_DEBUG(dbgs() << "\nOptimized vector-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nOptimized vector-legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -917,10 +939,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Legalize();
}

LLVM_DEBUG(dbgs() << "\nLegalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nLegalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -937,10 +959,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeDAG, AA, OptLevel);
}

LLVM_DEBUG(dbgs() << "\nOptimized legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nOptimized legalized selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

#ifndef NDEBUG
if (TTI.hasBranchDivergence())
Expand All @@ -961,10 +983,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
DoInstructionSelection();
}

LLVM_DEBUG(dbgs() << "\nSelected selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());
ISEL_DUMP(dbgs() << "\nSelected selection DAG: "
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
<< "'\n";
CurDAG->dump());

if (ViewSchedDAGs && MatchFilterBB)
CurDAG->viewGraph("scheduler input for " + BlockName);
Expand Down
33 changes: 33 additions & 0 deletions llvm/test/CodeGen/Generic/selectiondag-dump-filter.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; RUN: llc -debug-only=isel-dump -filter-print-funcs=foo < %s 2>&1 | FileCheck %s --check-prefix=FOO
; RUN: llc -debug-only=isel-dump -filter-print-funcs=bar < %s 2>&1 | FileCheck %s --check-prefix=BAR
; RUN: llc -debug-only=isel-dump -filter-print-funcs=foo,zap < %s 2>&1 | FileCheck %s --check-prefixes=FOO,ZAP
; Make sure the original -debug-only=isel still works.
; RUN: llc -debug-only=isel < %s 2>&1 | FileCheck %s --check-prefixes=FOO,BAR,ZAP
; REQUIRES: asserts

; FOO: === foo
; BAR-NOT: === foo
; ZAP-NOT: === foo
; FOO: # Machine code for function foo
define i32 @foo(i32 %a, i32 %b) {
%r = add i32 %a, %b
ret i32 %r
}

; BAR: === bar
; FOO-NOT: === bar
; ZAP-NOT: === bar
; BAR: # Machine code for function bar
define i32 @bar(i32 %a, i32 %b) {
%r = mul i32 %a, %b
ret i32 %r
}

; ZAP: === zap
; FOO-NOT: === zap
; BAR-NOT: === zap
; ZAP: # Machine code for function zap
define i32 @zap(i32 %a, i32 %b) {
%r = sub i32 %a, %b
ret i32 %r
}

0 comments on commit 0e24179

Please sign in to comment.