15#include "mlir/Dialect/OpenACC/OpenACC.h"
24template <
typename Op,
typename TermOp>
25mlir::LogicalResult CIRGenFunction::emitOpenACCOpAssociatedStmt(
28 mlir::LogicalResult res = mlir::success();
30 llvm::SmallVector<mlir::Type> retTy;
31 llvm::SmallVector<mlir::Value> operands;
32 auto op = Op::create(builder, start, retTy, operands,
35 emitOpenACCClauses(op, dirKind, clauses);
38 mlir::Block &block = op.getRegion().emplaceBlock();
39 mlir::OpBuilder::InsertionGuard guardCase(builder);
40 builder.setInsertionPointToEnd(&block);
42 LexicalScope ls{*
this, start, builder.getInsertionBlock()};
44 res =
emitStmt(associatedStmt,
true);
46 TermOp::create(builder, end);
52template <
typename Op>
struct CombinedType;
53template <>
struct CombinedType<ParallelOp> {
54 static constexpr mlir::acc::CombinedConstructsType value =
55 mlir::acc::CombinedConstructsType::ParallelLoop;
57template <>
struct CombinedType<SerialOp> {
58 static constexpr mlir::acc::CombinedConstructsType value =
59 mlir::acc::CombinedConstructsType::SerialLoop;
61template <>
struct CombinedType<KernelsOp> {
62 static constexpr mlir::acc::CombinedConstructsType value =
63 mlir::acc::CombinedConstructsType::KernelsLoop;
67template <
typename Op,
typename TermOp>
68mlir::LogicalResult CIRGenFunction::emitOpenACCOpCombinedConstruct(
70 llvm::ArrayRef<const OpenACCClause *> clauses,
const Stmt *loopStmt) {
71 mlir::LogicalResult res = mlir::success();
73 llvm::SmallVector<mlir::Type> retTy;
74 llvm::SmallVector<mlir::Value> operands;
77 Op::create(builder, start, retTy, operands,
79 computeOp.setCombinedAttr(builder.getUnitAttr());
80 mlir::acc::LoopOp loopOp;
85 mlir::Block &block = computeOp.getRegion().emplaceBlock();
86 mlir::OpBuilder::InsertionGuard guardCase(builder);
87 builder.setInsertionPointToEnd(&block);
89 LexicalScope ls{*
this, start, builder.getInsertionBlock()};
91 LoopOp::create(builder, start, retTy, operands,
93 loopOp.setCombinedAttr(mlir::acc::CombinedConstructsTypeAttr::get(
94 builder.getContext(), CombinedType<Op>::value));
97 mlir::Block &innerBlock = loopOp.getRegion().emplaceBlock();
98 mlir::OpBuilder::InsertionGuard guardCase(builder);
99 builder.setInsertionPointToEnd(&innerBlock);
101 LexicalScope ls{*
this, start, builder.getInsertionBlock()};
102 ActiveOpenACCLoopRAII activeLoop{*
this, &loopOp};
107 mlir::acc::YieldOp::create(builder, end);
110 emitOpenACCClauses(computeOp, loopOp, dirKind, clauses);
112 updateLoopOpParallelism(loopOp,
false, dirKind);
114 TermOp::create(builder, end);
120template <
typename Op>
121Op CIRGenFunction::emitOpenACCOp(
123 llvm::ArrayRef<const OpenACCClause *> clauses) {
124 llvm::SmallVector<mlir::Type> retTy;
125 llvm::SmallVector<mlir::Value> operands;
126 auto op = Op::create(builder, start, retTy, operands,
129 emitOpenACCClauses(op, dirKind, clauses);
135 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
136 mlir::Location end =
getLoc(s.getSourceRange().getEnd());
138 switch (s.getDirectiveKind()) {
140 return emitOpenACCOpAssociatedStmt<ParallelOp, mlir::acc::YieldOp>(
141 start, end, s.getDirectiveKind(), s.clauses(), s.getStructuredBlock());
143 return emitOpenACCOpAssociatedStmt<SerialOp, mlir::acc::YieldOp>(
144 start, end, s.getDirectiveKind(), s.clauses(), s.getStructuredBlock());
146 return emitOpenACCOpAssociatedStmt<KernelsOp, mlir::acc::TerminatorOp>(
147 start, end, s.getDirectiveKind(), s.clauses(), s.getStructuredBlock());
149 llvm_unreachable(
"invalid compute construct kind");
155 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
156 mlir::Location end =
getLoc(s.getSourceRange().getEnd());
158 return emitOpenACCOpAssociatedStmt<DataOp, mlir::acc::TerminatorOp>(
164 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
165 emitOpenACCOp<InitOp>(start, s.getDirectiveKind(), s.clauses());
166 return mlir::success();
171 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
172 emitOpenACCOp<SetOp>(start, s.getDirectiveKind(), s.clauses());
173 return mlir::success();
178 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
179 emitOpenACCOp<ShutdownOp>(start, s.getDirectiveKind(), s.clauses());
180 return mlir::success();
185 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
186 auto waitOp = emitOpenACCOp<WaitOp>(start, s.getDirectiveKind(), s.clauses());
188 auto createIntExpr = [
this](
const Expr *intExpr) {
190 mlir::Location exprLoc =
cgm.getLoc(intExpr->getBeginLoc());
192 mlir::IntegerType targetType = mlir::IntegerType::get(
194 intExpr->getType()->isSignedIntegerOrEnumerationType()
195 ? mlir::IntegerType::SignednessSemantics::Signed
196 : mlir::IntegerType::SignednessSemantics::Unsigned);
198 return builder.createBuiltinIntCast(exprLoc,
expr, targetType);
203 mlir::OpBuilder::InsertionGuard guardCase(builder);
204 builder.setInsertionPoint(waitOp);
207 waitOp.getWaitDevnumMutable().append(createIntExpr(s.
getDevNumExpr()));
210 waitOp.getWaitOperandsMutable().append(createIntExpr(QueueExpr));
213 return mlir::success();
218 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
219 mlir::Location end =
getLoc(s.getSourceRange().getEnd());
221 switch (s.getDirectiveKind()) {
223 return emitOpenACCOpCombinedConstruct<ParallelOp, mlir::acc::YieldOp>(
224 start, end, s.getDirectiveKind(), s.clauses(), s.
getLoop());
226 return emitOpenACCOpCombinedConstruct<SerialOp, mlir::acc::YieldOp>(
227 start, end, s.getDirectiveKind(), s.clauses(), s.
getLoop());
229 return emitOpenACCOpCombinedConstruct<KernelsOp, mlir::acc::TerminatorOp>(
230 start, end, s.getDirectiveKind(), s.clauses(), s.
getLoop());
232 llvm_unreachable(
"invalid compute construct kind");
238 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
239 mlir::Location end =
getLoc(s.getSourceRange().getEnd());
241 return emitOpenACCOpAssociatedStmt<HostDataOp, mlir::acc::TerminatorOp>(
247 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
248 emitOpenACCOp<EnterDataOp>(start, s.getDirectiveKind(), s.clauses());
249 return mlir::success();
254 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
255 emitOpenACCOp<ExitDataOp>(start, s.getDirectiveKind(), s.clauses());
256 return mlir::success();
261 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
262 emitOpenACCOp<UpdateOp>(start, s.getDirectiveKind(), s.clauses());
263 return mlir::success();
275 return mlir::success();
277 mlir::acc::LoopOp loopOp = *activeLoopOp;
279 mlir::OpBuilder::InsertionGuard guard(builder);
280 builder.setInsertionPoint(loopOp);
290 loopOp.getCacheOperandsMutable().append(cacheOp.getResult());
293 return mlir::success();
306static mlir::acc::AtomicReadOp
308 mlir::Location start,
319 return mlir::acc::AtomicReadOp::create(builder, start, x, v, resTy,
323static mlir::acc::AtomicWriteOp
325 mlir::Location start,
329 return mlir::acc::AtomicWriteOp::create(builder, start, x,
expr,
333static std::pair<mlir::LogicalResult, mlir::acc::AtomicUpdateOp>
335 mlir::Location start, mlir::Location end,
338 auto op = mlir::acc::AtomicUpdateOp::create(builder, start, x, {});
340 mlir::LogicalResult res = mlir::success();
342 mlir::OpBuilder::InsertionGuard guardCase(builder);
344 std::array<mlir::Type, 1> recipeType{argTy};
345 std::array<mlir::Location, 1> recipeLoc{start};
346 auto *recipeBlock = builder.createBlock(
347 &op.getRegion(), op.getRegion().end(), recipeType, recipeLoc);
348 builder.setInsertionPointToEnd(recipeBlock);
355 auto alloca = cir::AllocaOp::create(
356 builder, start, x.getType(),
"x_var",
360 alloca.setInitAttr(builder.getUnitAttr());
361 builder.CIRBaseBuilderTy::createStore(start, recipeBlock->getArgument(0),
372 auto load = cir::LoadOp::create(builder, start, alloca.getResult());
373 mlir::acc::YieldOp::create(builder, end, {load});
384 mlir::Location start =
getLoc(s.getSourceRange().getBegin());
385 mlir::Location end =
getLoc(s.getSourceRange().getEnd());
391 mlir::acc::AtomicReadOp op =
393 emitOpenACCClauses(op, s.getDirectiveKind(), s.clauses());
394 return mlir::success();
399 emitOpenACCClauses(op, s.getDirectiveKind(), s.clauses());
400 return mlir::success();
406 emitOpenACCClauses(op, s.getDirectiveKind(), s.clauses());
413 auto op = mlir::acc::AtomicCaptureOp::create(builder, start, {});
414 emitOpenACCClauses(op, s.getDirectiveKind(), s.clauses());
415 mlir::LogicalResult res = mlir::success();
417 mlir::OpBuilder::InsertionGuard guardCase(builder);
420 builder.createBlock(&op.getRegion(), op.getRegion().end(), {}, {});
422 builder.setInsertionPointToStart(block);
424 auto terminator = mlir::acc::TerminatorOp::create(builder, end);
429 builder.setInsertionPoint(op);
433 llvm_unreachable(
"invalid form for Capture");
435 mlir::acc::AtomicReadOp first =
437 mlir::acc::AtomicWriteOp second =
440 first->moveBefore(terminator);
441 second->moveBefore(terminator);
445 mlir::acc::AtomicReadOp first =
447 auto [this_res, second] =
451 first->moveBefore(terminator);
452 second->moveBefore(terminator);
456 auto [this_res, first] =
459 mlir::acc::AtomicReadOp second =
462 first->moveBefore(terminator);
463 second->moveBefore(terminator);
472 llvm_unreachable(
"unknown OpenACC atomic kind");
static mlir::acc::AtomicReadOp emitAtomicRead(CIRGenFunction &cgf, CIRGenBuilderTy &builder, mlir::Location start, const OpenACCAtomicConstruct::SingleStmtInfo &inf)
static std::pair< mlir::LogicalResult, mlir::acc::AtomicUpdateOp > emitAtomicUpdate(CIRGenFunction &cgf, CIRGenBuilderTy &builder, mlir::Location start, mlir::Location end, const OpenACCAtomicConstruct::SingleStmtInfo &inf)
static mlir::acc::AtomicWriteOp emitAtomicWrite(CIRGenFunction &cgf, CIRGenBuilderTy &builder, mlir::Location start, const OpenACCAtomicConstruct::SingleStmtInfo &inf)
const VarDecl * getLValueDecl(const Expr *e)
This file defines OpenACC AST classes for statement-level contructs.
const StmtInfo getAssociatedStmtInfo() const
OpenACCAtomicKind getAtomicKind() const
ArrayRef< Expr * > getVarList() const
Stmt * getStructuredBlock()
Stmt * getStructuredBlock()
bool hasDevNumExpr() const
ArrayRef< Expr * > getQueueIdExprs() const
Expr * getDevNumExpr() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
mlir::Type convertType(clang::QualType t)
mlir::LogicalResult emitOpenACCDataConstruct(const OpenACCDataConstruct &s)
mlir::LogicalResult emitOpenACCCombinedConstruct(const OpenACCCombinedConstruct &s)
mlir::LogicalResult emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s)
mlir::LogicalResult emitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &s)
mlir::LogicalResult emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s)
void replaceAddrOfLocalVar(const clang::VarDecl *vd, Address addr)
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::LogicalResult emitOpenACCInitConstruct(const OpenACCInitConstruct &s)
mlir::LogicalResult emitOpenACCSetConstruct(const OpenACCSetConstruct &s)
OpenACCDataOperandInfo getOpenACCDataOperandInfo(const Expr *e)
mlir::LogicalResult emitOpenACCComputeConstruct(const OpenACCComputeConstruct &s)
mlir::LogicalResult emitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &s)
mlir::LogicalResult emitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &s)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
mlir::MLIRContext & getMLIRContext()
mlir::LogicalResult emitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &s)
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
Emit code to compute the specified expression which can have any type.
clang::ASTContext & getContext() const
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
mlir::LogicalResult emitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &s)
mlir::LogicalResult emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s)
mlir::IntegerAttr getSize(CharUnits size)
mlir::Value getPointer() const
mlir::Value getValue() const
Return the value of this scalar value.
This represents one expression.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Stmt - This represents one statement.
Represents a variable declaration or definition.
Op::Properties getDefaultProperties(mlir::MLIRContext *context)
The properties of Op with every ODS-declared default applied.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
Top level wrappers for InstallAPI frontend operations.
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
U cast(CodeGen::Address addr)
enum OpenACCAtomicConstruct::StmtInfo::StmtForm Form
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
llvm::SmallVector< mlir::Value > bounds