Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 57 additions & 17 deletions clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,20 @@ class OpenACCClauseCIREmitter final
return recipeName;
}

void createFirstprivateRecipeCopy(
mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
CIRGenFunction::AutoVarEmission tempDeclEmission,
mlir::acc::FirstprivateRecipeOp recipe, const VarDecl *varRecipe,
const VarDecl *temporary) {
builder.createBlock(&recipe.getCopyRegion(), recipe.getCopyRegion().end(),
{mainOp.getType(), mainOp.getType()}, {loc, loc});
builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());

// TODO: OpenACC: Implement this copy to actually do something.

mlir::acc::YieldOp::create(builder, locEnd);
}

// Create the 'init' section of the recipe, including the 'copy' section for
// 'firstprivate'.
template <typename RecipeTy>
Expand All @@ -401,12 +415,6 @@ class OpenACCClauseCIREmitter final
cgf.cgm.errorNYI(exprRange, "OpenACC Reduction recipe init");
}

if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
// We haven't implemented the 'init'/copy recipe for firstprivate yet, so
// NYI it.
cgf.cgm.errorNYI(exprRange, "OpenACC firstprivate recipe init");
}

CIRGenFunction::AutoVarEmission tempDeclEmission{
CIRGenFunction::AutoVarEmission::invalid()};

Expand Down Expand Up @@ -442,17 +450,12 @@ class OpenACCClauseCIREmitter final
mlir::acc::YieldOp::create(builder, locEnd);

if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
if (!varRecipe->getInit()) {
// If we don't have any initialization recipe, we failed during Sema to
// initialize this correctly. If we disable the
// 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, "firstprivate copy-init recipe not properly generated");
}

cgf.cgm.errorNYI(exprRange, "firstprivate copy section generation");
// TODO: OpenACC: we should have a errorNYI call here if
// !varRecipe->getInit(), but as that generation isn't currently
// implemented, it ends up being too noisy. So when we implement copy-init
// generation both in Sema and here, we should have a diagnostic here.
createFirstprivateRecipeCopy(loc, locEnd, mainOp, tempDeclEmission,
recipe, varRecipe, temporary);
}

// Make sure we cleanup after ourselves here.
Expand Down Expand Up @@ -1155,6 +1158,43 @@ class OpenACCClauseCIREmitter final
llvm_unreachable("Unknown construct kind in VisitPrivateClause");
}
}

void VisitFirstPrivateClause(const OpenACCFirstPrivateClause &clause) {
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
mlir::acc::SerialOp>) {
for (const auto [varExpr, varRecipe] :
llvm::zip_equal(clause.getVarList(), clause.getInitRecipes())) {
CIRGenFunction::OpenACCDataOperandInfo opInfo =
cgf.getOpenACCDataOperandInfo(varExpr);
auto firstPrivateOp = mlir::acc::FirstprivateOp::create(
builder, opInfo.beginLoc, opInfo.varValue, /*structured=*/true,
/*implicit=*/false, opInfo.name, opInfo.bounds);

firstPrivateOp.setDataClause(mlir::acc::DataClause::acc_firstprivate);

{
mlir::OpBuilder::InsertionGuard guardCase(builder);
auto recipe = getOrCreateRecipe<mlir::acc::FirstprivateRecipeOp>(
cgf.getContext(), varExpr, varRecipe.RecipeDecl,
varRecipe.InitFromTemporary,
Decl::castToDeclContext(cgf.curFuncDecl), opInfo.baseType,
firstPrivateOp.getResult());

// TODO: OpenACC: The dialect is going to change in the near future to
// have these be on a different operation, so when that changes, we
// probably need to change these here.
operation.addFirstPrivatization(builder.getContext(), firstPrivateOp,
recipe);
}
}
} else if constexpr (isCombinedType<OpTy>) {
// Unlike 'private', 'firstprivate' applies to the compute op, not the
// loop op.
applyToComputeOp(clause);
} else {
llvm_unreachable("Unknown construct kind in VisitFirstPrivateClause");
}
}
};

template <typename OpTy>
Expand Down
Loading