Skip to content

Commit 65480d4

Browse files
KorovinVladigcbot
authored andcommitted
Introduce surface commoning
.
1 parent 80c96b6 commit 65480d4

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/GenXCategory.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ namespace {
201201
private:
202202
using ConvListT = std::array<llvm::Instruction *, vc::numRegCategories()>;
203203

204+
bool commonUpSurface(BasicBlock *BB);
204205
bool processFunction(Function *F);
205206
bool fixCircularPhis(Function *F);
206207
bool processValue(Value *V);
@@ -505,6 +506,50 @@ static bool commonUpPredicate(BasicBlock *BB) {
505506
return Changed;
506507
}
507508

509+
/***********************************************************************
510+
* isToSurfaceConversion : returns true if the input instruction is a
511+
* surface conversion intrinsic.
512+
*/
513+
static bool isToSurfaceConversion(Instruction *I,
514+
const GenXLiveness *Liveness) {
515+
if (IntrinsicInst *IC = dyn_cast<IntrinsicInst>(I)) {
516+
unsigned IntrinsicID = vc::getAnyIntrinsicID(IC);
517+
if (IntrinsicID != GenXIntrinsic::genx_convert)
518+
return false;
519+
if (auto LR = Liveness->getLiveRangeOrNull(I)) {
520+
auto Cat = LR->getCategory();
521+
if (Cat == vc::RegCategory::Surface)
522+
return true;
523+
}
524+
}
525+
return false;
526+
}
527+
528+
/***********************************************************************
529+
* commonUpSurface : perform surface commoning to reduce number of
530+
* instructions to stop the surface conversion falling outside of the
531+
* register into which it points to avoid going out of spec (256). The
532+
* logic is applied within a basic block to avoid dramatic live ranges
533+
* increase.
534+
*/
535+
bool GenXCategory::commonUpSurface(BasicBlock *BB) {
536+
bool Modified = false;
537+
// Maps the original value to after-conversion value.
538+
SmallDenseMap<Value *, Value *> ConvMap;
539+
for (auto bi = BB->begin(), be = BB->end(); bi != be; ++bi) {
540+
Instruction *I = &*bi;
541+
if (!isToSurfaceConversion(I, Liveness))
542+
continue;
543+
IGC_ASSERT(I->hasOneUse());
544+
if (!ConvMap.insert({I->getOperand(0), I}).second) {
545+
Modified = true;
546+
I->replaceAllUsesWith(ConvMap[I->getOperand(0)]);
547+
ToErase.push_back(I);
548+
}
549+
}
550+
return Modified;
551+
}
552+
508553
/***********************************************************************
509554
* processFunction : run the category conversion pass for this Function
510555
*
@@ -538,6 +583,8 @@ bool GenXCategory::processFunction(Function *F)
538583

539584
// This commons up constpred calls just loaded.
540585
Modified |= commonUpPredicate(BB);
586+
// This commons up to-surface conversion calls.
587+
Modified |= commonUpSurface(BB);
541588

542589
// Erase instructions (and their live ranges) as requested by processValue.
543590
for (unsigned i = 0, e = ToErase.size(); i != e; ++i) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2023 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; RUN: opt %use_old_pass_manager% -GenXModule -GenXNumberingWrapper -GenXLiveRangesWrapper -GenXCategoryWrapper \
10+
; RUN: -march=genx64 -mtriple=spir64-unknown-unknown -mcpu=Gen9 -S < %s | FileCheck %s
11+
12+
; Function Attrs: nofree nounwind readonly
13+
declare <32 x i32> @llvm.genx.oword.ld.unaligned.v32i32(i32, i32, i32) #1
14+
15+
; Function Attrs: nounwind
16+
declare void @llvm.genx.oword.st.v32i32(i32, i32, <32 x i32>) #2
17+
18+
define dllexport void @kernel(i32 %offset, i64 %impl.arg.private.base) #0 {
19+
entry:
20+
; CHECK: call i32 @llvm.genx.convert.i32(i32 2)
21+
%ld1 = tail call <32 x i32> @llvm.genx.oword.ld.unaligned.v32i32(i32 0, i32 2, i32 %offset)
22+
; CHECK: call i32 @llvm.genx.convert.i32(i32 3)
23+
%ld3 = tail call <32 x i32> @llvm.genx.oword.ld.unaligned.v32i32(i32 0, i32 3, i32 %offset)
24+
; CHECK-NOT: call i32 @llvm.genx.convert.i32(i32 3)
25+
call void @llvm.genx.oword.st.v32i32(i32 3, i32 0, <32 x i32> %ld1)
26+
; CHECK-NOT: call i32 @llvm.genx.convert.i32(i32 2)
27+
call void @llvm.genx.oword.st.v32i32(i32 2, i32 0, <32 x i32> %ld3)
28+
br label %BB
29+
BB:
30+
; CHECK: BB
31+
; CHECK: call i32 @llvm.genx.convert.i32(i32 2)
32+
%ld7 = tail call <32 x i32> @llvm.genx.oword.ld.unaligned.v32i32(i32 0, i32 2, i32 %offset)
33+
; CHECK: call i32 @llvm.genx.convert.i32(i32 3)
34+
%ld9 = tail call <32 x i32> @llvm.genx.oword.ld.unaligned.v32i32(i32 0, i32 3, i32 %offset)
35+
; CHECK-NOT: call i32 @llvm.genx.convert.i32(i32 3)
36+
call void @llvm.genx.oword.st.v32i32(i32 3, i32 128, <32 x i32> %ld7)
37+
; CHECK-NOT: call i32 @llvm.genx.convert.i32(i32 2)
38+
call void @llvm.genx.oword.st.v32i32(i32 2, i32 128, <32 x i32> %ld9)
39+
ret void
40+
}
41+
42+
attributes #0 = { "CMGenxMain" }
43+
attributes #1 = { nofree nounwind readonly }
44+
attributes #2 = { nounwind }
45+
46+
!genx.kernels = !{!6}
47+
!genx.kernel.internal = !{!11}
48+
49+
!0 = !{i32 2, i32 2}
50+
!1 = !{i32 0, i32 0}
51+
!2 = !{i32 1, i32 2}
52+
!3 = !{i32 2, i32 0}
53+
!4 = !{}
54+
!5 = !{i16 6, i16 14}
55+
!6 = !{void (i32, i64)* @kernel, !"kernel", !7, i32 0, !8, !9, !10, i32 0}
56+
!7 = !{i32 0, i32 96}
57+
!8 = !{i32 72, i32 64}
58+
!9 = !{i32 0}
59+
!10 = !{!""}
60+
!11 = !{void (i32, i64)* @kernel, !1, !12, !4, !13}
61+
!12 = !{i32 0, i32 1}
62+
!13 = !{i32 -1, i32 1}

0 commit comments

Comments
 (0)