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,19 @@ #ifndef FORTRAN_LOWER_OPENACC_H #define FORTRAN_LOWER_OPENACC_H +namespace llvm { +class StringRef; +} + +namespace mlir { +class Location; +class Type; +class OpBuilder; +namespace acc { +class PrivateRecipeOp; +} +} // namespace mlir + namespace Fortran { namespace parser { struct OpenACCConstruct; @@ -38,6 +51,12 @@ 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(mlir::OpBuilder &, + llvm::StringRef, + 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,17 @@ } } -static mlir::acc::PrivateRecipeOp -createBasePrivateRecipeOp(fir::FirOpBuilder &builder, mlir::Value input, - llvm::StringRef recipeName, mlir::Location loc) { - mlir::ModuleOp mod = builder.getModule(); +mlir::acc::PrivateRecipeOp +Fortran::lower::createOrGetPrivateRecipe(mlir::OpBuilder &builder, + llvm::StringRef recipeName, + mlir::Location loc, mlir::Type ty) { + mlir::ModuleOp mod = + builder.getBlock()->getParent()->getParentOfType(); + 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 +496,7 @@ builder.setInsertionPointToEnd(&recipe.getInitRegion().back()); builder.create( loc, recipe.getInitRegion().front().getArgument(0)); + builder.restoreInsertionPoint(crtPos); return recipe; } @@ -502,7 +508,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 +515,13 @@ 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( + builder, recipeName, operandLocation, baseAddr.getType()); + privatizations.push_back(mlir::SymbolRefAttr::get( + builder.getContext(), recipe.getSymName().str())); dataOperands.push_back(baseAddr); } }