Skip to content

Commit c1ed45a

Browse files
authored
[mlir] Add global and program memory space handling to the data layout subsystem (#77367)
This patch is based on a previous PR https://reviews.llvm.org/D144657 that added alloca address space handling to MLIR's DataLayout and DLTI interface. This patch aims to add identical features to import and access the global and program memory space through MLIR's DataLayout/DLTI system.
1 parent d9710d7 commit c1ed45a

File tree

12 files changed

+250
-8
lines changed

12 files changed

+250
-8
lines changed

mlir/include/mlir/Dialect/DLTI/DLTI.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ class DataLayoutSpecAttr
103103
/// Returns the alloca memory space identifier.
104104
StringAttr getAllocaMemorySpaceIdentifier(MLIRContext *context) const;
105105

106+
/// Returns the program memory space identifier.
107+
StringAttr getProgramMemorySpaceIdentifier(MLIRContext *context) const;
108+
109+
/// Returns the global memory space identifier.
110+
StringAttr getGlobalMemorySpaceIdentifier(MLIRContext *context) const;
111+
106112
/// Returns the stack alignment identifier.
107113
StringAttr getStackAlignmentIdentifier(MLIRContext *context) const;
108114

mlir/include/mlir/Dialect/DLTI/DLTIBase.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ def DLTI_Dialect : Dialect {
3939

4040
constexpr const static ::llvm::StringLiteral
4141
kDataLayoutAllocaMemorySpaceKey = "dlti.alloca_memory_space";
42+
43+
constexpr const static ::llvm::StringLiteral
44+
kDataLayoutProgramMemorySpaceKey = "dlti.program_memory_space";
45+
46+
constexpr const static ::llvm::StringLiteral
47+
kDataLayoutGlobalMemorySpaceKey = "dlti.global_memory_space";
4248

4349
constexpr const static ::llvm::StringLiteral
4450
kDataLayoutStackAlignmentKey = "dlti.stack_alignment";

mlir/include/mlir/Interfaces/DataLayoutInterfaces.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ getDefaultPreferredAlignment(Type type, const DataLayout &dataLayout,
6161
/// DataLayoutInterface if specified, otherwise returns the default.
6262
Attribute getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry);
6363

64+
/// Default handler for program memory space request. Dispatches to the
65+
/// DataLayoutInterface if specified, otherwise returns the default.
66+
Attribute getDefaultProgramMemorySpace(DataLayoutEntryInterface entry);
67+
68+
/// Default handler for global memory space request. Dispatches to the
69+
/// DataLayoutInterface if specified, otherwise returns the default.
70+
Attribute getDefaultGlobalMemorySpace(DataLayoutEntryInterface entry);
71+
6472
/// Default handler for the stack alignment request. Dispatches to the
6573
/// DataLayoutInterface if specified, otherwise returns the default.
6674
uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry);
@@ -175,6 +183,12 @@ class DataLayout {
175183
/// Returns the memory space used for AllocaOps.
176184
Attribute getAllocaMemorySpace() const;
177185

186+
/// Returns the memory space used for program memory operations.
187+
Attribute getProgramMemorySpace() const;
188+
189+
/// Returns the memory space used for global operations.
190+
Attribute getGlobalMemorySpace() const;
191+
178192
/// Returns the natural alignment of the stack in bits. Alignment promotion of
179193
/// stack variables should be limited to the natural stack alignment to
180194
/// prevent dynamic stack alignment. Returns zero if the stack alignment is
@@ -203,8 +217,10 @@ class DataLayout {
203217
mutable DenseMap<Type, uint64_t> abiAlignments;
204218
mutable DenseMap<Type, uint64_t> preferredAlignments;
205219

206-
/// Cache for alloca memory space.
220+
/// Cache for alloca, global, and program memory spaces.
207221
mutable std::optional<Attribute> allocaMemorySpace;
222+
mutable std::optional<Attribute> programMemorySpace;
223+
mutable std::optional<Attribute> globalMemorySpace;
208224

209225
/// Cache for stack alignment.
210226
mutable std::optional<uint64_t> stackAlignment;

mlir/include/mlir/Interfaces/DataLayoutInterfaces.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ def DataLayoutSpecInterface : AttrInterface<"DataLayoutSpecInterface"> {
112112
/*methodName=*/"getAllocaMemorySpaceIdentifier",
113113
/*args=*/(ins "::mlir::MLIRContext *":$context)
114114
>,
115+
InterfaceMethod<
116+
/*description=*/"Returns the program memory space identifier.",
117+
/*retTy=*/"::mlir::StringAttr",
118+
/*methodName=*/"getProgramMemorySpaceIdentifier",
119+
/*args=*/(ins "::mlir::MLIRContext *":$context)
120+
>,
121+
InterfaceMethod<
122+
/*description=*/"Returns the global memory space identifier.",
123+
/*retTy=*/"::mlir::StringAttr",
124+
/*methodName=*/"getGlobalMemorySpaceIdentifier",
125+
/*args=*/(ins "::mlir::MLIRContext *":$context)
126+
>,
115127
InterfaceMethod<
116128
/*description=*/"Returns the stack alignment identifier.",
117129
/*retTy=*/"::mlir::StringAttr",
@@ -280,6 +292,30 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
280292
return ::mlir::detail::getDefaultAllocaMemorySpace(entry);
281293
}]
282294
>,
295+
StaticInterfaceMethod<
296+
/*description=*/"Returns the memory space used by the ABI computed "
297+
"using the relevant entries. The data layout object "
298+
"can be used for recursive queries.",
299+
/*retTy=*/"::mlir::Attribute",
300+
/*methodName=*/"getProgramMemorySpace",
301+
/*args=*/(ins "::mlir::DataLayoutEntryInterface":$entry),
302+
/*methodBody=*/"",
303+
/*defaultImplementation=*/[{
304+
return ::mlir::detail::getDefaultProgramMemorySpace(entry);
305+
}]
306+
>,
307+
StaticInterfaceMethod<
308+
/*description=*/"Returns the memory space used by the ABI computed "
309+
"using the relevant entries. The data layout object "
310+
"can be used for recursive queries.",
311+
/*retTy=*/"::mlir::Attribute",
312+
/*methodName=*/"getGlobalMemorySpace",
313+
/*args=*/(ins "::mlir::DataLayoutEntryInterface":$entry),
314+
/*methodBody=*/"",
315+
/*defaultImplementation=*/[{
316+
return ::mlir::detail::getDefaultGlobalMemorySpace(entry);
317+
}]
318+
>,
283319
StaticInterfaceMethod<
284320
/*description=*/"Returns the natural stack alignment in bits computed "
285321
"using the relevant entries. The data layout object "

mlir/lib/Dialect/DLTI/DLTI.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ void DataLayoutEntryAttr::print(AsmPrinter &os) const {
108108
constexpr const StringLiteral mlir::DataLayoutSpecAttr::kAttrKeyword;
109109
constexpr const StringLiteral
110110
mlir::DLTIDialect::kDataLayoutAllocaMemorySpaceKey;
111+
constexpr const StringLiteral
112+
mlir::DLTIDialect::kDataLayoutProgramMemorySpaceKey;
113+
constexpr const StringLiteral
114+
mlir::DLTIDialect::kDataLayoutGlobalMemorySpaceKey;
115+
111116
constexpr const StringLiteral mlir::DLTIDialect::kDataLayoutStackAlignmentKey;
112117

113118
namespace mlir {
@@ -282,6 +287,17 @@ DataLayoutSpecAttr::getAllocaMemorySpaceIdentifier(MLIRContext *context) const {
282287
DLTIDialect::kDataLayoutAllocaMemorySpaceKey);
283288
}
284289

290+
StringAttr DataLayoutSpecAttr::getProgramMemorySpaceIdentifier(
291+
MLIRContext *context) const {
292+
return Builder(context).getStringAttr(
293+
DLTIDialect::kDataLayoutProgramMemorySpaceKey);
294+
}
295+
296+
StringAttr
297+
DataLayoutSpecAttr::getGlobalMemorySpaceIdentifier(MLIRContext *context) const {
298+
return Builder(context).getStringAttr(
299+
DLTIDialect::kDataLayoutGlobalMemorySpaceKey);
300+
}
285301
StringAttr
286302
DataLayoutSpecAttr::getStackAlignmentIdentifier(MLIRContext *context) const {
287303
return Builder(context).getStringAttr(
@@ -345,6 +361,8 @@ class TargetDataLayoutInterface : public DataLayoutDialectInterface {
345361
<< DLTIDialect::kDataLayoutEndiannessLittle << "'";
346362
}
347363
if (entryName == DLTIDialect::kDataLayoutAllocaMemorySpaceKey ||
364+
entryName == DLTIDialect::kDataLayoutProgramMemorySpaceKey ||
365+
entryName == DLTIDialect::kDataLayoutGlobalMemorySpaceKey ||
348366
entryName == DLTIDialect::kDataLayoutStackAlignmentKey)
349367
return success();
350368
return emitError(loc) << "unknown data layout entry name: " << entryName;

mlir/lib/Interfaces/DataLayoutInterfaces.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,30 @@ mlir::detail::getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry) {
230230
return entry.getValue();
231231
}
232232

233+
// Returns the memory space used for the program memory space. if
234+
// specified in the given entry. If the entry is empty the default
235+
// memory space represented by an empty attribute is returned.
236+
Attribute
237+
mlir::detail::getDefaultProgramMemorySpace(DataLayoutEntryInterface entry) {
238+
if (entry == DataLayoutEntryInterface()) {
239+
return Attribute();
240+
}
241+
242+
return entry.getValue();
243+
}
244+
245+
// Returns the memory space used for global the global memory space. if
246+
// specified in the given entry. If the entry is empty the default memory
247+
// space represented by an empty attribute is returned.
248+
Attribute
249+
mlir::detail::getDefaultGlobalMemorySpace(DataLayoutEntryInterface entry) {
250+
if (entry == DataLayoutEntryInterface()) {
251+
return Attribute();
252+
}
253+
254+
return entry.getValue();
255+
}
256+
233257
// Returns the stack alignment if specified in the given entry. If the entry is
234258
// empty the default alignment zero is returned.
235259
uint64_t
@@ -382,7 +406,8 @@ mlir::DataLayout::DataLayout() : DataLayout(ModuleOp()) {}
382406

383407
mlir::DataLayout::DataLayout(DataLayoutOpInterface op)
384408
: originalLayout(getCombinedDataLayout(op)), scope(op),
385-
allocaMemorySpace(std::nullopt), stackAlignment(std::nullopt) {
409+
allocaMemorySpace(std::nullopt), programMemorySpace(std::nullopt),
410+
globalMemorySpace(std::nullopt), stackAlignment(std::nullopt) {
386411
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
387412
checkMissingLayout(originalLayout, op);
388413
collectParentLayouts(op, layoutStack);
@@ -391,7 +416,8 @@ mlir::DataLayout::DataLayout(DataLayoutOpInterface op)
391416

392417
mlir::DataLayout::DataLayout(ModuleOp op)
393418
: originalLayout(getCombinedDataLayout(op)), scope(op),
394-
allocaMemorySpace(std::nullopt), stackAlignment(std::nullopt) {
419+
allocaMemorySpace(std::nullopt), programMemorySpace(std::nullopt),
420+
globalMemorySpace(std::nullopt), stackAlignment(std::nullopt) {
395421
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
396422
checkMissingLayout(originalLayout, op);
397423
collectParentLayouts(op, layoutStack);
@@ -510,6 +536,38 @@ mlir::Attribute mlir::DataLayout::getAllocaMemorySpace() const {
510536
return *allocaMemorySpace;
511537
}
512538

539+
mlir::Attribute mlir::DataLayout::getProgramMemorySpace() const {
540+
checkValid();
541+
if (programMemorySpace)
542+
return *programMemorySpace;
543+
DataLayoutEntryInterface entry;
544+
if (originalLayout)
545+
entry = originalLayout.getSpecForIdentifier(
546+
originalLayout.getProgramMemorySpaceIdentifier(
547+
originalLayout.getContext()));
548+
if (auto iface = dyn_cast_or_null<DataLayoutOpInterface>(scope))
549+
programMemorySpace = iface.getProgramMemorySpace(entry);
550+
else
551+
programMemorySpace = detail::getDefaultProgramMemorySpace(entry);
552+
return *programMemorySpace;
553+
}
554+
555+
mlir::Attribute mlir::DataLayout::getGlobalMemorySpace() const {
556+
checkValid();
557+
if (globalMemorySpace)
558+
return *globalMemorySpace;
559+
DataLayoutEntryInterface entry;
560+
if (originalLayout)
561+
entry = originalLayout.getSpecForIdentifier(
562+
originalLayout.getGlobalMemorySpaceIdentifier(
563+
originalLayout.getContext()));
564+
if (auto iface = dyn_cast_or_null<DataLayoutOpInterface>(scope))
565+
globalMemorySpace = iface.getGlobalMemorySpace(entry);
566+
else
567+
globalMemorySpace = detail::getDefaultGlobalMemorySpace(entry);
568+
return *globalMemorySpace;
569+
}
570+
513571
uint64_t mlir::DataLayout::getStackAlignment() const {
514572
checkValid();
515573
if (stackAlignment)

mlir/lib/Target/LLVMIR/DataLayoutImporter.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ DataLayoutImporter::tryToEmplaceEndiannessEntry(StringRef endianness,
164164
}
165165

166166
LogicalResult
167-
DataLayoutImporter::tryToEmplaceAllocaAddrSpaceEntry(StringRef token) {
168-
auto key =
169-
StringAttr::get(context, DLTIDialect::kDataLayoutAllocaMemorySpaceKey);
167+
DataLayoutImporter::tryToEmplaceAddrSpaceEntry(StringRef token,
168+
llvm::StringLiteral spaceKey) {
169+
auto key = StringAttr::get(context, spaceKey);
170170
if (keyEntries.count(key))
171171
return success();
172172

@@ -247,9 +247,24 @@ void DataLayoutImporter::translateDataLayout(
247247
return;
248248
continue;
249249
}
250+
// Parse the program address space.
251+
if (*prefix == "P") {
252+
if (failed(tryToEmplaceAddrSpaceEntry(
253+
token, DLTIDialect::kDataLayoutProgramMemorySpaceKey)))
254+
return;
255+
continue;
256+
}
257+
// Parse the global address space.
258+
if (*prefix == "G") {
259+
if (failed(tryToEmplaceAddrSpaceEntry(
260+
token, DLTIDialect::kDataLayoutGlobalMemorySpaceKey)))
261+
return;
262+
continue;
263+
}
250264
// Parse the alloca address space.
251265
if (*prefix == "A") {
252-
if (failed(tryToEmplaceAllocaAddrSpaceEntry(token)))
266+
if (failed(tryToEmplaceAddrSpaceEntry(
267+
token, DLTIDialect::kDataLayoutAllocaMemorySpaceKey)))
253268
return;
254269
continue;
255270
}

mlir/lib/Target/LLVMIR/DataLayoutImporter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ class DataLayoutImporter {
9797
StringRef token);
9898

9999
/// Adds an alloca address space entry if there is none yet.
100-
LogicalResult tryToEmplaceAllocaAddrSpaceEntry(StringRef token);
100+
LogicalResult tryToEmplaceAddrSpaceEntry(StringRef token,
101+
llvm::StringLiteral spaceKey);
101102

102103
/// Adds a stack alignment entry if there is none yet.
103104
LogicalResult tryToEmplaceStackAlignmentEntry(StringRef token);

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,26 @@ translateDataLayout(DataLayoutSpecInterface attribute,
190190
layoutStream.flush();
191191
continue;
192192
}
193+
if (key.getValue() == DLTIDialect::kDataLayoutProgramMemorySpaceKey) {
194+
auto value = cast<IntegerAttr>(entry.getValue());
195+
uint64_t space = value.getValue().getZExtValue();
196+
// Skip the default address space.
197+
if (space == 0)
198+
continue;
199+
layoutStream << "-P" << space;
200+
layoutStream.flush();
201+
continue;
202+
}
203+
if (key.getValue() == DLTIDialect::kDataLayoutGlobalMemorySpaceKey) {
204+
auto value = cast<IntegerAttr>(entry.getValue());
205+
uint64_t space = value.getValue().getZExtValue();
206+
// Skip the default address space.
207+
if (space == 0)
208+
continue;
209+
layoutStream << "-G" << space;
210+
layoutStream.flush();
211+
continue;
212+
}
193213
if (key.getValue() == DLTIDialect::kDataLayoutAllocaMemorySpaceKey) {
194214
auto value = cast<IntegerAttr>(entry.getValue());
195215
uint64_t space = value.getValue().getZExtValue();

0 commit comments

Comments
 (0)