32 return mlir::acc::ReductionOperator::AccAdd;
34 return mlir::acc::ReductionOperator::AccMul;
36 return mlir::acc::ReductionOperator::AccMax;
38 return mlir::acc::ReductionOperator::AccMin;
40 return mlir::acc::ReductionOperator::AccIand;
42 return mlir::acc::ReductionOperator::AccIor;
44 return mlir::acc::ReductionOperator::AccXor;
46 return mlir::acc::ReductionOperator::AccLand;
48 return mlir::acc::ReductionOperator::AccLor;
50 llvm_unreachable(
"invalid reduction operator");
53 llvm_unreachable(
"invalid reduction operator");
58 std::string recipeName;
60 llvm::raw_string_ostream stream(recipeName);
62 if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
63 stream <<
"privatization_";
64 }
else if constexpr (std::is_same_v<RecipeTy,
65 mlir::acc::FirstprivateRecipeOp>) {
66 stream <<
"firstprivatization_";
68 }
else if constexpr (std::is_same_v<RecipeTy,
69 mlir::acc::ReductionRecipeOp>) {
70 stream <<
"reduction_";
74 switch (reductionOp) {
103 llvm_unreachable(
"invalid reduction operator");
106 static_assert(!
sizeof(RecipeTy),
"Unknown Recipe op kind");
115 void createFirstprivateRecipeCopy(
116 mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
118 mlir::acc::FirstprivateRecipeOp recipe,
const VarDecl *varRecipe,
120 mlir::Block *block = builder.createBlock(
121 &recipe.getCopyRegion(), recipe.getCopyRegion().end(),
122 {mainOp.getType(), mainOp.getType()}, {loc, loc});
123 builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
126 mlir::BlockArgument fromArg = block->getArgument(0);
127 mlir::BlockArgument toArg = block->getArgument(1);
129 mlir::Type elementTy =
130 mlir::cast<cir::PointerType>(mainOp.getType()).getPointee();
135 Address{toArg, elementTy, cgf.getContext().getDeclAlign(varRecipe)});
139 cgf.setAddrOfLocalVar(
141 Address{fromArg, elementTy, cgf.getContext().getDeclAlign(varRecipe)});
143 cgf.emitAutoVarInit(tempDeclEmission);
144 mlir::acc::YieldOp::create(builder, locEnd);
151 void createRecipeInitCopy(mlir::Location loc, mlir::Location locEnd,
153 RecipeTy recipe,
const VarDecl *varRecipe,
155 assert(varRecipe &&
"Required recipe variable not set?");
163 mlir::Block *block = builder.createBlock(&recipe.getInitRegion(),
164 recipe.getInitRegion().end(),
165 {mainOp.getType()}, {loc});
166 builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
170 cgf.emitAutoVarAlloca(*varRecipe, builder.saveInsertionPoint());
177 if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
180 if (cgf.getContext().getLangOpts().CPlusPlus &&
190 cgf.cgm.errorNYI(exprRange,
"private default-init recipe");
192 cgf.emitAutoVarInit(tempDeclEmission);
193 }
else if constexpr (std::is_same_v<RecipeTy,
194 mlir::acc::ReductionRecipeOp>) {
198 cgf.cgm.errorNYI(exprRange,
"reduction init recipe");
199 cgf.emitAutoVarInit(tempDeclEmission);
202 mlir::acc::YieldOp::create(builder, locEnd);
204 if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp>) {
212 exprRange,
"firstprivate copy-init recipe not properly generated");
215 createFirstprivateRecipeCopy(loc, locEnd, mainOp, tempDeclEmission,
216 recipe, varRecipe, temporary);
224 void createReductionRecipeCombiner(mlir::Location loc, mlir::Location locEnd,
226 mlir::acc::ReductionRecipeOp recipe) {
227 mlir::Block *block = builder.createBlock(
228 &recipe.getCombinerRegion(), recipe.getCombinerRegion().end(),
229 {mainOp.getType(), mainOp.getType()}, {loc, loc});
230 builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
233 mlir::BlockArgument lhsArg = block->getArgument(0);
235 mlir::acc::YieldOp::create(builder, locEnd, lhsArg);
242 void createRecipeDestroySection(mlir::Location loc, mlir::Location locEnd,
245 mlir::Region &destroyRegion) {
247 builder.createBlock(&destroyRegion, destroyRegion.end(),
248 {mainOp.getType(), mainOp.getType()}, {loc, loc});
249 builder.setInsertionPointToEnd(&destroyRegion.back());
252 mlir::Type elementTy =
253 mlir::cast<cir::PointerType>(mainOp.getType()).getPointee();
257 Address addr{block->getArgument(1), elementTy, alignment};
258 cgf.emitDestroy(addr, baseType,
261 mlir::acc::YieldOp::create(builder, locEnd);
267 : cgf(cgf), builder(builder) {}
272 mlir::Value mainOp) {
284 "OpenACC recipe generation for pointer/non-constant arrays");
287 mlir::ModuleOp mod = builder.getBlock()
289 ->template getParentOfType<mlir::ModuleOp>();
291 std::string recipeName =
293 if (
auto recipe = mod.lookupSymbol<RecipeTy>(recipeName))
296 mlir::Location loc = cgf.cgm.getLoc(varRef->
getBeginLoc());
297 mlir::Location locEnd = cgf.cgm.getLoc(varRef->
getEndLoc());
299 mlir::OpBuilder modBuilder(mod.getBodyRegion());
302 if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
303 recipe = RecipeTy::create(modBuilder, loc, recipeName, mainOp.getType(),
304 convertReductionOp(reductionOp));
306 recipe = RecipeTy::create(modBuilder, loc, recipeName, mainOp.getType());
309 createRecipeInitCopy(loc, locEnd, varRef->
getSourceRange(), mainOp, recipe,
310 varRecipe, temporary);
312 if constexpr (std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
313 createReductionRecipeCombiner(loc, locEnd, mainOp, recipe);
317 createRecipeDestroySection(loc, locEnd, mainOp,
318 cgf.getContext().getDeclAlign(varRecipe),
319 baseType, recipe.getDestroyRegion());
Defines the clang::ASTContext interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.