@@ -49,14 +49,16 @@ class OpenACCRecipeBuilderBase {
4949 // Creates a loop through an 'acc.bounds', leaving the 'insertion' point to be
5050 // the inside of the loop body. Traverses LB->UB UNLESS `inverse` is set.
5151 // Returns the 'subscriptedValue' changed with the new bounds subscript.
52+ std::pair<mlir::Value, mlir::Value>
53+ createBoundsLoop (mlir::Value subscriptedValue, mlir::Value subscriptedValue2,
54+ mlir::Value bound, mlir::Location loc, bool inverse);
55+
5256 mlir::Value createBoundsLoop (mlir::Value subscriptedValue, mlir::Value bound,
53- mlir::Location loc, bool inverse);
57+ mlir::Location loc, bool inverse) {
58+ return createBoundsLoop (subscriptedValue, {}, bound, loc, inverse).first ;
59+ }
60+
5461 mlir::acc::ReductionOperator convertReductionOp (OpenACCReductionOperator op);
55- void createFirstprivateRecipeCopy (
56- mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
57- CIRGenFunction::AutoVarEmission tempDeclEmission,
58- mlir::acc::FirstprivateRecipeOp recipe, const VarDecl *varRecipe,
59- const VarDecl *temporary);
6062
6163 // This function generates the 'combiner' section for a reduction recipe. Note
6264 // that this function is not 'insertion point' clean, in that it alters the
@@ -66,11 +68,19 @@ class OpenACCRecipeBuilderBase {
6668 mlir::Value mainOp,
6769 mlir::acc::ReductionRecipeOp recipe,
6870 size_t numBounds);
71+
6972 void createInitRecipe (mlir::Location loc, mlir::Location locEnd,
7073 SourceRange exprRange, mlir::Value mainOp,
7174 mlir::Region &recipeInitRegion, size_t numBounds,
7275 llvm::ArrayRef<QualType> boundTypes,
73- const VarDecl *allocaDecl, QualType origType);
76+ const VarDecl *allocaDecl, QualType origType,
77+ bool emitInitExpr);
78+
79+ void createFirstprivateRecipeCopy (mlir::Location loc, mlir::Location locEnd,
80+ mlir::Value mainOp,
81+ const VarDecl *allocaDecl,
82+ const VarDecl *temporary,
83+ mlir::Region ©Region, size_t numBounds);
7484
7585 void createRecipeDestroySection (mlir::Location loc, mlir::Location locEnd,
7686 mlir::Value mainOp, CharUnits alignment,
@@ -150,63 +160,6 @@ class OpenACCRecipeBuilder : OpenACCRecipeBuilderBase {
150160 return recipeName;
151161 }
152162
153- // Create the 'init' section of the recipe, including the 'copy' section for
154- // 'firstprivate'. Note that this function is not 'insertion point' clean, in
155- // that it alters the insertion point to be inside of the 'destroy' section of
156- // the recipe, but doesn't restore it aftewards.
157- void createRecipeInitCopy (mlir::Location loc, mlir::Location locEnd,
158- SourceRange exprRange, mlir::Value mainOp,
159- RecipeTy recipe, const VarDecl *varRecipe,
160- const VarDecl *temporary) {
161- // TODO: OpenACC: when we get the 'pointer' variants for
162- // firstprivate/reduction, this probably should be removed/split into
163- // functions for the BuilderBase.
164- assert (varRecipe && " Required recipe variable not set?" );
165-
166- CIRGenFunction::AutoVarEmission tempDeclEmission{
167- CIRGenFunction::AutoVarEmission::invalid ()};
168- CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, varRecipe};
169-
170- // Do the 'init' section of the recipe IR, which does an alloca, then the
171- // initialization (except for firstprivate).
172- mlir::Block *block =
173- createRecipeBlock (recipe.getInitRegion (), mainOp.getType (), loc,
174- /* numBounds=*/ 0 , /* isInit=*/ true );
175- builder.setInsertionPointToEnd (&recipe.getInitRegion ().back ());
176- CIRGenFunction::LexicalScope ls (cgf, loc, block);
177-
178- tempDeclEmission =
179- cgf.emitAutoVarAlloca (*varRecipe, builder.saveInsertionPoint ());
180-
181- // 'firstprivate' doesn't do its initialization in the 'init' section,
182- // instead it does it in the 'copy' section. SO, only do 'init' here for
183- // reduction.
184- if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
185- // Unlike Private, the recipe here is always required as it has to do
186- // init, not just 'default' init.
187- if (!varRecipe->getInit ())
188- cgf.cgm .errorNYI (exprRange, " reduction init recipe" );
189- cgf.emitAutoVarInit (tempDeclEmission);
190- }
191-
192- mlir::acc::YieldOp::create (builder, locEnd);
193-
194- if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
195- if (!varRecipe->getInit ()) {
196- // If we don't have any initialization recipe, we failed during Sema to
197- // initialize this correctly. If we disable the
198- // Sema::TentativeAnalysisScopes in SemaOpenACC::CreateInitRecipe, it'll
199- // emit an error to tell us. However, emitting those errors during
200- // production is a violation of the standard, so we cannot do them.
201- cgf.cgm .errorNYI (
202- exprRange, " firstprivate copy-init recipe not properly generated" );
203- }
204-
205- createFirstprivateRecipeCopy (loc, locEnd, mainOp, tempDeclEmission,
206- recipe, varRecipe, temporary);
207- }
208- }
209-
210163public:
211164 OpenACCRecipeBuilder (CIRGen::CIRGenFunction &cgf,
212165 CIRGen::CIRGenBuilderTy &builder)
@@ -221,19 +174,6 @@ class OpenACCRecipeBuilder : OpenACCRecipeBuilderBase {
221174 BuiltinType::ArraySection) &&
222175 " array section shouldn't make it to recipe creation" );
223176
224- // TODO: OpenACC: This is a bit of a hackery to get this to not change for
225- // the non-private recipes. This will be removed soon, when we get this
226- // 'right' for firstprivate and reduction.
227- if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
228- if (numBounds) {
229- cgf.cgm .errorNYI (varRef->getSourceRange (),
230- " firstprivate-init with bounds" );
231- }
232- boundTypes = {};
233- numBounds = 0 ;
234- origType = baseType;
235- }
236-
237177 mlir::ModuleOp mod = builder.getBlock ()
238178 ->getParent ()
239179 ->template getParentOfType <mlir::ModuleOp>();
@@ -262,21 +202,20 @@ class OpenACCRecipeBuilder : OpenACCRecipeBuilderBase {
262202 if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
263203 createInitRecipe (loc, locEnd, varRef->getSourceRange (), mainOp,
264204 recipe.getInitRegion (), numBounds, boundTypes, varRecipe,
265- origType);
205+ origType, /* emitInitExpr= */ true );
266206 } else if constexpr (std::is_same_v<RecipeTy,
267207 mlir::acc::ReductionRecipeOp>) {
268208 createInitRecipe (loc, locEnd, varRef->getSourceRange (), mainOp,
269209 recipe.getInitRegion (), numBounds, boundTypes, varRecipe,
270- origType);
210+ origType, /* emitInitExpr= */ true );
271211 createReductionRecipeCombiner (loc, locEnd, mainOp, recipe, numBounds);
272212 } else {
273213 static_assert (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>);
274- // TODO: OpenACC: we probably want this to call createInitRecipe as well,
275- // but do so in a way that omits the 'initialization', so that we can do
276- // it separately, since it belongs in the 'copy' region. It also might
277- // need a way of getting the tempDeclEmission out of it for that purpose.
278- createRecipeInitCopy (loc, locEnd, varRef->getSourceRange (), mainOp,
279- recipe, varRecipe, temporary);
214+ createInitRecipe (loc, locEnd, varRef->getSourceRange (), mainOp,
215+ recipe.getInitRegion (), numBounds, boundTypes, varRecipe,
216+ origType, /* emitInitExpr=*/ false );
217+ createFirstprivateRecipeCopy (loc, locEnd, mainOp, varRecipe, temporary,
218+ recipe.getCopyRegion (), numBounds);
280219 }
281220
282221 if (origType.isDestructedType ())
0 commit comments