Index: llvm/include/llvm/Analysis/CFGPrinter.h =================================================================== --- llvm/include/llvm/Analysis/CFGPrinter.h +++ llvm/include/llvm/Analysis/CFGPrinter.h @@ -147,16 +147,12 @@ 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,9 @@ 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 +205,20 @@ 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 - HandleBasicBlock = [](raw_string_ostream &OS, - const BasicBlock &Node) -> void { OS << Node; }, + HandleBasicBlock = printBasicBlock, function_ref HandleComment = eraseComment) { return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment); Index: llvm/test/Analysis/DotMachineCFG/AMDGPU/functions.mir =================================================================== --- llvm/test/Analysis/DotMachineCFG/AMDGPU/functions.mir +++ llvm/test/Analysis/DotMachineCFG/AMDGPU/functions.mir @@ -12,7 +12,7 @@ # 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:|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}"]; --- name: func2 body: | Index: llvm/test/Analysis/DotMachineCFG/AMDGPU/irreducible.mir =================================================================== --- llvm/test/Analysis/DotMachineCFG/AMDGPU/irreducible.mir +++ llvm/test/Analysis/DotMachineCFG/AMDGPU/irreducible.mir @@ -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:|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-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:|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]*}} -> 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:|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]*}} -> 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:|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]*}} -> 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:|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]*}} -> 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:|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]*}} -> 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:|bb.6:\l\l\l S_ENDPGM 0\l}"]; # MCFG-ONLY: digraph "Machine CFG for 'irreducible' function" # MCFG-ONLY-NEXT: label="Machine CFG for 'irreducible' function" Index: llvm/test/Other/cfg_deopt_unreach.ll =================================================================== --- llvm/test/Other/cfg_deopt_unreach.ll +++ llvm/test/Other/cfg_deopt_unreach.ll @@ -14,18 +14,18 @@ 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 } Index: polly/test/ScopDetect/dot-scops-npm.ll =================================================================== --- polly/test/ScopDetect/dot-scops-npm.ll +++ polly/test/ScopDetect/dot-scops-npm.ll @@ -15,7 +15,7 @@ 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:.*]];