@@ -11271,6 +11271,7 @@ void EmitPass::emitStoreRawIndexed(
11271
11271
varOffset,
11272
11272
immOffset,
11273
11273
pValToStore,
11274
+ inst->getParent(),
11274
11275
cacheOpts,
11275
11276
inst->getAlignment(),
11276
11277
false);
@@ -11455,6 +11456,7 @@ void EmitPass::emitStore(
11455
11456
varOffset,
11456
11457
immOffset,
11457
11458
inst->getValueOperand(),
11459
+ inst->getParent(),
11458
11460
cacheOpts,
11459
11461
IGCLLVM::getAlignmentValue(inst),
11460
11462
inst->getMetadata("enable.vmask"));
@@ -11974,6 +11976,39 @@ CVariable* EmitPass::BroadcastIfUniform(CVariable* pVar, bool nomask)
11974
11976
return pVar;
11975
11977
}
11976
11978
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
+
11977
12012
// Get either the 1st/2nd of the execution mask based on whether IsSecondHalf() is set
11978
12013
// Note that for SIMD32 kernels we always return UD with one half zeroed-out
11979
12014
CVariable* EmitPass::GetHalfExecutionMask()
@@ -17178,6 +17213,7 @@ void EmitPass::emitVectorStore(StoreInst* inst, Value* offset, ConstantInt* immO
17178
17213
17179
17214
Value* Ptr = inst->getPointerOperand();
17180
17215
PointerType* ptrType = cast<PointerType>(Ptr->getType());
17216
+ BasicBlock* BB = inst->getParent();
17181
17217
17182
17218
ResourceDescriptor resource = GetResourceVariable(Ptr);
17183
17219
CountStatelessIndirectAccess(Ptr, resource);
@@ -17199,9 +17235,12 @@ void EmitPass::emitVectorStore(StoreInst* inst, Value* offset, ConstantInt* immO
17199
17235
eOffset = ReAlignUniformVariable(eOffset, EALIGN_GRF);
17200
17236
17201
17237
Value* storedVal = inst->getValueOperand();
17202
- CVariable* storedVar = GetSymbol(storedVal);
17203
17238
uint32_t eltBytes, elts;
17204
17239
Type* Ty = storedVal->getType();
17240
+
17241
+ CVariable* storedVar = tryReusingConstVectorStoreData(storedVal, BB, false);
17242
+ if (!storedVar) storedVar = GetSymbol(storedVal);
17243
+
17205
17244
if (Ty->isStructTy())
17206
17245
{
17207
17246
eltBytes = 4;
@@ -17433,7 +17472,9 @@ void EmitPass::emitVectorStore(StoreInst* inst, Value* offset, ConstantInt* immO
17433
17472
else
17434
17473
{
17435
17474
eOffset = BroadcastIfUniform(eOffset);
17436
- storedVar = BroadcastIfUniform(storedVar);
17475
+
17476
+ CVariable* broadcastedVar = tryReusingConstVectorStoreData(storedVal, BB, true);
17477
+ storedVar = broadcastedVar ? broadcastedVar : BroadcastIfUniform(storedVar);
17437
17478
17438
17479
VectorMessage VecMessInfo(this);
17439
17480
VecMessInfo.getInfo(Ty, align, useA32);
@@ -18184,15 +18225,16 @@ void EmitPass::emitLSCVectorStore_uniform(
18184
18225
void EmitPass::emitLSCVectorStore(
18185
18226
Value* Ptr,
18186
18227
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)
18188
18230
{
18189
18231
PointerType* ptrType = cast<PointerType>(Ptr->getType());
18190
18232
Type* Ty = storedVal->getType();
18191
18233
IGCLLVM::FixedVectorType* VTy = dyn_cast<IGCLLVM::FixedVectorType>(Ty);
18192
18234
Type* eltTy = VTy ? VTy->getElementType() : Ty;
18193
18235
uint32_t eltBytes = GetScalarTypeSizeInRegister(eltTy);
18194
18236
uint32_t elts = VTy ? int_cast<uint32_t>(VTy->getNumElements()) : 1;
18195
- CVariable* storedVar = GetSymbol(storedVal);
18237
+
18196
18238
unsigned int width = numLanes(m_currShader->m_SIMDSize);
18197
18239
18198
18240
ResourceDescriptor resource = GetResourceVariable(Ptr);
@@ -18224,6 +18266,9 @@ void EmitPass::emitLSCVectorStore(
18224
18266
// when true, one simd instance is generated only!
18225
18267
bool isOCLUniform = isUniformStoreOCL(varOffset, storedVal);
18226
18268
18269
+ CVariable* storedVar = tryReusingConstVectorStoreData(storedVal, BB, false);
18270
+ if (!storedVar) storedVar = GetSymbol(storedVal);
18271
+
18227
18272
// In case eOffset isn't GRF aligned, need to create a copy
18228
18273
// For non-uniform variable, it should be already GRF-aligned.
18229
18274
eOffset = ReAlignUniformVariable(eOffset, EALIGN_GRF);
@@ -18260,7 +18305,9 @@ void EmitPass::emitLSCVectorStore(
18260
18305
VecMessInfo.getLSCInfo(Ty, align, m_currShader->GetContext(), useA32, false);
18261
18306
18262
18307
eOffset = BroadcastIfUniform(eOffset);
18263
- storedVar = BroadcastIfUniform(storedVar);
18308
+
18309
+ CVariable* broadcastedVar = tryReusingConstVectorStoreData(storedVal, BB, true);
18310
+ storedVar = broadcastedVar ? broadcastedVar : BroadcastIfUniform(storedVar);
18264
18311
18265
18312
ResourceLoop(resource, [&](CVariable* flag) {
18266
18313
for (uint32_t i = 0; i < VecMessInfo.numInsts; ++i)
0 commit comments