@@ -2096,107 +2096,81 @@ static Constant* GetConstantValue(Type* type, char* rawData)
20962096 return nullptr ;
20972097}
20982098
2099- bool IGCConstProp::EvalConstantAddress (Value* address , unsigned int & offset, Value* ptrSrc )
2099+ Constant* IGCConstProp::ReplaceFromDynConstants ( unsigned bufId , unsigned eltId, unsigned int size_in_bytes, LoadInst* inst )
21002100{
2101- if ((ptrSrc == nullptr && isa<ConstantPointerNull>(address)) ||
2102- (ptrSrc == address))
2103- {
2104- offset = 0 ;
2105- return true ;
2106- }
2107- else if (Instruction * ptrExpr = dyn_cast<Instruction>(address ))
2101+ Type* type = inst-> getType ();
2102+
2103+ CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>(). getCodeGenContext ();
2104+ ModuleMetaData* modMD = ctx-> getModuleMetaData () ;
2105+
2106+ // Handling for base types (Integer/FloatingPoint)
2107+ if (!(type-> isVectorTy () ))
21082108 {
2109- if (ptrExpr->getOpcode () == Instruction::BitCast ||
2110- ptrExpr->getOpcode () == Instruction::AddrSpaceCast)
2111- {
2112- return EvalConstantAddress (ptrExpr->getOperand (0 ), offset, ptrSrc);
2113- }
2114- if (ptrExpr->getOpcode () == Instruction::IntToPtr)
2115- {
2116- Value* eltIdxVal = ptrExpr->getOperand (0 );
2117- ConstantInt* eltIdx = dyn_cast<ConstantInt>(eltIdxVal);
2118- if (!eltIdx)
2119- return false ;
2120- offset = int_cast<unsigned >(eltIdx->getZExtValue ());
2121- return true ;
2122- }
2123- else if (ptrExpr->getOpcode () == Instruction::GetElementPtr)
2109+ ConstantAddress cl;
2110+ cl.bufId = bufId;
2111+ cl.eltId = eltId;
2112+ cl.size = size_in_bytes;
2113+
2114+ // Inline the constants for constant buffer accesses of size <= 32bit only.
2115+ if (size_in_bytes > 4 )
2116+ return nullptr ;
2117+
2118+ auto it = modMD->inlineDynConstants .find (cl);
2119+ if (it != modMD->inlineDynConstants .end () && (it->first .size == cl.size ))
21242120 {
2125- offset = 0 ;
2126- if (!EvalConstantAddress (ptrExpr->getOperand (0 ), offset, ptrSrc))
2127- {
2128- return false ;
2129- }
2130- Type* Ty = ptrExpr->getType ();
2131- gep_type_iterator GTI = gep_type_begin (ptrExpr);
2132- for (auto OI = ptrExpr->op_begin () + 1 , E = ptrExpr->op_end (); OI != E; ++OI, ++GTI) {
2133- Value* Idx = *OI;
2134- if (StructType * StTy = GTI.getStructTypeOrNull ()) {
2135- unsigned Field = int_cast<unsigned >(cast<ConstantInt>(Idx)->getZExtValue ());
2136- if (Field) {
2137- offset += int_cast<unsigned int >(m_TD->getStructLayout (StTy)->getElementOffset (Field));
2138- }
2139- Ty = StTy->getElementType (Field);
2140- }
2141- else {
2142- Ty = GTI.getIndexedType ();
2143- if (const ConstantInt * CI = dyn_cast<ConstantInt>(Idx)) {
2144- offset += int_cast<unsigned int >(
2145- m_TD->getTypeAllocSize (Ty) * CI->getSExtValue ());
2146- }
2147- else
2148- {
2149- return false ;
2150- }
2151- }
2152- }
2153- return true ;
2121+ // This constant is
2122+ // found in the Dynamic inline constants list, and
2123+ // sizes match (find only looking for bufId and eltId, so need to compare size field explicitly)
2124+ char * pConstVal;
2125+ pConstVal = (char *)(&(it->second ));
2126+ return GetConstantValue (type, pConstVal);
21542127 }
21552128 }
2156- return false ;
2157- }
2158-
2159- bool GetStatelessBufferInfo (Value* pointer, unsigned & bufferId,
2160- BufferType& bufferTy, Value*& bufferSrcPtr)
2161- {
2162- // If the buffer info is not encoded in the address space, we can still find it by
2163- // tracing the pointer to where it's created.
2164- Value* src = IGC::TracePointerSource (pointer);
2165- BufferAccessType accType;
2166- if (src && IGC::GetResourcePointerInfo (src, bufferId, bufferTy, accType))
2129+ else
21672130 {
2168- bufferSrcPtr = src;
2169- return true ;
2170- }
2171- return false ;
2172- }
2131+ Type * srcEltTy = type->getVectorElementType ();
2132+ uint32_t srcNElts = type->getVectorNumElements ();
2133+ uint32_t eltSize_in_bytes = srcEltTy->getPrimitiveSizeInBits () / 8 ;
2134+ std::vector<uint32_t > constValVec;
21732135
2174- Constant* IGCConstProp::ReplaceFromDynConstants (unsigned bufId, unsigned eltId, unsigned int size_in_bytes, Type* type)
2175- {
2176- ConstantAddress cl;
2177- char * pConstVal;
2178- cl.bufId = bufId;
2179- cl.eltId = eltId;
2180- cl.size = size_in_bytes;
2136+ if (eltSize_in_bytes > 4 )
2137+ return nullptr ;
21812138
2182- CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
2183- ModuleMetaData* modMD = ctx->getModuleMetaData ();
2139+ // First make sure all elements of vector are available in the dynamic inline constants
2140+ // If not, we cannot inline the vector
2141+ for (uint i = 0 ; i < srcNElts; i++)
2142+ {
2143+ ConstantAddress cl;
2144+ cl.bufId = bufId;
2145+ cl.eltId = eltId + (i * eltSize_in_bytes);
2146+ cl.size = eltSize_in_bytes;
21842147
2185- auto it = modMD->inlineDynConstants .find (cl);
2186- if ((it != modMD->inlineDynConstants .end ()) && (it->first .size == cl.size ))
2187- {
2188- // For constant buffer accesses of size <= 32bit.
2189- if (size_in_bytes <= 4 )
2148+ auto it = modMD->inlineDynConstants .find (cl);
2149+ if (it != modMD->inlineDynConstants .end () && (it->first .size == cl.size ))
2150+ {
2151+ constValVec.push_back (it->second );
2152+ }
2153+ else
2154+ {
2155+ // All elements of the vector has to be available for inlining,
2156+ // otherwise we cannot replace the load instruction, hence return nullptr
2157+ return nullptr ;
2158+ }
2159+ }
2160+ if (constValVec.size () == srcNElts)
21902161 {
2191- // This constant is
2192- // found in the Dynamic inline constants list, and
2193- // sizes match (find only looking for bufId and eltId, so need to look for size explicitly)
2194- if (!(type->isVectorTy ()))
2162+ IRBuilder<> builder (inst);
2163+ Value * vectorValue = UndefValue::get (inst->getType ());
2164+ for (uint i = 0 ; i < srcNElts; i++)
21952165 {
2196- // Handling for base types (Integer/FloatingPoint)
2197- pConstVal = (char *)(&(it->second ));
2198- return GetConstantValue (type, pConstVal);
2166+ char * pConstVal;
2167+ pConstVal = (char *)(&(constValVec[i]));
2168+ vectorValue = builder.CreateInsertElement (
2169+ vectorValue,
2170+ GetConstantValue (srcEltTy, pConstVal),
2171+ builder.getInt32 (i));
21992172 }
2173+ return dyn_cast<Constant>(vectorValue);
22002174 }
22012175 }
22022176 return nullptr ;
@@ -2206,7 +2180,8 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
22062180{
22072181 unsigned as = inst->getPointerAddressSpace ();
22082182 bool directBuf = false ;
2209- unsigned bufId = 0 ;
2183+ bool statelessBuf = false ;
2184+ unsigned bufIdOrGRFOffset = 0 ;
22102185 unsigned int size_in_bytes = 0 ;
22112186 CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
22122187 ModuleMetaData* modMD = ctx->getModuleMetaData ();
@@ -2216,32 +2191,47 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
22162191
22172192 if (as == ADDRESS_SPACE_CONSTANT)
22182193 {
2219- if (!GetStatelessBufferInfo (inst->getPointerOperand (), bufId , bufType, pointerSrc))
2194+ if (!GetStatelessBufferInfo (inst->getPointerOperand (), bufIdOrGRFOffset , bufType, pointerSrc, directBuf ))
22202195 {
22212196 return nullptr ;
22222197 }
2223- directBuf = true ;
2198+ if (!directBuf)
2199+ {
2200+ // Make sure constant folding is safe by looking up in pushableAddresses
2201+ CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
2202+ PushInfo& pushInfo = ctx->getModuleMetaData ()->pushInfo ;
2203+
2204+ for (auto it : pushInfo.pushableAddresses )
2205+ {
2206+ if (bufIdOrGRFOffset * 4 == it.addressOffset && it.isStatic )
2207+ {
2208+ statelessBuf = true ;
2209+ break ;
2210+ }
2211+ }
2212+ }
22242213 }
22252214 else
22262215 {
2227- bufType = IGC::DecodeAS4GFXResource (as, directBuf, bufId );
2216+ bufType = IGC::DecodeAS4GFXResource (as, directBuf, bufIdOrGRFOffset );
22282217 }
22292218
2230- if (bufType == CONSTANT_BUFFER &&
2231- directBuf && modMD )
2219+ // If it is statelessBuf, we made sure it is a constant buffer by finding it in pushableAddresses
2220+ if (modMD && (( directBuf && (bufType == CONSTANT_BUFFER)) || statelessBuf) )
22322221 {
22332222 Value* ptrVal = inst->getPointerOperand ();
22342223 unsigned eltId = 0 ;
22352224 size_in_bytes = inst->getType ()->getPrimitiveSizeInBits () / 8 ;
2236- if (!EvalConstantAddress (ptrVal, eltId, pointerSrc))
2225+ if (!EvalConstantAddress (ptrVal, eltId, m_TD, pointerSrc))
22372226 {
22382227 return nullptr ;
22392228 }
22402229
22412230 if (size_in_bytes)
22422231 {
22432232 if (modMD->immConstant .data .size () &&
2244- (bufId == modMD->pushInfo .inlineConstantBufferSlot ))
2233+ ((statelessBuf && (bufIdOrGRFOffset == modMD->pushInfo .inlineConstantBufferGRFOffset ))||
2234+ (directBuf && (bufIdOrGRFOffset == modMD->pushInfo .inlineConstantBufferSlot ))))
22452235 {
22462236 char * offset = &(modMD->immConstant .data [0 ]);
22472237 if (inst->getType ()->isVectorTy ())
@@ -2267,7 +2257,7 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
22672257 }
22682258 else if ((!IGC_IS_FLAG_ENABLED (DisableDynamicConstantFolding)) && (modMD->inlineDynConstants .size () > 0 ))
22692259 {
2270- return ReplaceFromDynConstants (bufId , eltId, size_in_bytes, inst-> getType () );
2260+ return ReplaceFromDynConstants (bufIdOrGRFOffset , eltId, size_in_bytes, inst);
22712261 }
22722262 }
22732263 }
0 commit comments