[Mlir-commits] [flang] [mlir] [mlir][OpenMP] Add memory effects of single op (PR #237929)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Nov 2 03:52:10 PST 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: JRP-arm
<details>
<summary>Changes</summary>
Added a new attribute for the copyprivate clause `copyprivate_assume_bounded_recipe_effects`. Applied when the copyprivate variables are of a specific type.
Add direct memory effect tests, CSE & canonicalisation tests.
Add tests for correct application of the `copyprivate_assume_bounded_recipe_effects` attribute.
AI-Assisted-by: Codex (OpenAI)
---
Patch is 28.52 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/237929.diff
9 Files Affected:
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+43-25)
- (modified) flang/test/Lower/OpenMP/compound.f90 (+7-7)
- (modified) flang/test/Lower/OpenMP/recipe-memory-effects.f90 (+199)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td (+15-5)
- (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td (+6-4)
- (modified) mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp (+42-7)
- (modified) mlir/test/Dialect/OpenMP/canonicalize.mlir (+28)
- (modified) mlir/test/Dialect/OpenMP/cse.mlir (+21)
- (modified) mlir/test/Dialect/OpenMP/memory-effects.mlir (+84)
``````````diff
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 98a0a54ad2a6f2..63ebe6224bea4b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1858,6 +1858,30 @@ struct OpWithBodyGenInfo {
int collapseValue = 0;
};
+static bool isNonDerivedNonPointer(const semantics::Symbol &sym) {
+ const auto &ultimate = sym.GetUltimate();
+ const auto *type = ultimate.GetType();
+ return type && type->AsIntrinsic() && !semantics::IsAllocatable(ultimate) &&
+ !semantics::IsPointer(ultimate);
+}
+
+static bool isNonDerivedNonPointer(const mlir::Value &variable) {
+ return !fir::isAllocatableType(variable.getType()) &&
+ !fir::isa_derived(fir::getFortranElementType(variable.getType())) &&
+ !fir::isPointerType(variable.getType());
+}
+
+static bool isNonDerivedNonPointerItem(const semantics::Symbol &sym) {
+ const auto &ultimate = sym.GetUltimate();
+ if (const auto *common =
+ ultimate.detailsIf<semantics::CommonBlockDetails>()) {
+ return llvm::all_of(common->objects(), [](const auto &member) {
+ return isNonDerivedNonPointer(*member);
+ });
+ }
+ return isNonDerivedNonPointer(ultimate);
+}
+
/// Create the body (block) for an OpenMP Operation.
///
/// \param [in] op - the operation the body belongs to.
@@ -1926,6 +1950,17 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info,
Fortran::lower::omp::isLastItemInQueue(item, queue),
/*useDelayedPrivatization=*/false, info.symTable);
tempDsp->processStep1();
+
+ // TODO: omp.single still uses eager privatisation.
+ // Use clauseOps.privateVars inside genSingleOp once
+ // delayedPrivatization is turned on.
+ if (auto singleOp = llvm::dyn_cast<mlir::omp::SingleOp>(op)) {
+ const auto &privateSyms = tempDsp->getAllSymbolsToPrivatize();
+ if (llvm::all_of(privateSyms, [](const semantics::Symbol *sym) {
+ return isNonDerivedNonPointerItem(*sym);
+ }))
+ singleOp.setPrivateAssumeBoundedRecipeEffects(true);
+ }
}
if (info.dir == llvm::omp::Directive::OMPD_parallel) {
@@ -3564,30 +3599,6 @@ findEnclosingParallelOp(fir::FirOpBuilder &builder) {
return {};
}
-static bool isNonDerivedNonPointer(const semantics::Symbol &sym) {
- const auto &ultimate = sym.GetUltimate();
- const auto *type = ultimate.GetType();
- return type && type->AsIntrinsic() && !semantics::IsAllocatable(ultimate) &&
- !semantics::IsPointer(ultimate);
-}
-
-static bool isNonDerivedNonPointer(const mlir::Value &variable) {
- return !fir::isAllocatableType(variable.getType()) &&
- !fir::isa_derived(fir::getFortranElementType(variable.getType())) &&
- !fir::isPointerType(variable.getType());
-}
-
-static bool isNonDerivedNonPointerItem(const semantics::Symbol &sym) {
- const auto &ultimate = sym.GetUltimate();
- if (const auto *common =
- ultimate.detailsIf<semantics::CommonBlockDetails>()) {
- return llvm::all_of(common->objects(), [](const auto &member) {
- return isNonDerivedNonPointer(*member);
- });
- }
- return isNonDerivedNonPointer(ultimate);
-}
-
static mlir::omp::SectionsOp
genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
@@ -3945,11 +3956,18 @@ genSingleOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
mlir::omp::SingleOperands clauseOps;
genSingleClauses(converter, semaCtx, item->clauses, loc, clauseOps);
- return genOpWithBody<mlir::omp::SingleOp>(
+ auto singleOp = genOpWithBody<mlir::omp::SingleOp>(
OpWithBodyGenInfo(converter, symTable, semaCtx, loc, eval,
llvm::omp::Directive::OMPD_single)
.setClauses(&item->clauses),
queue, item, clauseOps);
+
+ if (llvm::all_of(clauseOps.copyprivateVars, [](mlir::Value variable) {
+ return isNonDerivedNonPointer(variable);
+ }))
+ singleOp.setCopyprivateAssumeBoundedRecipeEffects(true);
+
+ return singleOp;
}
static bool isDuplicateMappedSymbol(
diff --git a/flang/test/Lower/OpenMP/compound.f90 b/flang/test/Lower/OpenMP/compound.f90
index d61745345a6405..f06edf36244e5e 100644
--- a/flang/test/Lower/OpenMP/compound.f90
+++ b/flang/test/Lower/OpenMP/compound.f90
@@ -784,7 +784,7 @@ subroutine single_loop()
! CHECK-NEXT: }
! CHECK-NOT: omp.combined
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine single_parallel()
implicit none
@@ -803,7 +803,7 @@ subroutine single_parallel()
! CHECK-NEXT: }
! CHECK-NOT: omp.combined
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine single_simd()
implicit none
@@ -825,7 +825,7 @@ subroutine single_simd()
! CHECK-NEXT: }
! CHECK-NOT: omp.combined
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine single_target()
implicit none
@@ -844,7 +844,7 @@ subroutine single_target()
! CHECK-NEXT: }
! CHECK-NOT: omp.combined
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine single_target_data()
implicit none
@@ -864,7 +864,7 @@ subroutine single_target_data()
! CHECK-NEXT: }
! CHECK-NOT: omp.combined
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine single_task()
implicit none
@@ -883,7 +883,7 @@ subroutine single_task()
! CHECK-NEXT: }
! CHECK-NOT: omp.combined
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine single_taskloop()
implicit none
@@ -908,7 +908,7 @@ subroutine single_taskloop()
! CHECK: omp.terminator
! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
! CHECK: omp.terminator
-! CHECK-NEXT: } {{{.*}}omp.combined{{.*}}}
+! CHECK-NEXT: }{{.*}} {{{.*}}omp.combined{{.*}}}
subroutine target_task()
implicit none
diff --git a/flang/test/Lower/OpenMP/recipe-memory-effects.f90 b/flang/test/Lower/OpenMP/recipe-memory-effects.f90
index 631906ee7b45ba..1e4d748492e2ea 100644
--- a/flang/test/Lower/OpenMP/recipe-memory-effects.f90
+++ b/flang/test/Lower/OpenMP/recipe-memory-effects.f90
@@ -158,4 +158,203 @@ subroutine derived_common_private()
z%value = x
!$omp end sections
end subroutine
+
+ ! Eager privatisation emits the privatisation recipe inside the single
+ ! region, preventing getEffects() from providing its memory effects.
+ ! Make sure these are emitted so recursive analyis records their memory
+ ! effects.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPsingle_eager_firstprivate(
+ ! CHECK: %[[ORIGINAL:.*]] = fir.alloca i32
+ ! CHECK: %[[ORIGINAL_DECL:.*]]:2 = hlfir.declare %[[ORIGINAL]]
+ ! CHECK: omp.parallel {
+ ! CHECK-NEXT: omp.single {
+ ! CHECK-NEXT: %[[PRIVATE:.*]] = fir.alloca i32
+ ! CHECK-NEXT: %[[PRIVATE_DECL:.*]]:2 = hlfir.declare %[[PRIVATE]]
+ ! CHECK-NEXT: %[[INITIAL:.*]] = fir.load %[[ORIGINAL_DECL]]#0 : !fir.ref<i32>
+ ! CHECK-NEXT: hlfir.assign %[[INITIAL]] to %[[PRIVATE_DECL]]#0 : i32, !fir.ref<i32>
+ ! CHECK-NEXT: %[[VALUE:.*]] = fir.load %[[PRIVATE_DECL]]#0 : !fir.ref<i32>
+ ! CHECK-NEXT: %[[ONE:.*]] = arith.constant 1 : i32
+ ! CHECK-NEXT: %[[UPDATED:.*]] = arith.addi %[[VALUE]], %[[ONE]] : i32
+ ! CHECK-NEXT: hlfir.assign %[[UPDATED]] to %[[PRIVATE_DECL]]#0 : i32, !fir.ref<i32>
+ ! CHECK-NEXT: omp.terminator
+ ! CHECK-NEXT: } <copyprivate_assume_bounded_recipe_effects, private_assume_bounded_recipe_effects>
+ ! CHECK-NEXT: omp.terminator
+ ! CHECK-NEXT: }
+ ! CHECK-NEXT: %[[AFTER:.*]] = fir.load %[[ORIGINAL_DECL]]#0 : !fir.ref<i32>
+ ! CHECK-NEXT: hlfir.assign %[[AFTER]] to %{{.*}} : i32, !fir.ref<i32>
+ ! CHECK-NEXT: return
+ subroutine single_eager_firstprivate(result)
+ integer :: result, x
+ x = 10
+ !$omp parallel shared(x)
+ !$omp single firstprivate(x)
+ x = x + 1
+ !$omp end single
+ !$omp end parallel
+ result = x
+ end subroutine
+
+ ! Eager single privatization maps COMMON members rather than the block.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPsingle_intrinsic_common_private(
+ ! CHECK: omp.single {
+ ! CHECK: } <copyprivate_assume_bounded_recipe_effects, private_assume_bounded_recipe_effects>
+ ! CHECK: return
+ subroutine single_intrinsic_common_private()
+ integer :: x
+ real :: y
+ common /single_private_block/ x, y
+ !$omp single private(/single_private_block/)
+ x = 1
+ y = 1.0
+ !$omp end single
+ end subroutine
+
+ ! Firstprivate COMMON blocks must also be checked member by member.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPsingle_intrinsic_common_firstprivate(
+ ! CHECK: omp.single {
+ ! CHECK: } <copyprivate_assume_bounded_recipe_effects, private_assume_bounded_recipe_effects>
+ ! CHECK: return
+ subroutine single_intrinsic_common_firstprivate()
+ integer :: x
+ real :: y
+ common /single_firstprivate_block/ x, y
+ !$omp single firstprivate(/single_firstprivate_block/)
+ x = x + 1
+ y = y + 1.0
+ !$omp end single
+ end subroutine
+
+ ! One derived member prevents the assumption for the entire COMMON block.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPsingle_derived_common_private(
+ ! CHECK: omp.single {
+ ! CHECK-NOT: private_assume_bounded_recipe_effects
+ ! CHECK: } <copyprivate_assume_bounded_recipe_effects>
+ ! CHECK: return
+ subroutine single_derived_common_private()
+ integer :: x
+ type(record) :: z
+ common /single_derived_block/ x, z
+ !$omp single private(/single_derived_block/)
+ x = 1
+ z%value = x
+ !$omp end single
+ end subroutine
+
+ ! Direct intrinsic scalars and fixed-size arrays have bounded copy functions.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPintrinsic_copyprivate(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine intrinsic_copyprivate()
+ integer :: i, a(4)
+ real :: r
+ complex :: c
+ logical :: l
+ character(8) :: s
+ !$omp parallel private(i, a, r, c, l, s)
+ !$omp single
+ !$omp end single copyprivate(i, a, r, c, l, s)
+ !$omp end parallel
+ end subroutine
+
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPno_copyprivate(
+ ! CHECK: omp.single {
+ ! CHECK: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine no_copyprivate()
+ !$omp single
+ !$omp end single
+ end subroutine
+
+ ! Copyprivate and private make independent assumptions.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPbounded_copyprivate_derived_private(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine bounded_copyprivate_derived_private()
+ type record
+ integer :: value
+ end type
+ type(record) :: z
+ integer :: i
+ !$omp parallel private(i)
+ !$omp single private(z)
+ !$omp end single copyprivate(i)
+ !$omp end parallel
+ end subroutine
+
+ ! One derived item prevents the assumption for the entire copyprivate clause.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPderived_copyprivate_bounded_private(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK-NOT: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: } <private_assume_bounded_recipe_effects>
+ ! CHECK: return
+ subroutine derived_copyprivate_bounded_private()
+ type record
+ integer :: value
+ end type
+ type(record) :: z
+ integer :: i, p
+ !$omp parallel private(i, z)
+ !$omp single private(p)
+ !$omp end single copyprivate(i, z)
+ !$omp end parallel
+ end subroutine
+
+ ! Allocatable copies may allocate, free, and access pointee storage.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPallocatable_scalar_copyprivate(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK-NOT: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine allocatable_scalar_copyprivate()
+ integer, allocatable :: a
+ !$omp parallel private(a)
+ !$omp single
+ !$omp end single copyprivate(a)
+ !$omp end parallel
+ end subroutine
+
+ ! Allocatables may access pointees of the copyprivate variable, violating the
+ ! copyprivate_assume_bounded_recipe_effects attribute contract.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPallocatable_array_copyprivate(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK-NOT: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine allocatable_array_copyprivate()
+ integer, allocatable :: a(:)
+ !$omp parallel private(a)
+ !$omp single
+ !$omp end single copyprivate(a)
+ !$omp end parallel
+ end subroutine
+
+ ! Pointer variables may access pointees of the copyprivate variable, violating
+ ! the copyprivate_assume_bounded_recipe_effects attribute contract.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPpointer_copyprivate(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK-NOT: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine pointer_copyprivate()
+ integer, pointer :: p, a(:)
+ !$omp parallel private(p, a)
+ !$omp single
+ !$omp end single copyprivate(p, a)
+ !$omp end parallel
+ end subroutine
+
+ ! Check the members of a threadprivate COMMON block.
+ ! CHECK-LABEL: func.func @_QMrecipe_memory_effectsPintrinsic_common_copyprivate(
+ ! CHECK: omp.single copyprivate(
+ ! CHECK: copyprivate_assume_bounded_recipe_effects
+ ! CHECK: return
+ subroutine intrinsic_common_copyprivate()
+ integer :: i
+ real :: r
+ common /intrinsic_copy_block/ i, r
+ !$omp threadprivate(/intrinsic_copy_block/)
+ !$omp parallel
+ !$omp single
+ !$omp end single copyprivate(/intrinsic_copy_block/)
+ !$omp end parallel
+ end subroutine
end module
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index ab6e7178c9f2e9..eddd4fde2cd6bd 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -241,13 +241,16 @@ def OpenMP_CollapseClause : OpenMP_CollapseClauseSkip<>;
class OpenMP_CopyprivateClauseSkip<
bit traits = false, bit arguments = false, bit assemblyFormat = false,
- bit description = false, bit extraClassDeclaration = false
+ bit description = false, bit extraClassDeclaration = false,
+ bit boundedRecipeEffects = false
> : OpenMP_Clause<traits, arguments, assemblyFormat, description,
extraClassDeclaration> {
- let arguments = (ins
+ let arguments = !con((ins
Variadic<OpenMP_PointerLikeType>:$copyprivate_vars,
OptionalAttr<SymbolRefArrayAttr>:$copyprivate_syms
- );
+ ), !if(boundedRecipeEffects, (ins
+ UnitAttr:$copyprivate_assume_bounded_recipe_effects
+ ), (ins)));
let optAssemblyFormat = [{
`copyprivate` `(`
@@ -259,6 +262,15 @@ class OpenMP_CopyprivateClauseSkip<
If `copyprivate` variables and functions are specified, then each thread
variable is updated with the variable value of the thread that executed
the single region, using the specified copy functions.
+
+ The optional `copyprivate_assume_bounded_recipe_effects` unit attribute
+ asserts that referenced copyprivatisation recipes may only read or write
+ `copyprivate` variables associated with the clause.
+ These effects apply only to storage directly designated by the `copyprivate`
+ variables. Recipes may not access other storage, including globals or
+ pointees reached by loading pointers from these variables. Without the
+ attribute, referenced copy functions are assumed to have arbitrary memory
+ effects.
}];
}
@@ -1515,7 +1527,6 @@ def OpenMP_PriorityClause : OpenMP_PriorityClauseSkip<>;
class OpenMP_PrivateClauseSkip<
bit traits = false, bit arguments = false, bit assemblyFormat = false,
bit description = false, bit extraClassDeclaration = false,
- // Only sections currently consumes the recipe-effect assumption.
bit boundedRecipeEffects = false
> : OpenMP_Clause<traits, arguments, assemblyFormat, description,
extraClassDeclaration> {
@@ -1584,7 +1595,6 @@ def OpenMP_ProcBindClause : OpenMP_ProcBindClauseSkip<>;
class OpenMP_ReductionClauseSkip<
bit traits = false, bit arguments = false, bit assemblyFormat = false,
bit description = false, bit extraClassDeclaration = false,
- // Only sections currently consumes the recipe-effect assumption.
bit boundedRecipeEffects = false
> : OpenMP_Clause<traits, arguments, assemblyFormat, description,
extraClassDeclaration> {
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index d08b27b90ede5c..021ed0ce7d35e8 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -370,10 +370,12 @@ def SectionsOp : OpenMP_Op<"sections", traits = [
//===----------------------------------------------------------------------===//
def SingleOp : OpenMP_Op<"single", traits = [
- AttrSizedOperandSegments, DeclareOpInterfaceMethods<ComposableOpInterface>
+ AttrSizedOperandSegments, DeclareOpInterfaceMethods<ComposableOpInterface>,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>, RecursiveMemoryEffects
], clauses = [
- OpenMP_AllocateClause, OpenMP_CopyprivateClause, OpenMP_NowaitClause,
- OpenMP_PrivateClause
+ OpenMP_AllocateClause,
+ OpenMP_CopyprivateClauseSkip<boundedRecipeEffects = true>, OpenMP_NowaitClause,
+ OpenMP_PrivateClauseSkip<boundedRecipeEffects = true>
], singleRegion = true> {
let summary = "single directive";
let description = [{
@@ -390,7 +392,7 @@ def SingleOp : OpenMP_Op<"single", traits = [
let assemblyFormat = clausesAssemblyFormat # [{
custom<PrivateRegion>($region, $private_vars, type($private_vars),
- $private_syms, $private_needs_barrier) attr-dict
+ $private_syms, $private_needs_barrier) prop-dict attr-dict
}];
let hasVerifier = 1;
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 1c869ad04bbcf6..7e2d94e8f74c0b 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -3594,13 +3594,15 @@ void SingleOp::build(OpBuilder &builder, OperationState &state,
const SingleOperands &clauses) {
MLIRContext *ctx = builder.getContext();
// TODO Store clauses in op: privateVars, privateSyms, privateNeedsBarrier
- SingleOp::build(builder, state, clauses.allocateVars, clauses.allocatorVars,
- makeDenseI64ArrayAttr(ctx, clauses.allocateAlignments),
- makeDenseI64ArrayAttr(ctx, clauses.allocatePrivateIndices),
- clauses.copyprivateVars,
- makeArrayAttr(ctx, clauses.copyprivateSyms), clauses.nowait,
- /*private_vars=*/{}, /*private_syms=*/nullptr,
- /*private_needs_barrier=*/nullptr);
+ SingleOp::build(
+ builder, state, clauses.allocateVars, clauses.allocatorVars,
+ makeDenseI64ArrayAttr(ctx, clauses.allocateAlignments),
+ makeDenseI64ArrayAttr(ctx, clauses.allocatePrivateIndices),
+ clauses.copyprivateVars, makeArrayAttr(ctx, clauses.copyprivateSyms),
+ /*copyprivate_assume_bounded_recipe_effects=*/nullptr, clauses.nowait,
+ /*private_vars=*/{}, /*private_syms=*/nullptr,
+ /*private_needs_barrier=*/nullptr,
+ /*private_assume_bounded_recipe_effects=*/nullptr);
}
LogicalResult SingleOp::verify() {
@@ -3614,6 +3616,39 @@ LogicalResult SingleOp::verify() {
getCopyprivateSyms());
}
+void SingleOp::getEffects(
+ llvm::SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
+ &effects) {
+ // The presence of the nowait cl...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/237929
More information about the Mlir-commits
mailing list