Skip to content

Commit 3fee76c

Browse files
Marek Sedláčekarpilipe
authored andcommitted
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
1 parent a4b2237 commit 3fee76c

File tree

5 files changed

+33
-26
lines changed

5 files changed

+33
-26
lines changed

llvm/include/llvm/Analysis/CFGPrinter.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,12 @@ std::string CompleteNodeLabelString(
147147
enum { MaxColumns = 80 };
148148
std::string Str;
149149
raw_string_ostream OS(Str);
150-
151-
if (Node->getName().empty()) {
152-
Node->printAsOperand(OS, false);
153-
OS << ':';
154-
}
155-
156150
HandleBasicBlock(OS, *Node);
157151
std::string OutStr = OS.str();
158-
if (OutStr[0] == '\n')
152+
// Remove "%" from BB name
153+
if (OutStr[0] == '%') {
159154
OutStr.erase(OutStr.begin());
155+
}
160156

161157
unsigned ColNum = 0;
162158
unsigned LastSpace = 0;
@@ -182,6 +178,8 @@ std::string CompleteNodeLabelString(
182178
if (OutStr[i] == ' ')
183179
LastSpace = i;
184180
}
181+
// Replace \l after BB name with | to separate it into header
182+
OutStr.replace(OutStr.find_first_of('\\') + 1, 1, "|");
185183
return OutStr;
186184
}
187185

@@ -206,11 +204,20 @@ struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
206204
return SimpleNodeLabelString(Node);
207205
}
208206

207+
static void printBasicBlock(raw_string_ostream &OS, const BasicBlock &Node) {
208+
// Prepend label name
209+
Node.printAsOperand(OS, false);
210+
OS << ":\n";
211+
for (auto J = Node.begin(), JE = Node.end(); J != JE; ++J) {
212+
const Instruction *Inst = &*J;
213+
OS << *Inst << "\n";
214+
}
215+
}
216+
209217
static std::string getCompleteNodeLabel(
210218
const BasicBlock *Node, DOTFuncInfo *,
211219
function_ref<void(raw_string_ostream &, const BasicBlock &)>
212-
HandleBasicBlock = [](raw_string_ostream &OS,
213-
const BasicBlock &Node) -> void { OS << Node; },
220+
HandleBasicBlock = printBasicBlock,
214221
function_ref<void(std::string &, unsigned &, unsigned)>
215222
HandleComment = eraseComment) {
216223
return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);

llvm/test/Analysis/DotMachineCFG/AMDGPU/functions.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ body: |
1212

1313
# MCFG: digraph "Machine CFG for 'func2' function"
1414
# MCFG-NEXT: label="Machine CFG for 'func2' function"
15-
# 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}"];
15+
# 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}"];
1616
---
1717
name: func2
1818
body: |

llvm/test/Analysis/DotMachineCFG/AMDGPU/irreducible.mir

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@
55

66
# MCFG: digraph "Machine CFG for 'irreducible' function"
77
# MCFG-NEXT: label="Machine CFG for 'irreducible' function"
8-
# 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}"];
8+
# 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}"];
99
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
1010
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
11-
# 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}"];
11+
# 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}"];
1212
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
13-
# 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}"];
13+
# 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}"];
1414
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
15-
# 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}"];
15+
# 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}"];
1616
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
17-
# 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}"];
17+
# 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}"];
1818
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
1919
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
20-
# 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}"];
20+
# 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}"];
2121
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
2222
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} -> Node{{[0-9A-Za-z]*}};
23-
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{%bb.6:bb.6:\l\l\l S_ENDPGM 0\l}"];
23+
# MCFG-NEXT: Node{{[0-9A-Za-z]*}} [shape=record,label="{bb.6:|\l\l S_ENDPGM 0\l}"];
2424

2525
# MCFG-ONLY: digraph "Machine CFG for 'irreducible' function"
2626
# MCFG-ONLY-NEXT: label="Machine CFG for 'irreducible' function"

llvm/test/Other/cfg_deopt_unreach.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ declare i8 @llvm.experimental.deoptimize.i8(...)
1414
define i8 @callee(ptr %c) alwaysinline {
1515
%c0 = load volatile i1, ptr %c
1616
br i1 %c0, label %lleft, label %lright
17-
; NO-FLAGS: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
18-
; DEOPT-NOT: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
19-
; UNREACH: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
20-
; BOTH-FLAGS-NOT: label="{lleft: \l %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
17+
; NO-FLAGS: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
18+
; DEOPT-NOT: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
19+
; UNREACH: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
20+
; BOTH-FLAGS-NOT: label="{lleft:| %v0 = call i8 (...) @llvm.experimental.deoptimize.i8(i32 1) [ \"deopt\"(i32 1)\l... ]\l ret i8 %v0\l}"
2121
lleft:
2222
%v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i32 1) ]
2323
ret i8 %v0
2424

25-
; NO-FLAGS: label="{lright: \l unreachable\l}"
26-
; DEOPT: label="{lright: \l unreachable\l}"
27-
; UNREACH-NOT: label="{lright: \l unreachable\l}"
28-
; BOTH-FLAGS-NOT: label="{lright: \l unreachable\l}"
25+
; NO-FLAGS: label="{lright:| unreachable\l}"
26+
; DEOPT: label="{lright:| unreachable\l}"
27+
; UNREACH-NOT: label="{lright:| unreachable\l}"
28+
; BOTH-FLAGS-NOT: label="{lright:| unreachable\l}"
2929
lright:
3030
unreachable
3131
}

polly/test/ScopDetect/dot-scops-npm.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1515
define void @func_npm(i32 %n, i32 %m, ptr noalias nonnull %A) {
1616
; CHECK: digraph "Scop Graph for 'func_npm' function"
1717
; CHECK-NEXT: label="Scop Graph for 'func_npm' function"
18-
; CHECK: Node0x[[EntryID:.*]] [shape=record,label="{entry:\l br label %outer.for\l}"];
18+
; CHECK: Node0x[[EntryID:.*]] [shape=record,label="{entry:| br label %outer.for\l}"];
1919
; CHECK-NEXT: Node0x[[EntryID]] -> Node0x[[OUTER_FOR_ID:.*]];
2020
; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] [shape=record,label="{outer.for:
2121
; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] -> Node0x[[INNER_FOR_ID:.*]];

0 commit comments

Comments
 (0)