1*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // Emit OpenACC Stmt nodes as CIR code.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric
13*700637cbSDimitry Andric #include "CIRGenBuilder.h"
14*700637cbSDimitry Andric #include "CIRGenFunction.h"
15*700637cbSDimitry Andric #include "mlir/Dialect/OpenACC/OpenACC.h"
16*700637cbSDimitry Andric #include "clang/AST/OpenACCClause.h"
17*700637cbSDimitry Andric #include "clang/AST/StmtOpenACC.h"
18*700637cbSDimitry Andric
19*700637cbSDimitry Andric using namespace clang;
20*700637cbSDimitry Andric using namespace clang::CIRGen;
21*700637cbSDimitry Andric using namespace cir;
22*700637cbSDimitry Andric using namespace mlir::acc;
23*700637cbSDimitry Andric
24*700637cbSDimitry Andric template <typename Op, typename TermOp>
emitOpenACCOpAssociatedStmt(mlir::Location start,mlir::Location end,OpenACCDirectiveKind dirKind,SourceLocation dirLoc,llvm::ArrayRef<const OpenACCClause * > clauses,const Stmt * associatedStmt)25*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCOpAssociatedStmt(
26*700637cbSDimitry Andric mlir::Location start, mlir::Location end, OpenACCDirectiveKind dirKind,
27*700637cbSDimitry Andric SourceLocation dirLoc, llvm::ArrayRef<const OpenACCClause *> clauses,
28*700637cbSDimitry Andric const Stmt *associatedStmt) {
29*700637cbSDimitry Andric mlir::LogicalResult res = mlir::success();
30*700637cbSDimitry Andric
31*700637cbSDimitry Andric llvm::SmallVector<mlir::Type> retTy;
32*700637cbSDimitry Andric llvm::SmallVector<mlir::Value> operands;
33*700637cbSDimitry Andric auto op = builder.create<Op>(start, retTy, operands);
34*700637cbSDimitry Andric
35*700637cbSDimitry Andric emitOpenACCClauses(op, dirKind, dirLoc, clauses);
36*700637cbSDimitry Andric
37*700637cbSDimitry Andric {
38*700637cbSDimitry Andric mlir::Block &block = op.getRegion().emplaceBlock();
39*700637cbSDimitry Andric mlir::OpBuilder::InsertionGuard guardCase(builder);
40*700637cbSDimitry Andric builder.setInsertionPointToEnd(&block);
41*700637cbSDimitry Andric
42*700637cbSDimitry Andric LexicalScope ls{*this, start, builder.getInsertionBlock()};
43*700637cbSDimitry Andric res = emitStmt(associatedStmt, /*useCurrentScope=*/true);
44*700637cbSDimitry Andric
45*700637cbSDimitry Andric builder.create<TermOp>(end);
46*700637cbSDimitry Andric }
47*700637cbSDimitry Andric return res;
48*700637cbSDimitry Andric }
49*700637cbSDimitry Andric
50*700637cbSDimitry Andric namespace {
51*700637cbSDimitry Andric template <typename Op> struct CombinedType;
52*700637cbSDimitry Andric template <> struct CombinedType<ParallelOp> {
53*700637cbSDimitry Andric static constexpr mlir::acc::CombinedConstructsType value =
54*700637cbSDimitry Andric mlir::acc::CombinedConstructsType::ParallelLoop;
55*700637cbSDimitry Andric };
56*700637cbSDimitry Andric template <> struct CombinedType<SerialOp> {
57*700637cbSDimitry Andric static constexpr mlir::acc::CombinedConstructsType value =
58*700637cbSDimitry Andric mlir::acc::CombinedConstructsType::SerialLoop;
59*700637cbSDimitry Andric };
60*700637cbSDimitry Andric template <> struct CombinedType<KernelsOp> {
61*700637cbSDimitry Andric static constexpr mlir::acc::CombinedConstructsType value =
62*700637cbSDimitry Andric mlir::acc::CombinedConstructsType::KernelsLoop;
63*700637cbSDimitry Andric };
64*700637cbSDimitry Andric } // namespace
65*700637cbSDimitry Andric
66*700637cbSDimitry Andric template <typename Op, typename TermOp>
emitOpenACCOpCombinedConstruct(mlir::Location start,mlir::Location end,OpenACCDirectiveKind dirKind,SourceLocation dirLoc,llvm::ArrayRef<const OpenACCClause * > clauses,const Stmt * loopStmt)67*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCOpCombinedConstruct(
68*700637cbSDimitry Andric mlir::Location start, mlir::Location end, OpenACCDirectiveKind dirKind,
69*700637cbSDimitry Andric SourceLocation dirLoc, llvm::ArrayRef<const OpenACCClause *> clauses,
70*700637cbSDimitry Andric const Stmt *loopStmt) {
71*700637cbSDimitry Andric mlir::LogicalResult res = mlir::success();
72*700637cbSDimitry Andric
73*700637cbSDimitry Andric llvm::SmallVector<mlir::Type> retTy;
74*700637cbSDimitry Andric llvm::SmallVector<mlir::Value> operands;
75*700637cbSDimitry Andric
76*700637cbSDimitry Andric auto computeOp = builder.create<Op>(start, retTy, operands);
77*700637cbSDimitry Andric computeOp.setCombinedAttr(builder.getUnitAttr());
78*700637cbSDimitry Andric mlir::acc::LoopOp loopOp;
79*700637cbSDimitry Andric
80*700637cbSDimitry Andric // First, emit the bodies of both operations, with the loop inside the body of
81*700637cbSDimitry Andric // the combined construct.
82*700637cbSDimitry Andric {
83*700637cbSDimitry Andric mlir::Block &block = computeOp.getRegion().emplaceBlock();
84*700637cbSDimitry Andric mlir::OpBuilder::InsertionGuard guardCase(builder);
85*700637cbSDimitry Andric builder.setInsertionPointToEnd(&block);
86*700637cbSDimitry Andric
87*700637cbSDimitry Andric LexicalScope ls{*this, start, builder.getInsertionBlock()};
88*700637cbSDimitry Andric auto loopOp = builder.create<LoopOp>(start, retTy, operands);
89*700637cbSDimitry Andric loopOp.setCombinedAttr(mlir::acc::CombinedConstructsTypeAttr::get(
90*700637cbSDimitry Andric builder.getContext(), CombinedType<Op>::value));
91*700637cbSDimitry Andric
92*700637cbSDimitry Andric {
93*700637cbSDimitry Andric mlir::Block &innerBlock = loopOp.getRegion().emplaceBlock();
94*700637cbSDimitry Andric mlir::OpBuilder::InsertionGuard guardCase(builder);
95*700637cbSDimitry Andric builder.setInsertionPointToEnd(&innerBlock);
96*700637cbSDimitry Andric
97*700637cbSDimitry Andric LexicalScope ls{*this, start, builder.getInsertionBlock()};
98*700637cbSDimitry Andric ActiveOpenACCLoopRAII activeLoop{*this, &loopOp};
99*700637cbSDimitry Andric
100*700637cbSDimitry Andric res = emitStmt(loopStmt, /*useCurrentScope=*/true);
101*700637cbSDimitry Andric
102*700637cbSDimitry Andric builder.create<mlir::acc::YieldOp>(end);
103*700637cbSDimitry Andric }
104*700637cbSDimitry Andric
105*700637cbSDimitry Andric emitOpenACCClauses(computeOp, loopOp, dirKind, dirLoc, clauses);
106*700637cbSDimitry Andric
107*700637cbSDimitry Andric updateLoopOpParallelism(loopOp, /*isOrphan=*/false, dirKind);
108*700637cbSDimitry Andric
109*700637cbSDimitry Andric builder.create<TermOp>(end);
110*700637cbSDimitry Andric }
111*700637cbSDimitry Andric
112*700637cbSDimitry Andric return res;
113*700637cbSDimitry Andric }
114*700637cbSDimitry Andric
115*700637cbSDimitry Andric template <typename Op>
emitOpenACCOp(mlir::Location start,OpenACCDirectiveKind dirKind,SourceLocation dirLoc,llvm::ArrayRef<const OpenACCClause * > clauses)116*700637cbSDimitry Andric Op CIRGenFunction::emitOpenACCOp(
117*700637cbSDimitry Andric mlir::Location start, OpenACCDirectiveKind dirKind, SourceLocation dirLoc,
118*700637cbSDimitry Andric llvm::ArrayRef<const OpenACCClause *> clauses) {
119*700637cbSDimitry Andric llvm::SmallVector<mlir::Type> retTy;
120*700637cbSDimitry Andric llvm::SmallVector<mlir::Value> operands;
121*700637cbSDimitry Andric auto op = builder.create<Op>(start, retTy, operands);
122*700637cbSDimitry Andric
123*700637cbSDimitry Andric emitOpenACCClauses(op, dirKind, dirLoc, clauses);
124*700637cbSDimitry Andric return op;
125*700637cbSDimitry Andric }
126*700637cbSDimitry Andric
127*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCComputeConstruct(const OpenACCComputeConstruct & s)128*700637cbSDimitry Andric CIRGenFunction::emitOpenACCComputeConstruct(const OpenACCComputeConstruct &s) {
129*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
130*700637cbSDimitry Andric mlir::Location end = getLoc(s.getSourceRange().getEnd());
131*700637cbSDimitry Andric
132*700637cbSDimitry Andric switch (s.getDirectiveKind()) {
133*700637cbSDimitry Andric case OpenACCDirectiveKind::Parallel:
134*700637cbSDimitry Andric return emitOpenACCOpAssociatedStmt<ParallelOp, mlir::acc::YieldOp>(
135*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
136*700637cbSDimitry Andric s.getStructuredBlock());
137*700637cbSDimitry Andric case OpenACCDirectiveKind::Serial:
138*700637cbSDimitry Andric return emitOpenACCOpAssociatedStmt<SerialOp, mlir::acc::YieldOp>(
139*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
140*700637cbSDimitry Andric s.getStructuredBlock());
141*700637cbSDimitry Andric case OpenACCDirectiveKind::Kernels:
142*700637cbSDimitry Andric return emitOpenACCOpAssociatedStmt<KernelsOp, mlir::acc::TerminatorOp>(
143*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
144*700637cbSDimitry Andric s.getStructuredBlock());
145*700637cbSDimitry Andric default:
146*700637cbSDimitry Andric llvm_unreachable("invalid compute construct kind");
147*700637cbSDimitry Andric }
148*700637cbSDimitry Andric }
149*700637cbSDimitry Andric
150*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCDataConstruct(const OpenACCDataConstruct & s)151*700637cbSDimitry Andric CIRGenFunction::emitOpenACCDataConstruct(const OpenACCDataConstruct &s) {
152*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
153*700637cbSDimitry Andric mlir::Location end = getLoc(s.getSourceRange().getEnd());
154*700637cbSDimitry Andric
155*700637cbSDimitry Andric return emitOpenACCOpAssociatedStmt<DataOp, mlir::acc::TerminatorOp>(
156*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
157*700637cbSDimitry Andric s.getStructuredBlock());
158*700637cbSDimitry Andric }
159*700637cbSDimitry Andric
160*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCInitConstruct(const OpenACCInitConstruct & s)161*700637cbSDimitry Andric CIRGenFunction::emitOpenACCInitConstruct(const OpenACCInitConstruct &s) {
162*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
163*700637cbSDimitry Andric emitOpenACCOp<InitOp>(start, s.getDirectiveKind(), s.getDirectiveLoc(),
164*700637cbSDimitry Andric s.clauses());
165*700637cbSDimitry Andric return mlir::success();
166*700637cbSDimitry Andric }
167*700637cbSDimitry Andric
168*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCSetConstruct(const OpenACCSetConstruct & s)169*700637cbSDimitry Andric CIRGenFunction::emitOpenACCSetConstruct(const OpenACCSetConstruct &s) {
170*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
171*700637cbSDimitry Andric emitOpenACCOp<SetOp>(start, s.getDirectiveKind(), s.getDirectiveLoc(),
172*700637cbSDimitry Andric s.clauses());
173*700637cbSDimitry Andric return mlir::success();
174*700637cbSDimitry Andric }
175*700637cbSDimitry Andric
emitOpenACCShutdownConstruct(const OpenACCShutdownConstruct & s)176*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCShutdownConstruct(
177*700637cbSDimitry Andric const OpenACCShutdownConstruct &s) {
178*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
179*700637cbSDimitry Andric emitOpenACCOp<ShutdownOp>(start, s.getDirectiveKind(),
180*700637cbSDimitry Andric s.getDirectiveLoc(), s.clauses());
181*700637cbSDimitry Andric return mlir::success();
182*700637cbSDimitry Andric }
183*700637cbSDimitry Andric
184*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCWaitConstruct(const OpenACCWaitConstruct & s)185*700637cbSDimitry Andric CIRGenFunction::emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s) {
186*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
187*700637cbSDimitry Andric auto waitOp = emitOpenACCOp<WaitOp>(start, s.getDirectiveKind(),
188*700637cbSDimitry Andric s.getDirectiveLoc(), s.clauses());
189*700637cbSDimitry Andric
190*700637cbSDimitry Andric auto createIntExpr = [this](const Expr *intExpr) {
191*700637cbSDimitry Andric mlir::Value expr = emitScalarExpr(intExpr);
192*700637cbSDimitry Andric mlir::Location exprLoc = cgm.getLoc(intExpr->getBeginLoc());
193*700637cbSDimitry Andric
194*700637cbSDimitry Andric mlir::IntegerType targetType = mlir::IntegerType::get(
195*700637cbSDimitry Andric &getMLIRContext(), getContext().getIntWidth(intExpr->getType()),
196*700637cbSDimitry Andric intExpr->getType()->isSignedIntegerOrEnumerationType()
197*700637cbSDimitry Andric ? mlir::IntegerType::SignednessSemantics::Signed
198*700637cbSDimitry Andric : mlir::IntegerType::SignednessSemantics::Unsigned);
199*700637cbSDimitry Andric
200*700637cbSDimitry Andric auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
201*700637cbSDimitry Andric exprLoc, targetType, expr);
202*700637cbSDimitry Andric return conversionOp.getResult(0);
203*700637cbSDimitry Andric };
204*700637cbSDimitry Andric
205*700637cbSDimitry Andric // Emit the correct 'wait' clauses.
206*700637cbSDimitry Andric {
207*700637cbSDimitry Andric mlir::OpBuilder::InsertionGuard guardCase(builder);
208*700637cbSDimitry Andric builder.setInsertionPoint(waitOp);
209*700637cbSDimitry Andric
210*700637cbSDimitry Andric if (s.hasDevNumExpr())
211*700637cbSDimitry Andric waitOp.getWaitDevnumMutable().append(createIntExpr(s.getDevNumExpr()));
212*700637cbSDimitry Andric
213*700637cbSDimitry Andric for (Expr *QueueExpr : s.getQueueIdExprs())
214*700637cbSDimitry Andric waitOp.getWaitOperandsMutable().append(createIntExpr(QueueExpr));
215*700637cbSDimitry Andric }
216*700637cbSDimitry Andric
217*700637cbSDimitry Andric return mlir::success();
218*700637cbSDimitry Andric }
219*700637cbSDimitry Andric
emitOpenACCCombinedConstruct(const OpenACCCombinedConstruct & s)220*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCCombinedConstruct(
221*700637cbSDimitry Andric const OpenACCCombinedConstruct &s) {
222*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
223*700637cbSDimitry Andric mlir::Location end = getLoc(s.getSourceRange().getEnd());
224*700637cbSDimitry Andric
225*700637cbSDimitry Andric switch (s.getDirectiveKind()) {
226*700637cbSDimitry Andric case OpenACCDirectiveKind::ParallelLoop:
227*700637cbSDimitry Andric return emitOpenACCOpCombinedConstruct<ParallelOp, mlir::acc::YieldOp>(
228*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
229*700637cbSDimitry Andric s.getLoop());
230*700637cbSDimitry Andric case OpenACCDirectiveKind::SerialLoop:
231*700637cbSDimitry Andric return emitOpenACCOpCombinedConstruct<SerialOp, mlir::acc::YieldOp>(
232*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
233*700637cbSDimitry Andric s.getLoop());
234*700637cbSDimitry Andric case OpenACCDirectiveKind::KernelsLoop:
235*700637cbSDimitry Andric return emitOpenACCOpCombinedConstruct<KernelsOp, mlir::acc::TerminatorOp>(
236*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
237*700637cbSDimitry Andric s.getLoop());
238*700637cbSDimitry Andric default:
239*700637cbSDimitry Andric llvm_unreachable("invalid compute construct kind");
240*700637cbSDimitry Andric }
241*700637cbSDimitry Andric }
242*700637cbSDimitry Andric
emitOpenACCHostDataConstruct(const OpenACCHostDataConstruct & s)243*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCHostDataConstruct(
244*700637cbSDimitry Andric const OpenACCHostDataConstruct &s) {
245*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
246*700637cbSDimitry Andric mlir::Location end = getLoc(s.getSourceRange().getEnd());
247*700637cbSDimitry Andric
248*700637cbSDimitry Andric return emitOpenACCOpAssociatedStmt<HostDataOp, mlir::acc::TerminatorOp>(
249*700637cbSDimitry Andric start, end, s.getDirectiveKind(), s.getDirectiveLoc(), s.clauses(),
250*700637cbSDimitry Andric s.getStructuredBlock());
251*700637cbSDimitry Andric }
252*700637cbSDimitry Andric
emitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct & s)253*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCEnterDataConstruct(
254*700637cbSDimitry Andric const OpenACCEnterDataConstruct &s) {
255*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
256*700637cbSDimitry Andric emitOpenACCOp<EnterDataOp>(start, s.getDirectiveKind(), s.getDirectiveLoc(),
257*700637cbSDimitry Andric s.clauses());
258*700637cbSDimitry Andric return mlir::success();
259*700637cbSDimitry Andric }
260*700637cbSDimitry Andric
emitOpenACCExitDataConstruct(const OpenACCExitDataConstruct & s)261*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitOpenACCExitDataConstruct(
262*700637cbSDimitry Andric const OpenACCExitDataConstruct &s) {
263*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
264*700637cbSDimitry Andric emitOpenACCOp<ExitDataOp>(start, s.getDirectiveKind(), s.getDirectiveLoc(),
265*700637cbSDimitry Andric s.clauses());
266*700637cbSDimitry Andric return mlir::success();
267*700637cbSDimitry Andric }
268*700637cbSDimitry Andric
269*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCUpdateConstruct(const OpenACCUpdateConstruct & s)270*700637cbSDimitry Andric CIRGenFunction::emitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &s) {
271*700637cbSDimitry Andric mlir::Location start = getLoc(s.getSourceRange().getBegin());
272*700637cbSDimitry Andric emitOpenACCOp<UpdateOp>(start, s.getDirectiveKind(), s.getDirectiveLoc(),
273*700637cbSDimitry Andric s.clauses());
274*700637cbSDimitry Andric return mlir::success();
275*700637cbSDimitry Andric }
276*700637cbSDimitry Andric
277*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCCacheConstruct(const OpenACCCacheConstruct & s)278*700637cbSDimitry Andric CIRGenFunction::emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s) {
279*700637cbSDimitry Andric // The 'cache' directive 'may' be at the top of a loop by standard, but
280*700637cbSDimitry Andric // doesn't have to be. Additionally, there is nothing that requires this be a
281*700637cbSDimitry Andric // loop affected by an OpenACC pragma. Sema doesn't do any level of
282*700637cbSDimitry Andric // enforcement here, since it isn't particularly valuable to do so thanks to
283*700637cbSDimitry Andric // that. Instead, we treat cache as a 'noop' if there is no acc.loop to apply
284*700637cbSDimitry Andric // it to.
285*700637cbSDimitry Andric if (!activeLoopOp)
286*700637cbSDimitry Andric return mlir::success();
287*700637cbSDimitry Andric
288*700637cbSDimitry Andric mlir::acc::LoopOp loopOp = *activeLoopOp;
289*700637cbSDimitry Andric
290*700637cbSDimitry Andric mlir::OpBuilder::InsertionGuard guard(builder);
291*700637cbSDimitry Andric builder.setInsertionPoint(loopOp);
292*700637cbSDimitry Andric
293*700637cbSDimitry Andric for (const Expr *var : s.getVarList()) {
294*700637cbSDimitry Andric CIRGenFunction::OpenACCDataOperandInfo opInfo =
295*700637cbSDimitry Andric getOpenACCDataOperandInfo(var);
296*700637cbSDimitry Andric
297*700637cbSDimitry Andric auto cacheOp = builder.create<CacheOp>(
298*700637cbSDimitry Andric opInfo.beginLoc, opInfo.varValue,
299*700637cbSDimitry Andric /*structured=*/false, /*implicit=*/false, opInfo.name, opInfo.bounds);
300*700637cbSDimitry Andric
301*700637cbSDimitry Andric loopOp.getCacheOperandsMutable().append(cacheOp.getResult());
302*700637cbSDimitry Andric }
303*700637cbSDimitry Andric
304*700637cbSDimitry Andric return mlir::success();
305*700637cbSDimitry Andric }
306*700637cbSDimitry Andric
307*700637cbSDimitry Andric mlir::LogicalResult
emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct & s)308*700637cbSDimitry Andric CIRGenFunction::emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s) {
309*700637cbSDimitry Andric cgm.errorNYI(s.getSourceRange(), "OpenACC Atomic Construct");
310*700637cbSDimitry Andric return mlir::failure();
311*700637cbSDimitry Andric }
312