@@ -195,6 +195,40 @@ static void replaceLoad(LoadInst *LI, CBufferResource &CBR,
195
195
DeadInsts.push_back (LI);
196
196
}
197
197
198
+ // / This function recursively copies N array elements from the cbuffer resource
199
+ // / CBR to the MemCpy Destination. Recursion is used to unravel multidimensional
200
+ // / arrays into a sequence of scalar/vector extracts and stores.
201
+ static void copyArrayElemsForMemCpy (IRBuilder<> &Builder, MemCpyInst *MCI,
202
+ CBufferResource &CBR, ArrayType *ArrTy,
203
+ size_t ArrOffset, size_t N,
204
+ const Twine &Name = " " ) {
205
+ const DataLayout &DL = MCI->getDataLayout ();
206
+ Type *ElemTy = ArrTy->getElementType ();
207
+ size_t ElemTySize = DL.getTypeAllocSize (ElemTy);
208
+ for (unsigned I = 0 ; I < N; ++I) {
209
+ size_t Offset = ArrOffset + I * ElemTySize;
210
+
211
+ // Recursively copy nested arrays
212
+ if (ArrayType *ElemArrTy = dyn_cast<ArrayType>(ElemTy)) {
213
+ copyArrayElemsForMemCpy (Builder, MCI, CBR, ElemArrTy, Offset,
214
+ ElemArrTy->getNumElements (), Name);
215
+ continue ;
216
+ }
217
+
218
+ // Load CBuffer value and store it in Dest
219
+ APInt CBufArrayOffset (
220
+ DL.getIndexTypeSizeInBits (MCI->getSource ()->getType ()), Offset);
221
+ CBufArrayOffset =
222
+ hlsl::translateCBufArrayOffset (DL, CBufArrayOffset, ArrTy);
223
+ Value *CBufferVal =
224
+ CBR.loadValue (Builder, ElemTy, CBufArrayOffset.getZExtValue (), Name);
225
+ Value *GEP =
226
+ Builder.CreateInBoundsGEP (Builder.getInt8Ty (), MCI->getDest (),
227
+ {Builder.getInt32 (Offset)}, Name + " .dest" );
228
+ Builder.CreateStore (CBufferVal, GEP, MCI->isVolatile ());
229
+ }
230
+ }
231
+
198
232
// / Replace memcpy from a cbuffer global with a memcpy from the cbuffer handle
199
233
// / itself. Assumes the cbuffer global is an array, and the length of bytes to
200
234
// / copy is divisible by array element allocation size.
@@ -209,10 +243,6 @@ static void replaceMemCpy(MemCpyInst *MCI, CBufferResource &CBR) {
209
243
reportFatalUsageError (
210
244
" Expected MemCpy source to be a cbuffer global variable" );
211
245
212
- const std::string Name = (" memcpy." + MCI->getDest ()->getName () + " ." +
213
- MCI->getSource ()->getName ())
214
- .str ();
215
-
216
246
ConstantInt *Length = dyn_cast<ConstantInt>(MCI->getLength ());
217
247
uint64_t ByteLength = Length->getZExtValue ();
218
248
@@ -234,41 +264,9 @@ static void replaceMemCpy(MemCpyInst *MCI, CBufferResource &CBR) {
234
264
IRBuilder<> Builder (MCI);
235
265
CBR.createAndSetCurrentHandle (Builder);
236
266
237
- // This function recursively copies N array elements from the CBuffer Resource
238
- // to the MemCpy Destination. Recursion is used to unravel multidimensional
239
- // arrays into a sequence of scalar/vector extracts and stores.
240
- auto CopyElemsImpl = [&Builder, &MCI, &Name, &CBR,
241
- &DL](const auto &Self, ArrayType *ArrTy,
242
- size_t ArrOffset, size_t N) -> void {
243
- Type *ElemTy = ArrTy->getElementType ();
244
- size_t ElemTySize = DL.getTypeAllocSize (ElemTy);
245
- for (unsigned I = 0 ; I < N; ++I) {
246
- size_t Offset = ArrOffset + I * ElemTySize;
247
-
248
- // Recursively copy nested arrays
249
- if (ArrayType *ElemArrTy = dyn_cast<ArrayType>(ElemTy)) {
250
- Self (Self, ElemArrTy, Offset, ElemArrTy->getNumElements ());
251
- continue ;
252
- }
253
-
254
- // Load CBuffer value and store it in Dest
255
- APInt CBufArrayOffset (
256
- DL.getIndexTypeSizeInBits (MCI->getSource ()->getType ()), Offset);
257
- CBufArrayOffset =
258
- hlsl::translateCBufArrayOffset (DL, CBufArrayOffset, ArrTy);
259
- Value *CBufferVal =
260
- CBR.loadValue (Builder, ElemTy, CBufArrayOffset.getZExtValue (), Name);
261
- Value *GEP =
262
- Builder.CreateInBoundsGEP (Builder.getInt8Ty (), MCI->getDest (),
263
- {Builder.getInt32 (Offset)}, Name + " .dest" );
264
- Builder.CreateStore (CBufferVal, GEP, MCI->isVolatile ());
265
- }
266
- };
267
- auto CopyElems = [&CopyElemsImpl](ArrayType *ArrTy, size_t N) -> void {
268
- CopyElemsImpl (CopyElemsImpl, ArrTy, 0 , N);
269
- };
270
-
271
- CopyElems (ArrTy, ElemsToCpy);
267
+ copyArrayElemsForMemCpy (Builder, MCI, CBR, ArrTy, 0 , ElemsToCpy,
268
+ " memcpy." + MCI->getDest ()->getName () + " ." +
269
+ MCI->getSource ()->getName ());
272
270
273
271
MCI->eraseFromParent ();
274
272
}
0 commit comments