clang 22.0.0git
CIRGenDeclOpenACC.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code to emit Decl nodes as CIR code.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenFunction.h"
14#include "mlir/Dialect/OpenACC/OpenACC.h"
16
17using namespace clang;
18using namespace clang::CIRGen;
19
20namespace {
21struct OpenACCDeclareCleanup final : EHScopeStack::Cleanup {
22 SourceRange declareRange;
23 mlir::acc::DeclareEnterOp enterOp;
24
25 OpenACCDeclareCleanup(SourceRange declareRange,
26 mlir::acc::DeclareEnterOp enterOp)
27 : declareRange(declareRange), enterOp(enterOp) {}
28
29 template <typename OutTy, typename InTy>
30 void createOutOp(CIRGenFunction &cgf, InTy inOp) {
31 if constexpr (std::is_same_v<OutTy, mlir::acc::DeleteOp>) {
32 auto outOp =
33 OutTy::create(cgf.getBuilder(), inOp.getLoc(), inOp,
34 inOp.getStructured(), inOp.getImplicit(),
35 llvm::Twine(inOp.getNameAttr()), inOp.getBounds());
36 outOp.setDataClause(inOp.getDataClause());
37 outOp.setModifiers(inOp.getModifiers());
38 } else {
39 auto outOp =
40 OutTy::create(cgf.getBuilder(), inOp.getLoc(), inOp, inOp.getVarPtr(),
41 inOp.getStructured(), inOp.getImplicit(),
42 llvm::Twine(inOp.getNameAttr()), inOp.getBounds());
43 outOp.setDataClause(inOp.getDataClause());
44 outOp.setModifiers(inOp.getModifiers());
45 }
46 }
47
48 void emit(CIRGenFunction &cgf) override {
49 auto exitOp = mlir::acc::DeclareExitOp::create(
50 cgf.getBuilder(), enterOp.getLoc(), enterOp, {});
51
52 // Some data clauses need to be referenced in 'exit', AND need to have an
53 // operation after the exit. Copy these from the enter operation.
54 for (mlir::Value val : enterOp.getDataClauseOperands()) {
55 if (auto copyin = val.getDefiningOp<mlir::acc::CopyinOp>()) {
56 switch (copyin.getDataClause()) {
57 default:
58 cgf.cgm.errorNYI(declareRange,
59 "OpenACC local declare clause copyin cleanup");
60 break;
61 case mlir::acc::DataClause::acc_copy:
62 createOutOp<mlir::acc::CopyoutOp>(cgf, copyin);
63 break;
64 case mlir::acc::DataClause::acc_copyin:
65 createOutOp<mlir::acc::DeleteOp>(cgf, copyin);
66 break;
67 }
68 } else if (auto create = val.getDefiningOp<mlir::acc::CreateOp>()) {
69 switch (create.getDataClause()) {
70 default:
71 cgf.cgm.errorNYI(declareRange,
72 "OpenACC local declare clause create cleanup");
73 break;
74 case mlir::acc::DataClause::acc_copyout:
75 createOutOp<mlir::acc::CopyoutOp>(cgf, create);
76 break;
77 }
78 } else if (val.getDefiningOp<mlir::acc::DeclareLinkOp>()) {
79 // Link has no exit clauses, and shouldn't be copied.
80 continue;
81 } else if (val.getDefiningOp<mlir::acc::DevicePtrOp>()) {
82 // DevicePtr has no exit clauses, and shouldn't be copied.
83 continue;
84 } else {
85 cgf.cgm.errorNYI(declareRange, "OpenACC local declare clause cleanup");
86 continue;
87 }
88 exitOp.getDataClauseOperandsMutable().append(val);
89 }
90 }
91};
92} // namespace
93
95 mlir::Location exprLoc = cgm.getLoc(d.getBeginLoc());
96 auto enterOp = mlir::acc::DeclareEnterOp::create(
97 builder, exprLoc, mlir::acc::DeclareTokenType::get(&cgm.getMLIRContext()),
98 {});
99
100 emitOpenACCClauses(enterOp, OpenACCDirectiveKind::Declare, d.getBeginLoc(),
101 d.clauses());
102
103 ehStack.pushCleanup<OpenACCDeclareCleanup>(CleanupKind::NormalCleanup,
104 d.getSourceRange(), enterOp);
105}
106
108 getCIRGenModule().errorNYI(d.getSourceRange(), "OpenACC Routine Construct");
109}
110
113 errorNYI(d->getSourceRange(), "OpenACC Routine Construct");
114 else if (isa<OpenACCDeclareDecl>(d))
115 errorNYI(d->getSourceRange(), "OpenACC Declare Construct");
116 else
117 llvm_unreachable("unknown OpenACC declaration kind?");
118}
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
This file defines OpenACC nodes for declarative directives.
void emitOpenACCRoutine(const OpenACCRoutineDecl &d)
void emitOpenACCDeclare(const OpenACCDeclareDecl &d)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
CIRGenBuilderTy & getBuilder()
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:431
ArrayRef< const OpenACCClause * > clauses() const
Definition DeclOpenACC.h:62
virtual SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition DeclOpenACC.h:58
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330