diff options
author | Erich Keane <ekeane@nvidia.com> | 2025-05-09 09:29:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-09 09:29:46 -0700 |
commit | 6ff3b8e5b5757ab2c43913e98c16138a0e23d647 (patch) | |
tree | 8283373b69542be1af687cc51fef2cdc196f0659 /clang/lib | |
parent | 98181200db2af6e0aa43318d11c5c37e65c72845 (diff) | |
download | llvm-6ff3b8e5b5757ab2c43913e98c16138a0e23d647.zip llvm-6ff3b8e5b5757ab2c43913e98c16138a0e23d647.tar.gz llvm-6ff3b8e5b5757ab2c43913e98c16138a0e23d647.tar.bz2 |
[OpenACC][CIR] Impl default/seq lowering for combined constructs (#139263)
This adds two clauses plus the infrastructure for emitting the clauses
on combined constructs. Combined constructs require two operations, so
this makes sure we emit on the 'correct' one. It DOES require that the
combined construct handling picks the correct one to put it on, AND sets
up the 'inserter' correctly, but these two clauses don't require an
inserter, so a future patch will get those.
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h | 51 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp | 9 |
2 files changed, 55 insertions, 5 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h index 686bd32..e3a69ba 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h @@ -23,9 +23,25 @@ constexpr bool isOneOfTypes = template <typename ToTest, typename T> constexpr bool isOneOfTypes<ToTest, T> = std::is_same_v<ToTest, T>; +// Holds information for emitting clauses for a combined construct. We +// instantiate the clause emitter with this type so that it can use +// if-constexpr to specially handle these. +template <typename CompOpTy> struct CombinedConstructClauseInfo { + using ComputeOpTy = CompOpTy; + ComputeOpTy computeOp; + mlir::acc::LoopOp loopOp; +}; + +template <typename ToTest> constexpr bool isCombinedType = false; +template <typename T> +constexpr bool isCombinedType<CombinedConstructClauseInfo<T>> = true; + template <typename OpTy> class OpenACCClauseCIREmitter final : public OpenACCClauseVisitor<OpenACCClauseCIREmitter<OpTy>> { + // Necessary for combined constructs. + template <typename FriendOpTy> friend class OpenACCClauseCIREmitter; + OpTy &operation; CIRGen::CIRGenFunction &cgf; CIRGen::CIRGenBuilderTy &builder; @@ -119,6 +135,26 @@ class OpenACCClauseCIREmitter final llvm_unreachable("unknown gang kind"); } + template <typename U = void, + typename = std::enable_if_t<isCombinedType<OpTy>, U>> + void applyToLoopOp(const OpenACCClause &c) { + // TODO OpenACC: we have to set the insertion scope here correctly still. + OpenACCClauseCIREmitter<mlir::acc::LoopOp> loopEmitter{ + operation.loopOp, cgf, builder, dirKind, dirLoc}; + loopEmitter.lastDeviceTypeValues = lastDeviceTypeValues; + loopEmitter.Visit(&c); + } + + template <typename U = void, + typename = std::enable_if_t<isCombinedType<OpTy>, U>> + void applyToComputeOp(const OpenACCClause &c) { + // TODO OpenACC: we have to set the insertion scope here correctly still. + OpenACCClauseCIREmitter<typename OpTy::ComputeOpTy> computeEmitter{ + operation.computeOp, cgf, builder, dirKind, dirLoc}; + computeEmitter.lastDeviceTypeValues = lastDeviceTypeValues; + computeEmitter.Visit(&c); + } + public: OpenACCClauseCIREmitter(OpTy &operation, CIRGen::CIRGenFunction &cgf, CIRGen::CIRGenBuilderTy &builder, @@ -145,10 +181,10 @@ public: case OpenACCDefaultClauseKind::Invalid: break; } + } else if constexpr (isCombinedType<OpTy>) { + applyToComputeOp(clause); } else { - // TODO: When we've implemented this for everything, switch this to an - // unreachable. Combined constructs remain. - return clauseNotImplemented(clause); + llvm_unreachable("Unknown construct kind in VisitDefaultClause"); } } @@ -175,9 +211,12 @@ public: // Nothing to do here, these constructs don't have any IR for these, as // they just modify the other clauses IR. So setting of // `lastDeviceTypeValues` (done above) is all we need. + } else if constexpr (isCombinedType<OpTy>) { + // Nothing to do here either, combined constructs are just going to use + // 'lastDeviceTypeValues' to set the value for the child visitor. } else { // TODO: When we've implemented this for everything, switch this to an - // unreachable. update, data, routine, combined constructs remain. + // unreachable. update, data, routine constructs remain. return clauseNotImplemented(clause); } } @@ -334,9 +373,11 @@ public: void VisitSeqClause(const OpenACCSeqClause &clause) { if constexpr (isOneOfTypes<OpTy, mlir::acc::LoopOp>) { operation.addSeq(builder.getContext(), lastDeviceTypeValues); + } else if constexpr (isCombinedType<OpTy>) { + applyToLoopOp(clause); } else { // TODO: When we've implemented this for everything, switch this to an - // unreachable. Routine, Combined constructs remain. + // unreachable. Routine construct remains. return clauseNotImplemented(clause); } } diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp index cc2470b..fc76f57 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp @@ -109,6 +109,15 @@ mlir::LogicalResult CIRGenFunction::emitOpenACCOpCombinedConstruct( builder.create<mlir::acc::YieldOp>(end); } + { + mlir::OpBuilder::InsertionGuard guardCase(builder); + CombinedConstructClauseInfo<Op> inf{computeOp, loopOp}; + // We don't bother setting the insertion point, since the clause emitter + // is going to have to do this correctly. + makeClauseEmitter(inf, *this, builder, dirKind, dirLoc) + .VisitClauseList(clauses); + } + builder.create<TermOp>(end); } |