Skip to content

Commit 709a2e4

Browse files
admitricigcbot
authored andcommitted
Reuse constant vector payload for subsequent stores
Reuse constant vector payload for subsequent stores in the same basic block in EmitVISA when possible
1 parent 4c200ff commit 709a2e4

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11271,6 +11271,7 @@ void EmitPass::emitStoreRawIndexed(
1127111271
varOffset,
1127211272
immOffset,
1127311273
pValToStore,
11274+
inst->getParent(),
1127411275
cacheOpts,
1127511276
inst->getAlignment(),
1127611277
false);
@@ -11455,6 +11456,7 @@ void EmitPass::emitStore(
1145511456
varOffset,
1145611457
immOffset,
1145711458
inst->getValueOperand(),
11459+
inst->getParent(),
1145811460
cacheOpts,
1145911461
IGCLLVM::getAlignmentValue(inst),
1146011462
inst->getMetadata("enable.vmask"));
@@ -11974,6 +11976,39 @@ CVariable* EmitPass::BroadcastIfUniform(CVariable* pVar, bool nomask)
1197411976
return pVar;
1197511977
}
1197611978

11979+
// If constant vector is stored and there is already var instance for it
11980+
// try reusing it (if it was defined in the same basic block)
11981+
// or create a new var instance and make it available for reusing in further stores
11982+
CVariable* EmitPass::tryReusingConstVectorStoreData(Value* storedVal, BasicBlock* BB, bool isBroadcast)
11983+
{
11984+
Constant* constantStoredVal = dyn_cast<Constant>(storedVal);
11985+
if (!constantStoredVal || !constantStoredVal->getType()->isVectorTy())
11986+
{
11987+
return nullptr;
11988+
}
11989+
11990+
ConstVectorStoreData& storeData = m_constantVectorStores[constantStoredVal];
11991+
if (storeData.BB != BB)
11992+
{
11993+
// the variable is not yet created or has different BB, create the new instance
11994+
storeData = {GetSymbol(constantStoredVal), {nullptr, nullptr}, BB};
11995+
IGC_ASSERT(!isBroadcast); // if we need broadcast we must have already created it for this store
11996+
}
11997+
11998+
if (!isBroadcast)
11999+
{
12000+
return storeData.var;
12001+
}
12002+
12003+
CVariable* broadcastedVar = storeData.broadcastedVar[m_encoder->IsSecondHalf()];
12004+
if (!broadcastedVar)
12005+
{
12006+
broadcastedVar = BroadcastIfUniform(storeData.var);
12007+
storeData.broadcastedVar[m_encoder->IsSecondHalf()] = broadcastedVar;
12008+
}
12009+
return broadcastedVar;
12010+
}
12011+
1197712012
// Get either the 1st/2nd of the execution mask based on whether IsSecondHalf() is set
1197812013
// Note that for SIMD32 kernels we always return UD with one half zeroed-out
1197912014
CVariable* EmitPass::GetHalfExecutionMask()
@@ -17178,6 +17213,7 @@ void EmitPass::emitVectorStore(StoreInst* inst, Value* offset, ConstantInt* immO
1717817213

1717917214
Value* Ptr = inst->getPointerOperand();
1718017215
PointerType* ptrType = cast<PointerType>(Ptr->getType());
17216+
BasicBlock* BB = inst->getParent();
1718117217

1718217218
ResourceDescriptor resource = GetResourceVariable(Ptr);
1718317219
CountStatelessIndirectAccess(Ptr, resource);
@@ -17199,9 +17235,12 @@ void EmitPass::emitVectorStore(StoreInst* inst, Value* offset, ConstantInt* immO
1719917235
eOffset = ReAlignUniformVariable(eOffset, EALIGN_GRF);
1720017236

1720117237
Value* storedVal = inst->getValueOperand();
17202-
CVariable* storedVar = GetSymbol(storedVal);
1720317238
uint32_t eltBytes, elts;
1720417239
Type* Ty = storedVal->getType();
17240+
17241+
CVariable* storedVar = tryReusingConstVectorStoreData(storedVal, BB, false);
17242+
if (!storedVar) storedVar = GetSymbol(storedVal);
17243+
1720517244
if (Ty->isStructTy())
1720617245
{
1720717246
eltBytes = 4;
@@ -17433,7 +17472,9 @@ void EmitPass::emitVectorStore(StoreInst* inst, Value* offset, ConstantInt* immO
1743317472
else
1743417473
{
1743517474
eOffset = BroadcastIfUniform(eOffset);
17436-
storedVar = BroadcastIfUniform(storedVar);
17475+
17476+
CVariable* broadcastedVar = tryReusingConstVectorStoreData(storedVal, BB, true);
17477+
storedVar = broadcastedVar ? broadcastedVar : BroadcastIfUniform(storedVar);
1743717478

1743817479
VectorMessage VecMessInfo(this);
1743917480
VecMessInfo.getInfo(Ty, align, useA32);
@@ -18184,15 +18225,16 @@ void EmitPass::emitLSCVectorStore_uniform(
1818418225
void EmitPass::emitLSCVectorStore(
1818518226
Value* Ptr,
1818618227
Value* varOffset, ConstantInt* immOffset,
18187-
Value* storedVal, LSC_CACHE_OPTS cacheOpts, alignment_t align, bool dontForceDmask)
18228+
Value* storedVal, BasicBlock* BB,
18229+
LSC_CACHE_OPTS cacheOpts, alignment_t align, bool dontForceDmask)
1818818230
{
1818918231
PointerType* ptrType = cast<PointerType>(Ptr->getType());
1819018232
Type* Ty = storedVal->getType();
1819118233
IGCLLVM::FixedVectorType* VTy = dyn_cast<IGCLLVM::FixedVectorType>(Ty);
1819218234
Type* eltTy = VTy ? VTy->getElementType() : Ty;
1819318235
uint32_t eltBytes = GetScalarTypeSizeInRegister(eltTy);
1819418236
uint32_t elts = VTy ? int_cast<uint32_t>(VTy->getNumElements()) : 1;
18195-
CVariable* storedVar = GetSymbol(storedVal);
18237+
1819618238
unsigned int width = numLanes(m_currShader->m_SIMDSize);
1819718239

1819818240
ResourceDescriptor resource = GetResourceVariable(Ptr);
@@ -18224,6 +18266,9 @@ void EmitPass::emitLSCVectorStore(
1822418266
// when true, one simd instance is generated only!
1822518267
bool isOCLUniform = isUniformStoreOCL(varOffset, storedVal);
1822618268

18269+
CVariable* storedVar = tryReusingConstVectorStoreData(storedVal, BB, false);
18270+
if (!storedVar) storedVar = GetSymbol(storedVal);
18271+
1822718272
// In case eOffset isn't GRF aligned, need to create a copy
1822818273
// For non-uniform variable, it should be already GRF-aligned.
1822918274
eOffset = ReAlignUniformVariable(eOffset, EALIGN_GRF);
@@ -18260,7 +18305,9 @@ void EmitPass::emitLSCVectorStore(
1826018305
VecMessInfo.getLSCInfo(Ty, align, m_currShader->GetContext(), useA32, false);
1826118306

1826218307
eOffset = BroadcastIfUniform(eOffset);
18263-
storedVar = BroadcastIfUniform(storedVar);
18308+
18309+
CVariable* broadcastedVar = tryReusingConstVectorStoreData(storedVal, BB, true);
18310+
storedVar = broadcastedVar ? broadcastedVar : BroadcastIfUniform(storedVar);
1826418311

1826518312
ResourceLoop(resource, [&](CVariable* flag) {
1826618313
for (uint32_t i = 0; i < VecMessInfo.numInsts; ++i)

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,8 @@ class EmitPass : public llvm::FunctionPass
433433
uint64_t align);
434434
void emitLSCVectorStore(llvm::Value *Ptr,
435435
llvm::Value *offset, llvm::ConstantInt *immOffset,
436-
llvm::Value *storedVal, LSC_CACHE_OPTS cacheOpts,
436+
llvm::Value *storedVal, llvm::BasicBlock* BB,
437+
LSC_CACHE_OPTS cacheOpts,
437438
alignment_t align, bool dontForceDMask);
438439
void emitGenISACopy(llvm::GenIntrinsicInst* GenCopyInst);
439440
void emitUniformVectorCopy(CVariable* Dst, CVariable* Src, uint32_t nElts,
@@ -833,6 +834,13 @@ class EmitPass : public llvm::FunctionPass
833834
bool m_canGenericPointToPrivate = false;
834835
bool m_canGenericPointToLocal = false;
835836

837+
typedef struct {
838+
CVariable* var;
839+
CVariable* broadcastedVar[2];
840+
llvm::BasicBlock* BB;
841+
} ConstVectorStoreData;
842+
llvm::DenseMap<llvm::Constant*, ConstVectorStoreData> m_constantVectorStores;
843+
836844
// Used to relocate phi-mov to different BB. phiMovToBB is the map from "fromBB"
837845
// to "toBB" (meaning to move phi-mov from "fromBB" to "toBB"). See MovPhiSources.
838846
llvm::DenseMap<llvm::BasicBlock*, llvm::BasicBlock*> phiMovToBB;
@@ -873,6 +881,11 @@ class EmitPass : public llvm::FunctionPass
873881
return Var;
874882
}
875883

884+
// If constant vector is stored and there is already var instance for it
885+
// try reusing it (if it was defined in the same basic block)
886+
// or create a new var instance and make it available for reusing in further stores
887+
CVariable* tryReusingConstVectorStoreData(llvm::Value* storedVal, llvm::BasicBlock* BB, bool isBroadcast);
888+
876889
// Emit code in slice starting from (reverse) iterator I. Return the
877890
// iterator to the next pattern to emit.
878891
SBasicBlock::reverse_iterator emitInSlice(SBasicBlock& block,

0 commit comments

Comments
 (0)