Skip to content

Commit 3612436

Browse files
committed
[mlir] Ptr dialect
This patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces: - The pointer dialect and type. - The `MemorySpaceAttrInterface` interface, an interface to conceptualize memory models, giving proper semantical meaning to the Ptr dialect ops. - The `ptr::LoadOp` operation, an operation to load data from memory, with the semantics defined by `MemorySpaceAttrInterface` and translatable to LLVM IR. - The `SharedDialectTypeInterface` interface, an interface to delegate printing and parsing to a different dialect. - The introduction of `LLVM::AddressSpaceAttr`, an attribute to model LLVM memory semantics. - The replacement of `LLVMPointerType` with `ptr::PtrType`.
1 parent 463dad1 commit 3612436

26 files changed

+2195
-2
lines changed

mlir/include/mlir/Dialect/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ add_subdirectory(OpenACCMPCommon)
2727
add_subdirectory(OpenMP)
2828
add_subdirectory(PDL)
2929
add_subdirectory(PDLInterp)
30+
add_subdirectory(Ptr)
3031
add_subdirectory(Quant)
3132
add_subdirectory(SCF)
3233
add_subdirectory(Shape)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(IR)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
add_mlir_dialect(PtrOps ptr)
2+
add_mlir_doc(PtrOps PtrOps Dialects/ -gen-op-doc)
3+
4+
set(LLVM_TARGET_DEFINITIONS MemorySpaceInterfaces.td)
5+
mlir_tablegen(MemorySpaceInterfaces.h.inc -gen-op-interface-decls)
6+
mlir_tablegen(MemorySpaceInterfaces.cpp.inc -gen-op-interface-defs)
7+
mlir_tablegen(MemorySpaceAttrInterfaces.h.inc -gen-attr-interface-decls)
8+
mlir_tablegen(MemorySpaceAttrInterfaces.cpp.inc -gen-attr-interface-defs)
9+
add_public_tablegen_target(MLIRPtrMemorySpaceInterfacesIncGen)
10+
11+
set(LLVM_TARGET_DEFINITIONS PtrOps.td)
12+
mlir_tablegen(PtrOpsEnums.h.inc -gen-enum-decls)
13+
mlir_tablegen(PtrOpsEnums.cpp.inc -gen-enum-defs)
14+
add_public_tablegen_target(MLIRPtrOpsEnumsGen)
15+
16+
set(LLVM_TARGET_DEFINITIONS PtrOps.td)
17+
mlir_tablegen(PtrOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=ptr)
18+
mlir_tablegen(PtrOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=ptr)
19+
add_public_tablegen_target(MLIRPtrOpsAttributesIncGen)
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
//===-- MemorySpaceInterfaces.h - Memory space interfaces ------*- C++ -*-===//
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 file defines memory space interfaces.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H
14+
#define MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H
15+
16+
#include "mlir/IR/Attributes.h"
17+
18+
namespace mlir {
19+
class Operation;
20+
class RewriterBase;
21+
struct MemorySlot;
22+
enum class DeletionKind : int32_t;
23+
namespace ptr {
24+
enum class AtomicBinOp : uint64_t;
25+
enum class AtomicOrdering : uint64_t;
26+
/// Verifies whether the target and source types are compatible with the
27+
/// `addrspacecast` op in the default memory space.
28+
/// Compatible types are:
29+
/// Vectors of rank 1, or scalars of `ptr` type.
30+
LogicalResult verifyPtrCastDefaultImpl(Operation *op, Type tgt, Type src);
31+
/// Returns whether the target and source types are compatible with the
32+
/// `ptrtoint` and `inttoptr` ops in the memory space.
33+
/// Compatible types are:
34+
/// IntLikeTy: Vectors of rank 1, or scalars of integer types or `index` type.
35+
/// PtrLikeTy: Vectors of rank 1, or scalars of `ptr` type.
36+
LogicalResult verifyIntCastTypesDefaultImpl(Operation *op, Type intLikeTy,
37+
Type ptrLikeTy);
38+
/// Remove blocking issues of the store op for the`PromotableMemOpInterface`
39+
/// interface, the default implementation always deletes the op. For more
40+
/// information see `PromotableMemOpInterface` in
41+
/// `Interfaces/MemorySlotInterfaces`.
42+
DeletionKind removeStoreBlockingUsesDefaultImpl();
43+
44+
/// Utility class for holding the atomic-related information of an operation.
45+
struct AtomicOpInfo {
46+
AtomicOpInfo(Operation *op, Type valueType, IntegerAttr alignment,
47+
StringAttr syncScope, AtomicOrdering ordering, bool volatile_)
48+
: op(op), valueType(valueType), alignment(alignment),
49+
syncScope(syncScope), ordering(ordering), volatile_(volatile_) {}
50+
/// Atomic operation.
51+
Operation *op;
52+
/// Type of the value being acted on.
53+
Type valueType;
54+
/// Alignment of the operation.
55+
IntegerAttr alignment;
56+
/// Sync scope of the op.
57+
StringAttr syncScope;
58+
/// Atomic ordering of the op.
59+
AtomicOrdering ordering;
60+
/// Whether the atomic operation is volatile.
61+
bool volatile_;
62+
};
63+
} // namespace ptr
64+
} // namespace mlir
65+
66+
#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.h.inc"
67+
68+
namespace mlir {
69+
namespace ptr {
70+
/// This class wraps the `MemorySpaceAttrInterface` interface, providing a safe
71+
/// mechanism to specify the default behavior assumed by the ptr dialect.
72+
class MemorySpace {
73+
public:
74+
MemorySpace() = default;
75+
MemorySpace(std::nullptr_t) {}
76+
MemorySpace(MemorySpaceAttrInterface memorySpace)
77+
: memorySpace(memorySpace) {}
78+
MemorySpace(Attribute memorySpace)
79+
: memorySpace(dyn_cast_or_null<MemorySpaceAttrInterface>(memorySpace)) {}
80+
81+
/// Returns the underlying memory space.
82+
MemorySpaceAttrInterface getUnderlyingSpace() const { return memorySpace; }
83+
84+
/// Returns true if the underlying memory space is null.
85+
bool isDefaultModel() const { return memorySpace == nullptr; }
86+
87+
/// Returns the memory space as an integer, or 0 if using the default model.
88+
unsigned getAddressSpace() const {
89+
return memorySpace ? memorySpace.getAddressSpace() : 0;
90+
}
91+
92+
/// Returns the default memory space as an attribute, or nullptr if using the
93+
/// default model.
94+
Attribute getDefaultMemorySpace() const {
95+
return memorySpace ? memorySpace.getDefaultMemorySpace() : nullptr;
96+
}
97+
98+
/// Returns whether a type is loadable in the memory space. The default model
99+
/// assumes all types are loadable.
100+
bool isLoadableType(Type type) const {
101+
return memorySpace ? memorySpace.isLoadableType(type) : true;
102+
}
103+
104+
/// Returns whether a type is storable in the memory space. The default model
105+
/// assumes all types are storable.
106+
bool isStorableType(Type type) const {
107+
return memorySpace ? memorySpace.isStorableType(type) : true;
108+
}
109+
110+
/// Verifies whether the atomic information of an operation is compatible with
111+
/// the memory space. The default model assumes the op is compatible.
112+
LogicalResult verifyCompatibleAtomicOp(
113+
AtomicOpInfo atomicInfo,
114+
ArrayRef<AtomicOrdering> unsupportedOrderings) const {
115+
return memorySpace ? memorySpace.verifyCompatibleAtomicOp(
116+
atomicInfo, unsupportedOrderings)
117+
: success();
118+
}
119+
120+
/// Verifies whether an `atomicrmw` op is semantically correct according to
121+
/// the memory space. The default model assumes the op is compatible.
122+
LogicalResult verifyAtomicRMW(AtomicOpInfo atomicInfo,
123+
AtomicBinOp binOp) const {
124+
return memorySpace ? memorySpace.verifyAtomicRMW(atomicInfo, binOp)
125+
: success();
126+
}
127+
128+
/// Verifies whether a `cmpxchg` op is semantically correct according to the
129+
/// memory space. The default model assumes the op is compatible.
130+
LogicalResult
131+
verifyAtomicAtomicCmpXchg(AtomicOpInfo atomicInfo,
132+
AtomicOrdering failureOrdering) const {
133+
return memorySpace ? memorySpace.verifyAtomicAtomicCmpXchg(atomicInfo,
134+
failureOrdering)
135+
: success();
136+
}
137+
138+
/// Verifies whether the target and source types are compatible with the
139+
/// `addrspacecast` op in the memory space. Both types are expected to be
140+
/// vectors of rank 1, or scalars of `ptr` type.
141+
LogicalResult verifyPtrCast(Operation *op, Type tgt, Type src) const {
142+
return memorySpace ? memorySpace.verifyPtrCast(op, tgt, src)
143+
: verifyPtrCastDefaultImpl(op, tgt, src);
144+
}
145+
146+
/// Verifies whether the types are compatible with the `ptrtoint` and
147+
/// `inttoptr` ops in the memory space. The first type is expected to be
148+
/// integer-like, while the second must be a ptr-like type.
149+
LogicalResult verifyIntCastTypes(Operation *op, Type intLikeTy,
150+
Type ptrLikeTy) const {
151+
return memorySpace
152+
? memorySpace.verifyIntCastTypes(op, intLikeTy, ptrLikeTy)
153+
: verifyIntCastTypesDefaultImpl(op, intLikeTy, ptrLikeTy);
154+
}
155+
156+
/// Remove blocking issues of the store op for the`PromotableMemOpInterface`
157+
/// interface. For more information see `PromotableMemOpInterface` in
158+
/// `Interfaces/MemorySlotInterfaces`.
159+
DeletionKind
160+
removeStoreBlockingUses(Operation *storeOp, Value value,
161+
const MemorySlot &slot,
162+
const SmallPtrSetImpl<OpOperand *> &blockingUses,
163+
RewriterBase &rewriter, Value reachingDefinition) {
164+
return memorySpace
165+
? memorySpace.removeStoreBlockingUses(storeOp, value, slot,
166+
blockingUses, rewriter,
167+
reachingDefinition)
168+
: removeStoreBlockingUsesDefaultImpl();
169+
}
170+
171+
protected:
172+
/// Underlying memory space.
173+
MemorySpaceAttrInterface memorySpace{};
174+
};
175+
} // namespace ptr
176+
} // namespace mlir
177+
178+
#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h.inc"
179+
180+
#endif // MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H

0 commit comments

Comments
 (0)