Skip to content

Commit 7a3dbe2

Browse files
committed
Move recursive lambda to a module-level function
1 parent 14ce485 commit 7a3dbe2

File tree

1 file changed

+37
-39
lines changed

1 file changed

+37
-39
lines changed

llvm/lib/Target/DirectX/DXILCBufferAccess.cpp

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,40 @@ static void replaceLoad(LoadInst *LI, CBufferResource &CBR,
195195
DeadInsts.push_back(LI);
196196
}
197197

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+
198232
/// Replace memcpy from a cbuffer global with a memcpy from the cbuffer handle
199233
/// itself. Assumes the cbuffer global is an array, and the length of bytes to
200234
/// copy is divisible by array element allocation size.
@@ -209,10 +243,6 @@ static void replaceMemCpy(MemCpyInst *MCI, CBufferResource &CBR) {
209243
reportFatalUsageError(
210244
"Expected MemCpy source to be a cbuffer global variable");
211245

212-
const std::string Name = ("memcpy." + MCI->getDest()->getName() + "." +
213-
MCI->getSource()->getName())
214-
.str();
215-
216246
ConstantInt *Length = dyn_cast<ConstantInt>(MCI->getLength());
217247
uint64_t ByteLength = Length->getZExtValue();
218248

@@ -234,41 +264,9 @@ static void replaceMemCpy(MemCpyInst *MCI, CBufferResource &CBR) {
234264
IRBuilder<> Builder(MCI);
235265
CBR.createAndSetCurrentHandle(Builder);
236266

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());
272270

273271
MCI->eraseFromParent();
274272
}

0 commit comments

Comments
 (0)