@@ -2096,107 +2096,81 @@ static Constant* GetConstantValue(Type* type, char* rawData)
2096
2096
return nullptr ;
2097
2097
}
2098
2098
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 )
2100
2100
{
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 () ))
2108
2108
{
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 ))
2124
2120
{
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);
2154
2127
}
2155
2128
}
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
2167
2130
{
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;
2173
2135
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 ;
2181
2138
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;
2184
2147
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)
2190
2161
{
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++)
2195
2165
{
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));
2199
2172
}
2173
+ return dyn_cast<Constant>(vectorValue);
2200
2174
}
2201
2175
}
2202
2176
return nullptr ;
@@ -2206,7 +2180,8 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
2206
2180
{
2207
2181
unsigned as = inst->getPointerAddressSpace ();
2208
2182
bool directBuf = false ;
2209
- unsigned bufId = 0 ;
2183
+ bool statelessBuf = false ;
2184
+ unsigned bufIdOrGRFOffset = 0 ;
2210
2185
unsigned int size_in_bytes = 0 ;
2211
2186
CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
2212
2187
ModuleMetaData* modMD = ctx->getModuleMetaData ();
@@ -2216,32 +2191,47 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
2216
2191
2217
2192
if (as == ADDRESS_SPACE_CONSTANT)
2218
2193
{
2219
- if (!GetStatelessBufferInfo (inst->getPointerOperand (), bufId , bufType, pointerSrc))
2194
+ if (!GetStatelessBufferInfo (inst->getPointerOperand (), bufIdOrGRFOffset , bufType, pointerSrc, directBuf ))
2220
2195
{
2221
2196
return nullptr ;
2222
2197
}
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
+ }
2224
2213
}
2225
2214
else
2226
2215
{
2227
- bufType = IGC::DecodeAS4GFXResource (as, directBuf, bufId );
2216
+ bufType = IGC::DecodeAS4GFXResource (as, directBuf, bufIdOrGRFOffset );
2228
2217
}
2229
2218
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) )
2232
2221
{
2233
2222
Value* ptrVal = inst->getPointerOperand ();
2234
2223
unsigned eltId = 0 ;
2235
2224
size_in_bytes = inst->getType ()->getPrimitiveSizeInBits () / 8 ;
2236
- if (!EvalConstantAddress (ptrVal, eltId, pointerSrc))
2225
+ if (!EvalConstantAddress (ptrVal, eltId, m_TD, pointerSrc))
2237
2226
{
2238
2227
return nullptr ;
2239
2228
}
2240
2229
2241
2230
if (size_in_bytes)
2242
2231
{
2243
2232
if (modMD->immConstant .data .size () &&
2244
- (bufId == modMD->pushInfo .inlineConstantBufferSlot ))
2233
+ ((statelessBuf && (bufIdOrGRFOffset == modMD->pushInfo .inlineConstantBufferGRFOffset ))||
2234
+ (directBuf && (bufIdOrGRFOffset == modMD->pushInfo .inlineConstantBufferSlot ))))
2245
2235
{
2246
2236
char * offset = &(modMD->immConstant .data [0 ]);
2247
2237
if (inst->getType ()->isVectorTy ())
@@ -2267,7 +2257,7 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
2267
2257
}
2268
2258
else if ((!IGC_IS_FLAG_ENABLED (DisableDynamicConstantFolding)) && (modMD->inlineDynConstants .size () > 0 ))
2269
2259
{
2270
- return ReplaceFromDynConstants (bufId , eltId, size_in_bytes, inst-> getType () );
2260
+ return ReplaceFromDynConstants (bufIdOrGRFOffset , eltId, size_in_bytes, inst);
2271
2261
}
2272
2262
}
2273
2263
}
0 commit comments