Index: llvm/include/llvm/Analysis/CFGPrinter.h =================================================================== --- llvm/include/llvm/Analysis/CFGPrinter.h +++ llvm/include/llvm/Analysis/CFGPrinter.h @@ -135,7 +135,6 @@ Node->printAsOperand(OS, false); return OS.str(); } - template std::string CompleteNodeLabelString( const BasicBlockT *Node, @@ -147,17 +146,24 @@ 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') OutStr.erase(OutStr.begin()); + // Preprend BB name if the name is not set and the code does not start + // with BB number label + if (Node->getName().empty() && !std::isdigit(OutStr[0])) { + std::string LabelStr; + raw_string_ostream OSLabel(LabelStr); + Node->printAsOperand(OSLabel, false); + OSLabel << ":\n"; + OutStr = OSLabel.str() + OutStr; + } + + if (OutStr[0] == '%') + OutStr.erase(OutStr.begin()); + unsigned ColNum = 0; unsigned LastSpace = 0; for (unsigned i = 0; i != OutStr.length(); ++i) { @@ -182,6 +188,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; } 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 }