mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 00:36:34 +00:00
Headers for basic blocks in CFG dot graphs
This change adds separators for basic block names, which makes it easier to find a basic block based on its name and separates it from the code. Currently there is also a chance that the basic block label will be present twice, that is in case the basic block has explicit numbering, this change fixes this bug. Differential Revision: https://reviews.llvm.org/D154102
This commit is contained in:
parent
a4b2237cfc
commit
3fee76cff3
@ -147,16 +147,12 @@ std::string CompleteNodeLabelString(
|
||||
enum { MaxColumns = 80 };
|
||||
std::string Str;
|
||||
raw_string_ostream OS(Str);
|
||||
|
||||
if (Node->getName().empty()) {
|
||||
Node->printAsOperand(OS, false);
|
||||
OS << ':';
|
||||
}
|
||||
|
||||
HandleBasicBlock(OS, *Node);
|
||||
std::string OutStr = OS.str();
|
||||
if (OutStr[0] == '\n')
|
||||
// Remove "%" from BB name
|
||||
if (OutStr[0] == '%') {
|
||||
OutStr.erase(OutStr.begin());
|
||||
}
|
||||
|
||||
unsigned ColNum = 0;
|
||||
unsigned LastSpace = 0;
|
||||
@ -182,6 +178,8 @@ std::string CompleteNodeLabelString(
|
||||
if (OutStr[i] == ' ')
|
||||
LastSpace = i;
|
||||
}
|
||||
// Replace \l after BB name with | to separate it into header
|
||||
OutStr.replace(OutStr.find_first_of('\\') + 1, 1, "|");
|
||||
return OutStr;
|
||||
}
|
||||
|
||||
@ -206,11 +204,20 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
|
||||
return SimpleNodeLabelString(Node);
|
||||
}
|
||||
|
||||
static void printBasicBlock(raw_string_ostream &OS, const BasicBlock &Node) {
|
||||
// Prepend label name
|
||||
Node.printAsOperand(OS, false);
|
||||
OS << ":\n";
|
||||
for (auto J = Node.begin(), JE = Node.end(); J != JE; ++J) {
|
||||
const Instruction *Inst = &*J;
|
||||
OS << *Inst << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getCompleteNodeLabel(
|
||||
const BasicBlock *Node, DOTFuncInfo *,
|
||||
function_ref<void(raw_string_ostream &, const BasicBlock &)>
|
||||
HandleBasicBlock = [](raw_string_ostream &OS,
|
||||
const BasicBlock &Node) -> void { OS << Node; },
|
||||
HandleBasicBlock = printBasicBlock,
|
||||
function_ref<void(std::string &, unsigned &, unsigned)>
|
||||
HandleComment = eraseComment) {
|
||||
return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
|
||||
|
@ -12,7 +12,7 @@ body: |
|
||||
|
||||
# MCFG: digraph "Machine CFG for 'func2' function"
|
||||
# MCFG-NEXT: label="Machine CFG for 'func2' function"
|
||||
# MCFG: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.0:bb.0:\l $sgpr0 = S_LOAD_DWORD_IMM $sgpr12_sgpr13, 0, 0\l $sgpr1 = S_LOAD_DWORD_IMM $sgpr6_sgpr7, 0, 0\l $sgpr2 = S_LOAD_DWORD_IMM $sgpr14_sgpr15, 0, 0\l S_ENDPGM 0\l}"];
|
||||
# MCFG: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.0:| $sgpr0 = S_LOAD_DWORD_IMM $sgpr12_sgpr13, 0, 0\l $sgpr1 = S_LOAD_DWORD_IMM $sgpr6_sgpr7, 0, 0\l $sgpr2 = S_LOAD_DWORD_IMM $sgpr14_sgpr15, 0, 0\l S_ENDPGM 0\l}"];
|
||||
---
|
||||
name: func2
|
||||
body: |
|
||||
|
@ -5,22 +5,22 @@
|
||||
|
||||
# MCFG: digraph "Machine CFG for 'irreducible' function"
|
||||
# MCFG-NEXT: label="Machine CFG for 'irreducible' function"
|
||||
# MCFG: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.0:bb.0:\l successors: %bb.1(0x40000000), %bb.2(0x40000000)\l liveins: $vgpr0, $vgpr1, $vgpr2, $sgpr4_sgpr5, $sgpr6_sgpr7, $sgpr8_sgpr9,\l... $sgpr10_sgpr11, $sgpr14, $sgpr15, $sgpr16\l %0:sreg_32 = IMPLICIT_DEF\l %1:vgpr_32 = COPY $vgpr0\l %2:vgpr_32 = V_MOV_B32_e32 0, implicit $exec\l S_CMP_EQ_U32 %0:sreg_32, 0, implicit-def $scc\l S_CBRANCH_SCC1 %bb.1, implicit $scc\l S_BRANCH %bb.2\l}"];
|
||||
# MCFG: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.0:| successors: %bb.1(0x40000000), %bb.2(0x40000000)\l liveins: $vgpr0, $vgpr1, $vgpr2, $sgpr4_sgpr5, $sgpr6_sgpr7, $sgpr8_sgpr9,\l... $sgpr10_sgpr11, $sgpr14, $sgpr15, $sgpr16\l %0:sreg_32 = IMPLICIT_DEF\l %1:vgpr_32 = COPY $vgpr0\l %2:vgpr_32 = V_MOV_B32_e32 0, implicit $exec\l S_CMP_EQ_U32 %0:sreg_32, 0, implicit-def $scc\l S_CBRANCH_SCC1 %bb.1, implicit $scc\l S_BRANCH %bb.2\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.1:bb.1:\l\l successors: %bb.3(0x80000000)\l\l %3:vgpr_32 = PHI %2:vgpr_32, %bb.0, %4:vgpr_32, %bb.5\l %5:vgpr_32 = V_ADD_U32_e64 %3:vgpr_32, 1, 0, implicit $exec\l S_BRANCH %bb.3\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.1:|\l successors: %bb.3(0x80000000)\l\l %3:vgpr_32 = PHI %2:vgpr_32, %bb.0, %4:vgpr_32, %bb.5\l %5:vgpr_32 = V_ADD_U32_e64 %3:vgpr_32, 1, 0, implicit $exec\l S_BRANCH %bb.3\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.2:bb.2:\l\l successors: %bb.3(0x80000000)\l\l %6:vgpr_32 = PHI %2:vgpr_32, %bb.0, %4:vgpr_32, %bb.4\l %7:vgpr_32 = V_ADD_U32_e64 %6:vgpr_32, 2, 0, implicit $exec\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.2:|\l successors: %bb.3(0x80000000)\l\l %6:vgpr_32 = PHI %2:vgpr_32, %bb.0, %4:vgpr_32, %bb.4\l %7:vgpr_32 = V_ADD_U32_e64 %6:vgpr_32, 2, 0, implicit $exec\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.3:bb.3:\l\l successors: %bb.4(0x80000000)\l\l %4:vgpr_32 = PHI %5:vgpr_32, %bb.1, %7:vgpr_32, %bb.2\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.3:|\l successors: %bb.4(0x80000000)\l\l %4:vgpr_32 = PHI %5:vgpr_32, %bb.1, %7:vgpr_32, %bb.2\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.4:bb.4:\l\l successors: %bb.2(0x40000000), %bb.5(0x40000000)\l\l %8:vgpr_32 = V_AND_B32_e32 3, %1:vgpr_32, implicit $exec\l %9:sreg_64 = V_CMP_EQ_U32_e64 %8:vgpr_32, 2, implicit $exec\l %10:sreg_64 = SI_IF killed %9:sreg_64, %bb.2, implicit-def dead $exec,\l... implicit-def dead $scc, implicit $exec\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.4:|\l successors: %bb.2(0x40000000), %bb.5(0x40000000)\l\l %8:vgpr_32 = V_AND_B32_e32 3, %1:vgpr_32, implicit $exec\l %9:sreg_64 = V_CMP_EQ_U32_e64 %8:vgpr_32, 2, implicit $exec\l %10:sreg_64 = SI_IF killed %9:sreg_64, %bb.2, implicit-def dead $exec,\l... implicit-def dead $scc, implicit $exec\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.5:bb.5:\l\l successors: %bb.1(0x40000000), %bb.6(0x40000000)\l\l %11:sreg_64 = V_CMP_EQ_U32_e64 %8:vgpr_32, 1, implicit $exec\l %12:sreg_64 = SI_IF killed %11:sreg_64, %bb.1, implicit-def dead $exec,\l... implicit-def dead $scc, implicit $exec\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.5:|\l successors: %bb.1(0x40000000), %bb.6(0x40000000)\l\l %11:sreg_64 = V_CMP_EQ_U32_e64 %8:vgpr_32, 1, implicit $exec\l %12:sreg_64 = SI_IF killed %11:sreg_64, %bb.1, implicit-def dead $exec,\l... implicit-def dead $scc, implicit $exec\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.6:bb.6:\l\l\l S_ENDPGM 0\l}"];
|
||||
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.6:|\l\l S_ENDPGM 0\l}"];
|
||||
|
||||
# MCFG-ONLY: digraph "Machine CFG for 'irreducible' function"
|
||||
# MCFG-ONLY-NEXT: label="Machine CFG for 'irreducible' function"
|
||||
|
@ -14,18 +14,18 @@ declare i8 @llvm.experimental.deoptimize.i8(...)
|
||||
define i8 @callee(ptr %c) alwaysinline {
|
||||
%c0 = load volatile i1, ptr %c
|
||||
br i1 %c0, label %lleft, label %lright
|
||||
; NO-FLAGS: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; DEOPT-NOT: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; UNREACH: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; BOTH-FLAGS-NOT: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; NO-FLAGS: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; DEOPT-NOT: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; UNREACH: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
; BOTH-FLAGS-NOT: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
|
||||
lleft:
|
||||
%v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i32 1) ]
|
||||
ret i8 %v0
|
||||
|
||||
; NO-FLAGS: label="{lright: \l unreachable\l}"
|
||||
; DEOPT: label="{lright: \l unreachable\l}"
|
||||
; UNREACH-NOT: label="{lright: \l unreachable\l}"
|
||||
; BOTH-FLAGS-NOT: label="{lright: \l unreachable\l}"
|
||||
; NO-FLAGS: label="{lright:| unreachable\l}"
|
||||
; DEOPT: label="{lright:| unreachable\l}"
|
||||
; UNREACH-NOT: label="{lright:| unreachable\l}"
|
||||
; BOTH-FLAGS-NOT: label="{lright:| unreachable\l}"
|
||||
lright:
|
||||
unreachable
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
define void @func_npm(i32 %n, i32 %m, ptr noalias nonnull %A) {
|
||||
; CHECK: digraph "Scop Graph for 'func_npm' function"
|
||||
; CHECK-NEXT: label="Scop Graph for 'func_npm' function"
|
||||
; CHECK: Node0x[[EntryID:.*]] [shape=record,label="{entry:\l br label %outer.for\l}"];
|
||||
; CHECK: Node0x[[EntryID:.*]] [shape=record,label="{entry:| br label %outer.for\l}"];
|
||||
; CHECK-NEXT: Node0x[[EntryID]] -> Node0x[[OUTER_FOR_ID:.*]];
|
||||
; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] [shape=record,label="{outer.for:
|
||||
; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] -> Node0x[[INNER_FOR_ID:.*]];
|
||||
|
Loading…
x
Reference in New Issue
Block a user