@@ -36,6 +36,77 @@ mlir::Block *OpenACCRecipeBuilderBase::createRecipeBlock(mlir::Region ®ion,
3636 llvm::SmallVector<mlir::Location> locs{types.size (), loc};
3737 return builder.createBlock (®ion, region.end (), types, locs);
3838}
39+ void OpenACCRecipeBuilderBase::makeAllocaCopy (mlir::Location loc,
40+ mlir::Type copyType,
41+ mlir::Value numEltsToCopy,
42+ mlir::Value offsetPerSubarray,
43+ mlir::Value destAlloca,
44+ mlir::Value srcAlloca) {
45+ mlir::OpBuilder::InsertionGuard guardCase (builder);
46+
47+ mlir::Type itrTy = cgf.cgm .convertType (cgf.getContext ().UnsignedLongLongTy );
48+ auto itrPtrTy = cir::PointerType::get (itrTy);
49+ mlir::IntegerAttr itrAlign =
50+ cgf.cgm .getSize (cgf.getContext ().getTypeAlignInChars (
51+ cgf.getContext ().UnsignedLongLongTy ));
52+
53+ auto loopBuilder = [&]() {
54+ auto itr =
55+ cir::AllocaOp::create (builder, loc, itrPtrTy, itrTy, " itr" , itrAlign);
56+ cir::ConstantOp constZero = builder.getConstInt (loc, itrTy, 0 );
57+ builder.CIRBaseBuilderTy ::createStore (loc, constZero.getResult (), itr);
58+ builder.createFor (
59+ loc,
60+ /* condBuilder=*/
61+ [&](mlir::OpBuilder &b, mlir::Location loc) {
62+ // itr < numEltsToCopy
63+ // Enforce a trip count of 1 if there wasn't any element count, this
64+ // way we can just use this loop with a constant bounds instead of a
65+ // separate code path.
66+ if (!numEltsToCopy)
67+ numEltsToCopy = builder.getConstInt (loc, itrTy, 1 ).getResult ();
68+
69+ auto loadCur = cir::LoadOp::create (builder, loc, {itr});
70+ auto cmp = builder.createCompare (loc, cir::CmpOpKind::lt,
71+ loadCur.getResult (), numEltsToCopy);
72+ builder.createCondition (cmp);
73+ },
74+ /* bodyBuilder=*/
75+ [&](mlir::OpBuilder &b, mlir::Location loc) {
76+ // destAlloca[itr] = srcAlloca[offsetPerSubArray * itr];
77+ auto loadCur = cir::LoadOp::create (builder, loc, {itr});
78+ auto srcOffset =
79+ builder.createMul (loc, offsetPerSubarray, loadCur.getResult ());
80+
81+ auto ptrToOffsetIntoSrc = cir::PtrStrideOp::create (
82+ builder, loc, copyType, srcAlloca, srcOffset);
83+
84+ auto offsetIntoDecayDest = cir::PtrStrideOp::create (
85+ builder, loc, builder.getPointerTo (copyType), destAlloca,
86+ loadCur.getResult ());
87+
88+ builder.CIRBaseBuilderTy ::createStore (loc, ptrToOffsetIntoSrc,
89+ offsetIntoDecayDest);
90+ builder.createYield (loc);
91+ },
92+ /* stepBuilder=*/
93+ [&](mlir::OpBuilder &b, mlir::Location loc) {
94+ // Simple increment of the iterator.
95+ auto load = cir::LoadOp::create (builder, loc, {itr});
96+ auto inc =
97+ cir::UnaryOp::create (builder, loc, load.getType (),
98+ cir::UnaryOpKind::Inc, load.getResult ());
99+ builder.CIRBaseBuilderTy ::createStore (loc, inc.getResult (), itr);
100+ builder.createYield (loc);
101+ });
102+ };
103+
104+ cir::ScopeOp::create (builder, loc,
105+ [&](mlir::OpBuilder &b, mlir::Location loc) {
106+ loopBuilder ();
107+ builder.createYield (loc);
108+ });
109+ }
39110
40111mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca (
41112 mlir::Block *block, SourceRange exprRange, mlir::Location loc,
@@ -78,6 +149,10 @@ mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
78149
79150 bool lastBoundWasArray = isArrayTy (boundTypes.back ());
80151
152+ // Make sure we track a moving version of this so we can get our
153+ // 'copying' back to correct.
154+ mlir::Value lastAlloca = initialAlloca;
155+
81156 // Since we're iterating the types in reverse, this sets up for each index
82157 // corresponding to the boundsRange to be the 'after application of the
83158 // bounds.
@@ -125,14 +200,21 @@ mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
125200
126201 mlir::Type eltTy = cgf.convertType (resultType);
127202 cir::PointerType ptrTy = builder.getPointerTo (eltTy);
128- builder.createAlloca (loc, ptrTy, eltTy, " openacc.init.bounds" ,
129- cgf.getContext ().getTypeAlignInChars (resultType),
130- curSize);
131-
132- // TODO: OpenACC : At this point we should be copying the addresses of
133- // each element of this to the last allocation. At the moment, that is
134- // not yet implemented.
135- cgf.cgm .errorNYI (exprRange, " OpenACC recipe alloca copying" );
203+ mlir::Value curAlloca = builder.createAlloca (
204+ loc, ptrTy, eltTy, " openacc.init.bounds" ,
205+ cgf.getContext ().getTypeAlignInChars (resultType), curSize);
206+
207+ makeAllocaCopy (loc, ptrTy, cumulativeElts, eltsPerSubArray, lastAlloca,
208+ curAlloca);
209+ lastAlloca = curAlloca;
210+ } else {
211+ // In the case of an array, we just need to decay the pointer, so just do
212+ // a zero-offset stride on the last alloca to decay it down an array
213+ // level.
214+ cir::ConstantOp constZero = builder.getConstInt (loc, itrTy, 0 );
215+ lastAlloca = builder.getArrayElement (
216+ loc, loc, lastAlloca, cgf.convertType (resultType),
217+ constZero.getResult (), /* shouldDecay=*/ true );
136218 }
137219
138220 cumulativeElts = eltsToAlloca;
0 commit comments