Skip to content

Commit 484284e

Browse files
[mlir][acc] Introduce createAndPopulate for recipe creation (#162917)
Private and firstprivate recipes can now be created and populated through the createAndPopulate method. The populating of recipe bodies is done through using the PointerLikeType and MappableType interfaces (with MappableType support still in progress). The existing create() API remains available for cases where dialects need manual recipe population (e.g., for frontend-specific semantics like default value initialization or constructor calls). Testing exercises the new API with memref types.
1 parent 5eeae08 commit 484284e

File tree

9 files changed

+627
-23
lines changed

9 files changed

+627
-23
lines changed

mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,24 @@ def OpenACC_PrivateRecipeOp
13161316
}];
13171317

13181318
let hasRegionVerifier = 1;
1319+
1320+
let extraClassDeclaration = [{
1321+
/// Creates a PrivateRecipeOp and populates its regions based on the
1322+
/// variable type as long as the type implements MappableType or
1323+
/// PointerLikeType interface. If a type implements both, the MappableType
1324+
/// API will be preferred. Returns std::nullopt if the recipe cannot be
1325+
/// created or populated. The builder's current insertion point will be used
1326+
/// and it must be a valid place for this operation to be inserted. The
1327+
/// `recipeName` must be a unique name to prevent "redefinition of symbol"
1328+
/// IR errors.
1329+
static std::optional<PrivateRecipeOp> createAndPopulate(
1330+
::mlir::OpBuilder &builder,
1331+
::mlir::Location loc,
1332+
::llvm::StringRef recipeName,
1333+
::mlir::Type varType,
1334+
::llvm::StringRef varName = "",
1335+
::mlir::ValueRange bounds = {});
1336+
}];
13191337
}
13201338

13211339
//===----------------------------------------------------------------------===//
@@ -1410,6 +1428,24 @@ def OpenACC_FirstprivateRecipeOp
14101428
}];
14111429

14121430
let hasRegionVerifier = 1;
1431+
1432+
let extraClassDeclaration = [{
1433+
/// Creates a FirstprivateRecipeOp and populates its regions based on the
1434+
/// variable type as long as the type implements MappableType or
1435+
/// PointerLikeType interface. If a type implements both, the MappableType
1436+
/// API will be preferred. Returns std::nullopt if the recipe cannot be
1437+
/// created or populated. The builder's current insertion point will be used
1438+
/// and it must be a valid place for this operation to be inserted. The
1439+
/// `recipeName` must be a unique name to prevent "redefinition of symbol"
1440+
/// IR errors.
1441+
static std::optional<FirstprivateRecipeOp> createAndPopulate(
1442+
::mlir::OpBuilder &builder,
1443+
::mlir::Location loc,
1444+
::llvm::StringRef recipeName,
1445+
::mlir::Type varType,
1446+
::llvm::StringRef varName = "",
1447+
::mlir::ValueRange bounds = {});
1448+
}];
14131449
}
14141450

14151451
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,15 @@ def OpenACC_PointerLikeTypeInterface : TypeInterface<"PointerLikeType"> {
8383
The `originalVar` parameter is optional but enables support for dynamic
8484
types (e.g., dynamic memrefs). When provided, implementations can extract
8585
runtime dimension information from the original variable to create
86-
allocations with matching dynamic sizes.
86+
allocations with matching dynamic sizes. When generating recipe bodies,
87+
`originalVar` should be the block argument representing the original
88+
variable in the recipe region.
89+
90+
The `needsFree` output parameter indicates whether the allocated memory
91+
requires explicit deallocation. Implementations should set this to true
92+
for heap allocations that need a matching deallocation operation (e.g.,
93+
alloc) and false for stack-based allocations (e.g., alloca). During
94+
recipe generation, this determines whether a destroy region is created.
8795

8896
Returns a Value representing the result of the allocation. If no value
8997
is returned, it means the allocation was not successfully generated.
@@ -94,31 +102,43 @@ def OpenACC_PointerLikeTypeInterface : TypeInterface<"PointerLikeType"> {
94102
"::mlir::Location":$loc,
95103
"::llvm::StringRef":$varName,
96104
"::mlir::Type":$varType,
97-
"::mlir::Value":$originalVar),
105+
"::mlir::Value":$originalVar,
106+
"bool &":$needsFree),
98107
/*methodBody=*/"",
99108
/*defaultImplementation=*/[{
100109
return {};
101110
}]
102111
>,
103112
InterfaceMethod<
104113
/*description=*/[{
105-
Generates deallocation operations for the pointer-like type. It deallocates
106-
the instance provided.
114+
Generates deallocation operations for the pointer-like type.
107115

108-
The `varPtr` parameter is required and must represent an instance that was
109-
previously allocated. If the current type is represented in a way that it
110-
does not capture the pointee type, `varType` must be passed in to provide
111-
the necessary type information. Nothing is generated in case the allocate
112-
is `alloca`-like.
116+
The `varToFree` parameter is required and must represent an instance
117+
that was previously allocated. When generating recipe bodies, this
118+
should be the block argument representing the private variable in the
119+
destroy region.
120+
121+
The `allocRes` parameter is optional and provides the result of the
122+
corresponding allocation from the init region. This allows implementations
123+
to inspect the allocation operation to determine the appropriate
124+
deallocation strategy. This is necessary because in recipe generation,
125+
the allocation and deallocation occur in separate regions. Dialects that
126+
use only one allocation type or can determine deallocation from type
127+
information alone may ignore this parameter.
128+
129+
The `varType` parameter must be provided if the current type does not
130+
capture the pointee type information. No deallocation is generated for
131+
stack-based allocations (e.g., alloca).
113132

114-
Returns true if deallocation was successfully generated or successfully
115-
deemed as not needed to be generated, false otherwise.
133+
Returns true if deallocation was successfully generated or determined to
134+
be unnecessary, false otherwise.
116135
}],
117136
/*retTy=*/"bool",
118137
/*methodName=*/"genFree",
119138
/*args=*/(ins "::mlir::OpBuilder &":$builder,
120139
"::mlir::Location":$loc,
121-
"::mlir::TypedValue<::mlir::acc::PointerLikeType>":$varPtr,
140+
"::mlir::TypedValue<::mlir::acc::PointerLikeType>":$varToFree,
141+
"::mlir::Value":$allocRes,
122142
"::mlir::Type":$varType),
123143
/*methodBody=*/"",
124144
/*defaultImplementation=*/[{

0 commit comments

Comments
 (0)