diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp index e603884..bbc45e5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp @@ -400,23 +400,47 @@ void OpenACCRecipeBuilderBase::createRecipeDestroySection( mlir::acc::YieldOp::create(builder, locEnd); } +void OpenACCRecipeBuilderBase::makeBoundsInit( + mlir::Value alloca, mlir::Location loc, mlir::Block *block, + const VarDecl *allocaDecl, QualType origType, bool isInitSection) { + mlir::OpBuilder::InsertionGuard guardCase(builder); + builder.setInsertionPointToEnd(block); + CIRGenFunction::LexicalScope ls(cgf, loc, block); + + CIRGenFunction::AutoVarEmission tempDeclEmission{*allocaDecl}; + tempDeclEmission.emittedAsOffload = true; + + // The init section is the only one of the handful that only has a single + // argument for the 'type', so we have to drop 1 for init, and future calls + // to this will need to drop 2. + llvm::MutableArrayRef<mlir::BlockArgument> boundsRange = + block->getArguments().drop_front(isInitSection ? 1 : 2); + + mlir::Value subscriptedValue = alloca; + for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange)) + subscriptedValue = createBoundsLoop(subscriptedValue, boundArg, loc, + /*inverse=*/false); + + tempDeclEmission.setAllocatedAddress( + Address{subscriptedValue, cgf.convertType(origType), + cgf.getContext().getDeclAlign(allocaDecl)}); + cgf.emitAutoVarInit(tempDeclEmission); +} -// TODO: OpenACC: When we get this implemented for the reduction/firstprivate, -// this might end up re-merging with createRecipeInitCopy. For now, keep it -// separate until we're sure what everything looks like to keep this as clean -// as possible. -void OpenACCRecipeBuilderBase::createPrivateInitRecipe( +// TODO: OpenACC: when we start doing firstprivate for array/vlas/etc, we +// probably need to do a little work about the 'init' calls to put it in 'copy' +// region instead. +void OpenACCRecipeBuilderBase::createInitRecipe( mlir::Location loc, mlir::Location locEnd, SourceRange exprRange, - mlir::Value mainOp, mlir::acc::PrivateRecipeOp recipe, size_t numBounds, + mlir::Value mainOp, mlir::Region &recipeInitRegion, size_t numBounds, llvm::ArrayRef<QualType> boundTypes, const VarDecl *allocaDecl, - QualType origType, const Expr *initExpr) { + QualType origType) { assert(allocaDecl && "Required recipe variable not set?"); CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, allocaDecl}; - mlir::Block *block = - createRecipeBlock(recipe.getInitRegion(), mainOp.getType(), loc, - numBounds, /*isInit=*/true); - builder.setInsertionPointToEnd(&recipe.getInitRegion().back()); + mlir::Block *block = createRecipeBlock(recipeInitRegion, mainOp.getType(), + loc, numBounds, /*isInit=*/true); + builder.setInsertionPointToEnd(&recipeInitRegion.back()); CIRGenFunction::LexicalScope ls(cgf, loc, block); const Type *allocaPointeeType = @@ -432,7 +456,7 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe( // Sema::TentativeAnalysisScopes in SemaOpenACC::CreateInitRecipe, it'll // emit an error to tell us. However, emitting those errors during // production is a violation of the standard, so we cannot do them. - cgf.cgm.errorNYI(exprRange, "private default-init recipe"); + cgf.cgm.errorNYI(exprRange, "private/reduction default-init recipe"); } if (!numBounds) { @@ -442,11 +466,17 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe( cgf.emitAutoVarAlloca(*allocaDecl, builder.saveInsertionPoint()); cgf.emitAutoVarInit(tempDeclEmission); } else { - makeBoundsAlloca(block, exprRange, loc, "openacc.private.init", numBounds, - boundTypes); - - if (initExpr) - cgf.cgm.errorNYI(exprRange, "private-init with bounds initialization"); + mlir::Value alloca = makeBoundsAlloca( + block, exprRange, loc, allocaDecl->getName(), numBounds, boundTypes); + + // If the initializer is trivial, there is nothing to do here, so save + // ourselves some effort. + if (allocaDecl->getInit() && + (!cgf.isTrivialInitializer(allocaDecl->getInit()) || + cgf.getContext().getLangOpts().getTrivialAutoVarInit() != + LangOptions::TrivialAutoVarInitKind::Uninitialized)) + makeBoundsInit(alloca, loc, block, allocaDecl, origType, + /*isInitSection=*/true); } mlir::acc::YieldOp::create(builder, locEnd); @@ -473,7 +503,7 @@ void OpenACCRecipeBuilderBase::createFirstprivateRecipeCopy( // that instead of the variable in the other block. tempDeclEmission.setAllocatedAddress( Address{toArg, elementTy, cgf.getContext().getDeclAlign(varRecipe)}); - tempDeclEmission.EmittedAsOffload = true; + tempDeclEmission.emittedAsOffload = true; CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, temporary}; cgf.setAddrOfLocalVar( @@ -489,10 +519,10 @@ void OpenACCRecipeBuilderBase::createFirstprivateRecipeCopy( // doesn't restore it aftewards. void OpenACCRecipeBuilderBase::createReductionRecipeCombiner( mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp, - mlir::acc::ReductionRecipeOp recipe) { - mlir::Block *block = builder.createBlock( - &recipe.getCombinerRegion(), recipe.getCombinerRegion().end(), - {mainOp.getType(), mainOp.getType()}, {loc, loc}); + mlir::acc::ReductionRecipeOp recipe, size_t numBounds) { + mlir::Block *block = + createRecipeBlock(recipe.getCombinerRegion(), mainOp.getType(), loc, + numBounds, /*isInit=*/false); builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back()); CIRGenFunction::LexicalScope ls(cgf, loc, block); |