Skip to content

Commit 098259e

Browse files
matborzyszkowskiigcbot
authored andcommitted
Treat BasicBlock with only dbg calls as an empty BasicBlock
Attempt 2: Treat BasicBlock with only dbg calls as an empty BasicBlock
1 parent 86482b6 commit 098259e

File tree

3 files changed

+232
-1
lines changed

3 files changed

+232
-1
lines changed

IGC/Compiler/CISACodeGen/BlockCoalescing.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,15 @@ namespace IGC
5555
for (uint i = 0; i < patternMatch->m_numBlocks; i++)
5656
{
5757
SBasicBlock& block = patternMatch->m_blocks[i];
58+
59+
// Count dbg instructions in BB to determine whether BB can be marked as empty.
60+
// BB is empty when only br or phi instruction are in the BB.
61+
// We cannot use sizeWithoutDebug() method directly, because it also counts
62+
// phi instructions, which we can ignore here (phis are ignored during add instruction to m_dags).
63+
uint dbgInstrInBB = block.bb->size() - block.bb->sizeWithoutDebug();
64+
5865
// An empty block would have only one pattern matching the branch instruction
59-
if (block.m_dags.size() == 1)
66+
if (block.m_dags.size() - dbgInstrInBB == 1)
6067
{
6168
if (BranchInst * br = dyn_cast<BranchInst>(block.m_dags[0].m_root))
6269
{
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; The test checks if the BB with only dbg calls is treated as empty BB and
10+
; the compiler doesn't emit this BB in visaasm.
11+
12+
; For provided .ll file we can skip BB with only LOC information, e.g.:
13+
14+
; .function "_main_0"
15+
; _main_0:
16+
; FILE "/test.cl"
17+
; LOC 3
18+
; mov (M1_NM, 1) Trunc(0,0)<1> 0x0:ud
19+
; lsc_load.slm (M1_NM, 1) V0032:d32t flat[Trunc]:a32
20+
; mov (M1_NM, 1) bTrunc(0,0)<1> b(0,0)<0;1,0>
21+
; lsc_load.slm (M1_NM, 1) V0033:d32t flat[bTrunc]:a32
22+
; add (M1_NM, 1) add_(0,0)<1> V0032(0,0)<0;1,0> V0033(0,0)<0;1,0>
23+
;
24+
; _test_001_bb0: -----> We don't need emit _test_001_bb0 basic block,
25+
; LOC 0 -----> because this BB is empty (has only dbg calls
26+
; LOC 3 -----> and br instruction in .ll file)
27+
;
28+
; _test_002_exit:
29+
; mov (M1_NM, 1) resultTrunc(0,0)<1> result(0,0)<0;1,0>
30+
; lsc_store.slm (M1_NM, 1) flat[resultTrunc]:a32 add_:d32t
31+
; LOC 4
32+
; ret (M1, 1)
33+
34+
35+
; REQUIRES: llvm-14-plus, regkeys
36+
37+
; RUN: igc_opt --opaque-pointers -platformdg2 -igc-emit-visa %s -regkey DumpVISAASMToConsole | FileCheck %s
38+
39+
define spir_kernel void @test(i32 addrspace(3)* align 4 %a, i32 addrspace(3)* align 4 %b, i32 addrspace(3)* align 4 %result, <8 x i32> %r0, <3 x i32> %globalOffset) #0 !dbg !473 {
40+
entry:
41+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %b, metadata !480, metadata !DIExpression()), !dbg !483
42+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %result, metadata !481, metadata !DIExpression()), !dbg !483
43+
%0 = load i32, i32 addrspace(3)* null, align 4294967296, !dbg !484
44+
%1 = load i32, i32 addrspace(3)* %b, align 4, !dbg !485
45+
%add = add nsw i32 %0, %1, !dbg !486, !spirv.Decorations !487
46+
br label %bb0
47+
bb0:
48+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %b, metadata !480, metadata !DIExpression()), !dbg !483
49+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %result, metadata !481, metadata !DIExpression()), !dbg !483
50+
br label %exit
51+
exit:
52+
store i32 %add, i32 addrspace(3)* %result, align 4, !dbg !489
53+
ret void, !dbg !490, !stats.blockFrequency.digits !491, !stats.blockFrequency.scale !492
54+
}
55+
56+
; CHECK: .function "[[FUNC:[^ ]+]]"
57+
; CHECK: [[FUNC]]:
58+
; CHECK: FILE "/test.cl"
59+
; CHECK: LOC 3
60+
; CHECK: mov (M1_NM, 1) Trunc(0,0)<1> 0x0:ud
61+
; CHECK: lsc_load.slm (M1_NM, 1) V0032:d32t flat[Trunc]:a32
62+
; CHECK: mov (M1_NM, 1) bTrunc(0,0)<1> b(0,0)<0;1,0>
63+
; CHECK: lsc_load.slm (M1_NM, 1) V0033:d32t flat[bTrunc]:a32
64+
; CHECK: add (M1_NM, 1) add_(0,0)<1> V0032(0,0)<0;1,0> V0033(0,0)<0;1,0>
65+
; CHECK: [[BB_EXIT:[^ ]+]]
66+
; CHECK: mov (M1_NM, 1) resultTrunc(0,0)<1> result(0,0)<0;1,0>
67+
; CHECK: lsc_store.slm (M1_NM, 1) flat[resultTrunc]:a32 add_:d32t
68+
; CHECK: LOC 4
69+
; CHECK: ret (M1, 1)
70+
71+
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
72+
73+
!llvm.module.flags = !{!0, !1, !2}
74+
!llvm.dbg.cu = !{!3}
75+
!spirv.MemoryModel = !{!5}
76+
!spirv.Source = !{!6}
77+
!spirv.Generator = !{!7}
78+
!igc.functions = !{!8}
79+
!IGCMetadata = !{!14}
80+
!opencl.ocl.version = !{!471, !471}
81+
!opencl.spir.version = !{!471, !471}
82+
!llvm.ident = !{!472, !472}
83+
!printf.strings = !{}
84+
!0 = !{i32 7, !"Dwarf Version", i32 4}
85+
!1 = !{i32 2, !"Debug Info Version", i32 3}
86+
!2 = !{i32 1, !"wchar_size", i32 4}
87+
!3 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !4, producer: "clang version 15.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
88+
!4 = !DIFile(filename: "test.cl", directory: "/")
89+
!5 = !{i32 2, i32 2}
90+
!6 = !{i32 3, i32 102000}
91+
!7 = !{i16 6, i16 14}
92+
!8 = !{void (i32 addrspace(3)*, i32 addrspace(3)*, i32 addrspace(3)*, <8 x i32>, <3 x i32>)* @test, !9}
93+
!9 = !{!10, !11}
94+
!10 = !{!"function_type", i32 0}
95+
!11 = !{!"implicit_arg_desc", !12, !13}
96+
!12 = !{i32 0}
97+
!13 = !{i32 2}
98+
!14 = !{!"ModuleMD", !15}
99+
!15 = !{!"isPrecise", i1 false}
100+
!471 = !{i32 2, i32 0}
101+
!472 = !{!"clang version 15.0.0"}
102+
!473 = distinct !DISubprogram(name: "test", scope: null, file: !4, line: 1, type: !474, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, templateParams: !482, retainedNodes: !478)
103+
!474 = !DISubroutineType(types: !475)
104+
!475 = !{null, !476, !476, !476}
105+
!476 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !477, size: 64, dwarfAddressSpace: 3)
106+
!477 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
107+
!478 = !{!479, !480, !481}
108+
!479 = !DILocalVariable(name: "a", arg: 1, scope: !473, file: !4, line: 1, type: !476)
109+
!480 = !DILocalVariable(name: "b", arg: 2, scope: !473, file: !4, line: 1, type: !476)
110+
!481 = !DILocalVariable(name: "result", arg: 3, scope: !473, file: !4, line: 1, type: !476)
111+
!482 = !{}
112+
!483 = !DILocation(line: 0, scope: !473)
113+
!484 = !DILocation(line: 3, column: 17, scope: !473)
114+
!485 = !DILocation(line: 3, column: 24, scope: !473)
115+
!486 = !DILocation(line: 3, column: 22, scope: !473)
116+
!487 = !{!488}
117+
!488 = !{i32 4469}
118+
!489 = !DILocation(line: 3, column: 15, scope: !473)
119+
!490 = !DILocation(line: 4, column: 1, scope: !473)
120+
!491 = !{!"80"}
121+
!492 = !{!"-3"}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; The test checks if the BB with phi and dbg calls is treated as empty BB and
10+
; the compiler doesn't emit this BB in visaasm.
11+
12+
; REQUIRES: llvm-14-plus, regkeys
13+
14+
; RUN: igc_opt --opaque-pointers -platformdg2 -igc-emit-visa %s -regkey DumpVISAASMToConsole | FileCheck %s
15+
16+
define spir_kernel void @test(i32 addrspace(3)* align 4 %a, i32 addrspace(3)* align 4 %b, i32 addrspace(3)* align 4 %result, <8 x i32> %r0, <3 x i32> %globalOffset) #0 !dbg !473 {
17+
entry:
18+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %b, metadata !480, metadata !DIExpression()), !dbg !483
19+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %result, metadata !481, metadata !DIExpression()), !dbg !483
20+
%0 = load i32, i32 addrspace(3)* null, align 4294967296, !dbg !484
21+
%1 = load i32, i32 addrspace(3)* %b, align 4, !dbg !485
22+
%add = add nsw i32 %0, %1, !dbg !486, !spirv.Decorations !487
23+
%cmp = icmp eq i32 %add, 0
24+
br i1 %cmp, label %bb0, label %exit
25+
bb0:
26+
%phi.1 = phi i1 [ %cmp, %entry ]
27+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %b, metadata !480, metadata !DIExpression()), !dbg !483
28+
call void @llvm.dbg.value(metadata i32 addrspace(3)* %result, metadata !481, metadata !DIExpression()), !dbg !483
29+
br label %exit
30+
exit:
31+
store i32 %add, i32 addrspace(3)* %result, align 4, !dbg !489
32+
ret void, !dbg !490, !stats.blockFrequency.digits !491, !stats.blockFrequency.scale !492
33+
}
34+
35+
; CHECK: .function "[[FUNC:[^ ]+]]"
36+
; CHECK: [[FUNC]]:
37+
; CHECK: FILE "/test.cl"
38+
; CHECK: LOC 3
39+
; CHECK: mov (M1_NM, 1) Trunc(0,0)<1> 0x0:ud
40+
; CHECK: lsc_load.slm (M1_NM, 1) V0032:d32t flat[Trunc]:a32
41+
; CHECK: mov (M1_NM, 1) bTrunc(0,0)<1> b(0,0)<0;1,0>
42+
; CHECK: lsc_load.slm (M1_NM, 1) V0033:d32t flat[bTrunc]:a32
43+
; CHECK: add (M1_NM, 1) add_(0,0)<1> V0032(0,0)<0;1,0> V0033(0,0)<0;1,0>
44+
; CHECK: cmp.eq (M1, 16) P1 add_(0,0)<0;1,0> 0x0:d
45+
; CHECK: cmp.eq (M5, 16) P1 add_(0,0)<0;1,0> 0x0:d
46+
; CHECK: (!P1) goto (M1, 32) [[BB_EXIT:[^ ]+]]
47+
; CHECK: [[BB_EXIT]]
48+
; CHECK: mov (M1_NM, 1) resultTrunc(0,0)<1> result(0,0)<0;1,0>
49+
; CHECK: lsc_store.slm (M1_NM, 1) flat[resultTrunc]:a32 add_:d32t
50+
; CHECK: LOC 4
51+
; CHECK: ret (M1, 1)
52+
53+
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
54+
55+
!llvm.module.flags = !{!0, !1, !2}
56+
!llvm.dbg.cu = !{!3}
57+
!spirv.MemoryModel = !{!5}
58+
!spirv.Source = !{!6}
59+
!spirv.Generator = !{!7}
60+
!igc.functions = !{!8}
61+
!IGCMetadata = !{!14}
62+
!opencl.ocl.version = !{!471, !471}
63+
!opencl.spir.version = !{!471, !471}
64+
!llvm.ident = !{!472, !472}
65+
!printf.strings = !{}
66+
!0 = !{i32 7, !"Dwarf Version", i32 4}
67+
!1 = !{i32 2, !"Debug Info Version", i32 3}
68+
!2 = !{i32 1, !"wchar_size", i32 4}
69+
!3 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !4, producer: "clang version 15.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
70+
!4 = !DIFile(filename: "test.cl", directory: "/")
71+
!5 = !{i32 2, i32 2}
72+
!6 = !{i32 3, i32 102000}
73+
!7 = !{i16 6, i16 14}
74+
!8 = !{void (i32 addrspace(3)*, i32 addrspace(3)*, i32 addrspace(3)*, <8 x i32>, <3 x i32>)* @test, !9}
75+
!9 = !{!10, !11}
76+
!10 = !{!"function_type", i32 0}
77+
!11 = !{!"implicit_arg_desc", !12, !13}
78+
!12 = !{i32 0}
79+
!13 = !{i32 2}
80+
!14 = !{!"ModuleMD", !15}
81+
!15 = !{!"isPrecise", i1 false}
82+
!471 = !{i32 2, i32 0}
83+
!472 = !{!"clang version 15.0.0"}
84+
!473 = distinct !DISubprogram(name: "test", scope: null, file: !4, line: 1, type: !474, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, templateParams: !482, retainedNodes: !478)
85+
!474 = !DISubroutineType(types: !475)
86+
!475 = !{null, !476, !476, !476}
87+
!476 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !477, size: 64, dwarfAddressSpace: 3)
88+
!477 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
89+
!478 = !{!479, !480, !481}
90+
!479 = !DILocalVariable(name: "a", arg: 1, scope: !473, file: !4, line: 1, type: !476)
91+
!480 = !DILocalVariable(name: "b", arg: 2, scope: !473, file: !4, line: 1, type: !476)
92+
!481 = !DILocalVariable(name: "result", arg: 3, scope: !473, file: !4, line: 1, type: !476)
93+
!482 = !{}
94+
!483 = !DILocation(line: 0, scope: !473)
95+
!484 = !DILocation(line: 3, column: 17, scope: !473)
96+
!485 = !DILocation(line: 3, column: 24, scope: !473)
97+
!486 = !DILocation(line: 3, column: 22, scope: !473)
98+
!487 = !{!488}
99+
!488 = !{i32 4469}
100+
!489 = !DILocation(line: 3, column: 15, scope: !473)
101+
!490 = !DILocation(line: 4, column: 1, scope: !473)
102+
!491 = !{!"80"}
103+
!492 = !{!"-3"}

0 commit comments

Comments
 (0)