@@ -12056,13 +12056,53 @@ CVariable* EmitPass::BroadcastIfUniform(CVariable* pVar, bool nomask)
12056
12056
return pVar;
12057
12057
}
12058
12058
12059
+ CVariable* EmitPass::tryReusingXYZWPayload(Value* storedVal, BasicBlock* BB,
12060
+ unsigned numElems, VISA_Type type, CVariable* pSrc_X, CVariable* pSrc_Y,
12061
+ CVariable* pSrc_Z, CVariable* pSrc_W, const unsigned int numEltGRF)
12062
+ {
12063
+ Constant* constantStoredVal = dyn_cast<Constant>(storedVal);
12064
+ if (!constantStoredVal ||
12065
+ !(constantStoredVal->getType()->isFPOrFPVectorTy() ||
12066
+ constantStoredVal->getType()->isIntOrIntVectorTy()))
12067
+ {
12068
+ return nullptr;
12069
+ }
12070
+
12071
+ ConstVectorStoreData& storeData = m_constantVectorStores[constantStoredVal];
12072
+ if (storeData.BB != BB)
12073
+ {
12074
+ // Make an entry of this store data with BB in the constant vector stores
12075
+ storeData = {
12076
+ m_currShader->GetNewVariable(
12077
+ numElems,
12078
+ type,
12079
+ EALIGN_GRF,
12080
+ CName::NONE), {nullptr, nullptr}, BB};
12081
+
12082
+ m_currShader->CopyVariable(storeData.var, pSrc_X, 0);
12083
+ m_currShader->CopyVariable(storeData.var, pSrc_Y, numEltGRF);
12084
+ m_currShader->CopyVariable(storeData.var, pSrc_Z, 2 * numEltGRF);
12085
+ m_currShader->CopyVariable(storeData.var, pSrc_W, 3 * numEltGRF);
12086
+ }
12087
+
12088
+ CVariable* broadcastedVar = storeData.broadcastedVar[m_encoder->IsSecondHalf()];
12089
+ if (!broadcastedVar)
12090
+ {
12091
+ broadcastedVar = BroadcastIfUniform(storeData.var);
12092
+ storeData.broadcastedVar[m_encoder->IsSecondHalf()] = broadcastedVar;
12093
+ }
12094
+ return broadcastedVar;
12095
+ }
12096
+
12059
12097
// If constant vector is stored and there is already var instance for it
12060
12098
// try reusing it (if it was defined in the same basic block)
12061
12099
// or create a new var instance and make it available for reusing in further stores
12062
12100
CVariable* EmitPass::tryReusingConstVectorStoreData(Value* storedVal, BasicBlock* BB, bool isBroadcast)
12063
12101
{
12064
12102
Constant* constantStoredVal = dyn_cast<Constant>(storedVal);
12065
- if (!constantStoredVal || !constantStoredVal->getType()->isVectorTy())
12103
+ if (!constantStoredVal ||
12104
+ !(constantStoredVal->getType()->isFPOrFPVectorTy() ||
12105
+ constantStoredVal->getType()->isIntOrIntVectorTy()))
12066
12106
{
12067
12107
return nullptr;
12068
12108
}
@@ -12072,7 +12112,6 @@ CVariable* EmitPass::tryReusingConstVectorStoreData(Value* storedVal, BasicBlock
12072
12112
{
12073
12113
// the variable is not yet created or has different BB, create the new instance
12074
12114
storeData = {GetSymbol(constantStoredVal), {nullptr, nullptr}, BB};
12075
- IGC_ASSERT(!isBroadcast); // if we need broadcast we must have already created it for this store
12076
12115
}
12077
12116
12078
12117
if (!isBroadcast)
@@ -14880,16 +14919,33 @@ void EmitPass::emitTypedWrite(llvm::Instruction* pInsn)
14880
14919
14881
14920
if (!needsSplit)
14882
14921
{
14883
- CVariable* pPayload = m_currShader->GetNewVariable(
14884
- parameterLength * numLanes(m_currShader->m_SIMDSize),
14885
- ISA_TYPE_F,
14886
- EALIGN_GRF,
14887
- CName::NONE);
14888
- // pSrcX, Y, Z & W are broadcast to uniform by this function itself.
14889
- m_currShader->CopyVariable(pPayload, pSrc_X, 0);
14890
- m_currShader->CopyVariable(pPayload, pSrc_Y, 1);
14891
- m_currShader->CopyVariable(pPayload, pSrc_Z, 2);
14892
- m_currShader->CopyVariable(pPayload, pSrc_W, 3);
14922
+ Constant* p_X = dyn_cast<Constant>(pllSrc_X);
14923
+ Constant* p_Y = dyn_cast<Constant>(pllSrc_Y);
14924
+ Constant* p_Z = dyn_cast<Constant>(pllSrc_Z);
14925
+ Constant* p_W = dyn_cast<Constant>(pllSrc_W);
14926
+
14927
+ CVariable* pPayload = nullptr;
14928
+ if (p_X && p_Y && p_Z && p_W) {
14929
+ // if x, y, z, w are constants, find opportunities to reuse
14930
+ std::vector<Constant*> xyzwPayload{ p_X, p_Y, p_Z, p_W };
14931
+ llvm::Constant* payloadConstant = llvm::ConstantVector::get(xyzwPayload);
14932
+ pPayload = tryReusingXYZWPayload(payloadConstant, pInsn->getParent(),
14933
+ parameterLength * numLanes(m_currShader->m_SIMDSize), ISA_TYPE_F,
14934
+ pSrc_X, pSrc_Y, pSrc_Z, pSrc_W, 1);
14935
+ }
14936
+
14937
+ if (!pPayload) {
14938
+ pPayload = m_currShader->GetNewVariable(
14939
+ parameterLength * numLanes(m_currShader->m_SIMDSize),
14940
+ ISA_TYPE_F,
14941
+ EALIGN_GRF,
14942
+ CName::NONE);
14943
+ // pSrcX, Y, Z & W are broadcast to uniform by this function itself.
14944
+ m_currShader->CopyVariable(pPayload, pSrc_X, 0);
14945
+ m_currShader->CopyVariable(pPayload, pSrc_Y, 1);
14946
+ m_currShader->CopyVariable(pPayload, pSrc_Z, 2);
14947
+ m_currShader->CopyVariable(pPayload, pSrc_W, 3);
14948
+ }
14893
14949
m_encoder->SetPredicate(flag);
14894
14950
m_encoder->TypedWrite4(resource, pU, pV, pR, pLOD, pPayload, writeMask);
14895
14951
@@ -22321,4 +22377,5 @@ void EmitPass::emitStackOverflowDetectionCall(Function* ParentFunction) {
22321
22377
22322
22378
m_encoder->SubroutineCall(nullptr, StackOverflowDetectionFunction);
22323
22379
m_encoder->Push();
22324
- }
22380
+ }
22381
+
0 commit comments