[SelectionDAG] Add support to filter SelectionDAG dumps during ISel by 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.
This commit is contained in:
parent
a1e2c65663
commit
0e24179797
@ -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
|
||||
|
@ -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.
|
||||
|
@ -61,6 +61,13 @@ public:
|
||||
/// 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;
|
||||
|
@ -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"
|
||||
@ -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");
|
||||
@ -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.
|
||||
@ -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();
|
||||
@ -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>())
|
||||
@ -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;
|
||||
}
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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())
|
||||
@ -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);
|
||||
|
33
llvm/test/CodeGen/Generic/selectiondag-dump-filter.ll
Normal file
33
llvm/test/CodeGen/Generic/selectiondag-dump-filter.ll
Normal file
@ -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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user