diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h --- a/flang/include/flang/Lower/OpenACC.h +++ b/flang/include/flang/Lower/OpenACC.h @@ -13,6 +13,14 @@ #ifndef FORTRAN_LOWER_OPENACC_H #define FORTRAN_LOWER_OPENACC_H +namespace mlir { +class Location; +class Type; +namespace acc { +class PrivateRecipeOp; +} +} // namespace mlir + namespace Fortran { namespace parser { struct OpenACCConstruct; @@ -38,6 +46,11 @@ AbstractConverter &, pft::Evaluation &, const parser::OpenACCDeclarativeConstruct &); +/// Get a acc.private.recipe op for the given type or create it if it does not +/// exist yet. +mlir::acc::PrivateRecipeOp createOrGetPrivateRecipe(AbstractConverter &, + mlir::Location, mlir::Type); + } // namespace lower } // namespace Fortran diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -478,12 +478,18 @@ } } -static mlir::acc::PrivateRecipeOp -createBasePrivateRecipeOp(fir::FirOpBuilder &builder, mlir::Value input, - llvm::StringRef recipeName, mlir::Location loc) { +mlir::acc::PrivateRecipeOp Fortran::lower::createOrGetPrivateRecipe( + Fortran::lower::AbstractConverter &converter, mlir::Location loc, + mlir::Type ty) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + std::string recipeName = + fir::getTypeAsString(ty, converter.getKindMap(), "privatization"); mlir::ModuleOp mod = builder.getModule(); + if (auto recipe = mod.lookupSymbol(recipeName)) + return recipe; + + auto crtPos = builder.saveInsertionPoint(); mlir::OpBuilder modBuilder(mod.getBodyRegion()); - mlir::Type ty = input.getType(); auto recipe = modBuilder.create(loc, recipeName, ty); builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(), @@ -491,6 +497,7 @@ builder.setInsertionPointToEnd(&recipe.getInitRegion().back()); builder.create( loc, recipe.getInitRegion().front().getArgument(0)); + builder.restoreInsertionPoint(crtPos); return recipe; } @@ -502,7 +509,6 @@ llvm::SmallVectorImpl &dataOperands, llvm::SmallVector &privatizations) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - mlir::ModuleOp mod = builder.getModule(); for (const auto &accObject : objectList.v) { llvm::SmallVector bounds; std::stringstream asFortran; @@ -510,21 +516,11 @@ mlir::Value baseAddr = gatherDataOperandAddrAndBounds( converter, builder, semanticsContext, stmtCtx, accObject, operandLocation, asFortran, bounds); - - std::string recipeName = fir::getTypeAsString( - baseAddr.getType(), converter.getKindMap(), "privatization"); - if (auto recipe = - mod.lookupSymbol(recipeName)) { - privatizations.push_back(mlir::SymbolRefAttr::get( - builder.getContext(), recipe.getSymName().str())); - } else { - auto crtPos = builder.saveInsertionPoint(); - mlir::acc::PrivateRecipeOp newRecipe = createBasePrivateRecipeOp( - builder, baseAddr, recipeName, operandLocation); - builder.restoreInsertionPoint(crtPos); - privatizations.push_back(mlir::SymbolRefAttr::get( - builder.getContext(), newRecipe.getSymName().str())); - } + mlir::acc::PrivateRecipeOp recipe = + Fortran::lower::createOrGetPrivateRecipe(converter, operandLocation, + baseAddr.getType()); + privatizations.push_back(mlir::SymbolRefAttr::get( + builder.getContext(), recipe.getSymName().str())); dataOperands.push_back(baseAddr); } }