-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mlir][Ptr] Add the MemorySpaceAttrInterface
interface and dependencies.
#86870
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-mlir Author: Fabian Mora (fabianmcg) ChangesThis patch introduces the For example, this interface can be used to create read-only memory spaces, making any other operation other than a load a verification error, see This patch also introduces Enum depedencies Also, see:
Note: Ignore the first commit, that's being reviewed in #86860 . Patch is 48.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86870.diff 23 Files Affected:
diff --git a/mlir/include/mlir/Dialect/CMakeLists.txt b/mlir/include/mlir/Dialect/CMakeLists.txt
index 2da79011fa26a3..5f0e9806926145 100644
--- a/mlir/include/mlir/Dialect/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/CMakeLists.txt
@@ -28,6 +28,7 @@ add_subdirectory(OpenACCMPCommon)
add_subdirectory(OpenMP)
add_subdirectory(PDL)
add_subdirectory(PDLInterp)
+add_subdirectory(Ptr)
add_subdirectory(Quant)
add_subdirectory(SCF)
add_subdirectory(Shape)
diff --git a/mlir/include/mlir/Dialect/Ptr/CMakeLists.txt b/mlir/include/mlir/Dialect/Ptr/CMakeLists.txt
new file mode 100644
index 00000000000000..f33061b2d87cff
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(IR)
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt
new file mode 100644
index 00000000000000..80dffdfd402cf2
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_mlir_dialect(PtrOps ptr)
+add_mlir_doc(PtrOps PtrOps Dialects/ -gen-op-doc)
+
+set(LLVM_TARGET_DEFINITIONS MemorySpaceInterfaces.td)
+mlir_tablegen(MemorySpaceInterfaces.h.inc -gen-op-interface-decls)
+mlir_tablegen(MemorySpaceInterfaces.cpp.inc -gen-op-interface-defs)
+mlir_tablegen(MemorySpaceAttrInterfaces.h.inc -gen-attr-interface-decls)
+mlir_tablegen(MemorySpaceAttrInterfaces.cpp.inc -gen-attr-interface-defs)
+add_public_tablegen_target(MLIRPtrMemorySpaceInterfacesIncGen)
+
+set(LLVM_TARGET_DEFINITIONS PtrOps.td)
+mlir_tablegen(PtrOpsEnums.h.inc -gen-enum-decls)
+mlir_tablegen(PtrOpsEnums.cpp.inc -gen-enum-defs)
+add_public_tablegen_target(MLIRPtrOpsEnumsGen)
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpace.h b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpace.h
new file mode 100644
index 00000000000000..e467d121f2c886
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpace.h
@@ -0,0 +1,161 @@
+//===-- MemorySpace.h - ptr dialect memory space ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ptr's dialect memory space class and related
+// interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_PTR_IR_MEMORYSPACE_H
+#define MLIR_DIALECT_PTR_IR_MEMORYSPACE_H
+
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/OpDefinition.h"
+
+namespace mlir {
+class Operation;
+namespace ptr {
+/// This method checks if it's valid to perform an `addrspacecast` op in the
+/// memory space.
+/// Compatible types are:
+/// Vectors of rank 1, or scalars of `ptr` type.
+LogicalResult isValidAddrSpaceCastImpl(Type tgt, Type src,
+ Operation *diagnosticOp);
+
+/// This method checks if it's valid to perform a `ptrtoint` or `inttoptr` op in
+/// the memory space.
+/// Compatible types are:
+/// IntLikeTy: Vectors of rank 1, or scalars of integer types or `index` type.
+/// PtrLikeTy: Vectors of rank 1, or scalars of `ptr` type.
+LogicalResult isValidPtrIntCastImpl(Type intLikeTy, Type ptrLikeTy,
+ Operation *diagnosticOp);
+
+enum class AtomicBinOp : uint64_t;
+enum class AtomicOrdering : uint64_t;
+} // namespace ptr
+} // namespace mlir
+
+#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.h.inc"
+
+namespace mlir {
+namespace ptr {
+/// This class wraps the `MemorySpaceAttrInterface` interface, providing a safe
+/// mechanism to specify the default behavior assumed by the ptr dialect.
+class MemorySpace {
+public:
+ MemorySpace() = default;
+ MemorySpace(std::nullptr_t) {}
+ MemorySpace(MemorySpaceAttrInterface memorySpace)
+ : memorySpaceAttr(memorySpace), memorySpace(memorySpace) {}
+ MemorySpace(Attribute memorySpace)
+ : memorySpaceAttr(memorySpace),
+ memorySpace(dyn_cast_or_null<MemorySpaceAttrInterface>(memorySpace)) {}
+
+ operator Attribute() const { return memorySpaceAttr; }
+ operator MemorySpaceAttrInterface() const { return memorySpace; }
+ bool operator==(const MemorySpace &memSpace) const {
+ return memSpace.memorySpaceAttr == memorySpaceAttr;
+ }
+
+ /// Returns the underlying memory space.
+ Attribute getUnderlyingSpace() const { return memorySpaceAttr; }
+
+ /// Returns true if the underlying memory space is null.
+ bool isDefaultModel() const { return memorySpace == nullptr; }
+
+ /// Returns the memory space as an integer, or 0 if using the default space.
+ unsigned getAddressSpace() const {
+ if (memorySpace)
+ return memorySpace.getAddressSpace();
+ if (auto intAttr = llvm::dyn_cast_or_null<IntegerAttr>(memorySpaceAttr))
+ return intAttr.getInt();
+ return 0;
+ }
+
+ /// Returns the default memory space as an attribute, or nullptr if using the
+ /// default model.
+ Attribute getDefaultMemorySpace() const {
+ return memorySpace ? memorySpace.getDefaultMemorySpace() : nullptr;
+ }
+
+ /// This method checks if it's valid to load a value from the memory space
+ /// with a specific type, alignment, and atomic ordering. The default model
+ /// assumes all values are loadable.
+ LogicalResult isValidLoad(Type type, AtomicOrdering ordering,
+ IntegerAttr alignment,
+ Operation *diagnosticOp = nullptr) const {
+ return memorySpace ? memorySpace.isValidLoad(type, ordering, alignment,
+ diagnosticOp)
+ : success();
+ }
+
+ /// This method checks if it's valid to store a value in the memory space with
+ /// a specific type, alignment, and atomic ordering. The default model assumes
+ /// all values are loadable.
+ LogicalResult isValidStore(Type type, AtomicOrdering ordering,
+ IntegerAttr alignment,
+ Operation *diagnosticOp = nullptr) const {
+ return memorySpace ? memorySpace.isValidStore(type, ordering, alignment,
+ diagnosticOp)
+ : success();
+ }
+
+ /// This method checks if it's valid to perform an atomic operation in the
+ /// memory space with a specific type, alignment, and atomic ordering.
+ LogicalResult isValidAtomicOp(AtomicBinOp op, Type type,
+ AtomicOrdering ordering, IntegerAttr alignment,
+ Operation *diagnosticOp = nullptr) const {
+ return memorySpace ? memorySpace.isValidAtomicOp(op, type, ordering,
+ alignment, diagnosticOp)
+ : success();
+ }
+
+ /// This method checks if it's valid to perform an atomic operation in the
+ /// memory space with a specific type, alignment, and atomic ordering.
+ LogicalResult isValidAtomicXchg(Type type, AtomicOrdering successOrdering,
+ AtomicOrdering failureOrdering,
+ IntegerAttr alignment,
+ Operation *diagnosticOp = nullptr) const {
+ return memorySpace ? memorySpace.isValidAtomicXchg(type, successOrdering,
+ failureOrdering,
+ alignment, diagnosticOp)
+ : success();
+ }
+
+ /// This method checks if it's valid to perform an `addrspacecast` op in the
+ /// memory space.
+ LogicalResult isValidAddrSpaceCast(Type tgt, Type src,
+ Operation *diagnosticOp = nullptr) const {
+ return memorySpace
+ ? memorySpace.isValidAddrSpaceCast(tgt, src, diagnosticOp)
+ : isValidAddrSpaceCastImpl(tgt, src, diagnosticOp);
+ }
+
+ /// This method checks if it's valid to perform a `ptrtoint` or `inttoptr` op
+ /// in the memory space.
+ LogicalResult isValidPtrIntCast(Type intLikeTy, Type ptrLikeTy,
+ Operation *diagnosticOp = nullptr) const {
+ return memorySpace
+ ? memorySpace.isValidPtrIntCast(intLikeTy, ptrLikeTy,
+ diagnosticOp)
+ : isValidPtrIntCastImpl(intLikeTy, ptrLikeTy, diagnosticOp);
+ }
+
+protected:
+ /// Underlying memory space.
+ Attribute memorySpaceAttr{};
+ /// Memory space.
+ MemorySpaceAttrInterface memorySpace{};
+};
+} // namespace ptr
+} // namespace mlir
+
+#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h.inc"
+
+#endif // MLIR_DIALECT_PTR_IR_MEMORYSPACE_H
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td
new file mode 100644
index 00000000000000..b7bed95434839e
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td
@@ -0,0 +1,182 @@
+//===-- MemorySpaceInterfaces.td - Memory space interfaces ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines memory space attribute interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PTR_MEMORYSPACEINTERFACES
+#define PTR_MEMORYSPACEINTERFACES
+
+include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/OpBase.td"
+
+//===----------------------------------------------------------------------===//
+// Memory space attribute interface.
+//===----------------------------------------------------------------------===//
+
+def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
+ let description = [{
+ This interface defines a common API for interacting with the memory model of
+ a memory space and the operations in the pointer dialect, giving proper
+ semantical meaning to the ops.
+
+ Furthermore, this interface allows concepts such as read-only memory to be
+ adequately modeled and enforced.
+ }];
+ let cppNamespace = "::mlir::ptr";
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/ [{
+ Returns the dialect implementing the memory space.
+ }],
+ /*returnType=*/ "::mlir::Dialect*",
+ /*methodName=*/ "getMemorySpaceDialect",
+ /*args=*/ (ins),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{ return nullptr; }]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ Returns the default memory space as an attribute.
+ }],
+ /*returnType=*/ "::mlir::Attribute",
+ /*methodName=*/ "getDefaultMemorySpace",
+ /*args=*/ (ins),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ Returns the memory space as an integer, or 0 if using the default model.
+ }],
+ /*returnType=*/ "unsigned",
+ /*methodName=*/ "getAddressSpace",
+ /*args=*/ (ins),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{ return 0; }]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ This method checks if it's valid to load a value from the memory space
+ with a specific type, alignment, and atomic ordering.
+ If `diagnosticOp` is non-null then the method might emit diagnostics.
+ }],
+ /*returnType=*/ "::mlir::LogicalResult",
+ /*methodName=*/ "isValidLoad",
+ /*args=*/ (ins "::mlir::Type":$type,
+ "::mlir::ptr::AtomicOrdering":$ordering,
+ "::mlir::IntegerAttr":$alignment,
+ "::mlir::Operation*":$diagnosticOp),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ This method checks if it's valid to store a value in the memory space
+ with a specific type, alignment, and atomic ordering.
+ If `diagnosticOp` is non-null then the method might emit diagnostics.
+ }],
+ /*returnType=*/ "::mlir::LogicalResult",
+ /*methodName=*/ "isValidStore",
+ /*args=*/ (ins "::mlir::Type":$type,
+ "::mlir::ptr::AtomicOrdering":$ordering,
+ "::mlir::IntegerAttr":$alignment,
+ "::mlir::Operation*":$diagnosticOp),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ This method checks if it's valid to perform an atomic operation in the
+ memory space with a specific type, alignment, and atomic ordering.
+ If `diagnosticOp` is non-null then the method might emit diagnostics.
+ }],
+ /*returnType=*/ "::mlir::LogicalResult",
+ /*methodName=*/ "isValidAtomicOp",
+ /*args=*/ (ins "::mlir::ptr::AtomicBinOp":$op,
+ "::mlir::Type":$type,
+ "::mlir::ptr::AtomicOrdering":$ordering,
+ "::mlir::IntegerAttr":$alignment,
+ "::mlir::Operation*":$diagnosticOp),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ This method checks if it's valid to perform an atomic exchange operation
+ in the memory space with a specific type, alignment, and atomic
+ orderings.
+ If `diagnosticOp` is non-null then the method might emit diagnostics.
+ }],
+ /*returnType=*/ "::mlir::LogicalResult",
+ /*methodName=*/ "isValidAtomicXchg",
+ /*args=*/ (ins "::mlir::Type":$type,
+ "::mlir::ptr::AtomicOrdering":$successOrdering,
+ "::mlir::ptr::AtomicOrdering":$failureOrdering,
+ "::mlir::IntegerAttr":$alignment,
+ "::mlir::Operation*":$diagnosticOp),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ This method checks if it's valid to perform an `addrspacecast` op
+ in the memory space.
+ Both types are expected to be vectors of rank 1, or scalars of `ptr`
+ type.
+ If `diagnosticOp` is non-null then the method might emit diagnostics.
+ }],
+ /*returnType=*/ "::mlir::LogicalResult",
+ /*methodName=*/ "isValidAddrSpaceCast",
+ /*args=*/ (ins "::mlir::Type":$tgt,
+ "::mlir::Type":$src,
+ "::mlir::Operation*":$diagnosticOp),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ InterfaceMethod<
+ /*desc=*/ [{
+ This method checks if it's valid to perform a `ptrtoint` or `inttoptr`
+ op in the memory space. `CastValidity::InvalidSourceType` always refers
+ to the 'ptr-like' type and `CastValidity::InvalidTargetType` always
+ refers to the `int-like` type.
+ The first type is expected to be integer-like, while the second must be a
+ ptr-like type.
+ If `diagnosticOp` is non-null then the method might emit diagnostics.
+ }],
+ /*returnType=*/ "::mlir::LogicalResult",
+ /*methodName=*/ "isValidPtrIntCast",
+ /*args=*/ (ins "::mlir::Type":$intLikeTy,
+ "::mlir::Type":$ptrLikeTy,
+ "::mlir::Operation*":$diagnosticOp),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ ];
+}
+
+def MemorySpaceOpInterface : OpInterface<"MemorySpaceOpInterface"> {
+ let description = [{
+ An interface for operations with a memory space.
+ }];
+
+ let cppNamespace = "::mlir::ptr";
+
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/ "Returns the memory space of the op.",
+ /*returnType=*/ "::mlir::ptr::MemorySpace",
+ /*methodName=*/ "getMemorySpace",
+ /*args=*/ (ins),
+ /*methodBody=*/ [{}],
+ /*defaultImpl=*/ [{}]
+ >,
+ ];
+}
+#endif // PTR_MEMORYSPACEINTERFACES
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
new file mode 100644
index 00000000000000..e6aa7635919f6d
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
@@ -0,0 +1,20 @@
+//===- PtrAttrs.h - Pointer dialect attributes ------------------*- C++ -*-===//
+//
+// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Ptr dialect attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_PTR_IR_PTRATTRS_H
+#define MLIR_DIALECT_PTR_IR_PTRATTRS_H
+
+#include "mlir/IR/OpImplementation.h"
+
+#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.h.inc"
+
+#endif // MLIR_DIALECT_PTR_IR_PTRATTRS_H
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.h
new file mode 100644
index 00000000000000..92f877c20dbf07
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.h
@@ -0,0 +1,20 @@
+//===- PtrDialect.h - Pointer dialect ---------------------------*- C++ -*-===//
+//
+// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Ptr dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_PTR_IR_PTRDIALECT_H
+#define MLIR_DIALECT_PTR_IR_PTRDIALECT_H
+
+#include "mlir/IR/Dialect.h"
+
+#include "mlir/Dialect/Ptr/IR/PtrOpsDialect.h.inc"
+
+#endif // MLIR_DIALECT_PTR_IR_PTRDIALECT_H
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
new file mode 100644
index 00000000000000..bffae6b1ad71bb
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
@@ -0,0 +1,83 @@
+//===- PtrDialect.td - Pointer dialect ---------------------*- tablegen -*-===//
+//
+// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PTR_DIALECT
+#define PTR_DIALECT
+
+include "mlir/Interfaces/DataLayoutInterfaces.td"
+include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/BuiltinTypeInterfaces.td"
+include "mlir/IR/OpBase.td"
+
+//===----------------------------------------------------------------------===//
+// Pointer dialect definition.
+//===----------------------------------------------------------------------===//
+
+def Ptr_Dialect : Dialect {
+ let name = "ptr";
+ let summary = "Pointer dialect";
+ let cppNamespace = "::mlir::ptr";
+ let useDefaultTypePrinterParser = 1;
+ let useDefaultAttributePrinterParser = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Pointer type definitions
+//===----------------------------------------------------------------------===//
+
+class Ptr_Type<string name, string typeMnemonic, list<Trait> traits = []>
+ : TypeDef<Ptr_Dialect, name, traits> {
+ let mnemonic = typeMnemonic;
+}
+
+def Ptr_PtrType : Ptr_Type<"Ptr", "ptr", [
+ MemRefElementTypeInterface,
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface, [
+ "areCompatible", "getIndexBitwidth", "verifyEntries"]>
+ ]> {
+ let summary = "pointer type";
+ let description = [{
+ The `ptr` type is an opaque pointer type. This type typically represents
+ a reference to an object in memory. Pointers are optionally parameterized
+ by a memory space.
+ Syntax:
+
+ ```mlir
+ pointer ::=...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work. Dropped a few comments, but the design should be reviewed by someone else, I think.
MemorySpace(std::nullptr_t) {} | ||
MemorySpace(MemorySpaceAttrInterface memorySpace) | ||
: memorySpaceAttr(memorySpace), memorySpace(memorySpace) {} | ||
MemorySpace(Attribute memorySpace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Do we want implicit conversion constructors? Especially from Attribute
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can make it explicit. I left it implicit for convenience.
Attribute getUnderlyingSpace() const { return memorySpaceAttr; } | ||
|
||
/// Returns true if the underlying memory space is null. | ||
bool isDefaultModel() const { return memorySpace == nullptr; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment implies that this should be a check with memorySpaceAttr
|
||
protected: | ||
/// Underlying memory space. | ||
Attribute memorySpaceAttr{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: The naming is confusing. Maybe consider to use something like underlyingMemorySpace
?
|
||
/// This method checks if it's valid to store a value in the memory space with | ||
/// a specific type, alignment, and atomic ordering. The default model assumes | ||
/// all values are loadable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: loadable -> storable or can be stored
: success(); | ||
} | ||
|
||
/// This method checks if it's valid to perform an atomic operation in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: an atomic exchange operation?
Also I would change "This method checks" to just "Checks" here and for the other functions?
std::pair<Type, int64_t> intInfo = getVecOrScalarInfo(intLikeTy); | ||
if (!intInfo.first.isSignlessIntOrIndex()) | ||
/// The int-like operand is invalid. | ||
return op ? op->emitError("invalid int-like type") : failure(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please use braces around such multi-line ifs here and below. Also no need for triple slash doc comments inside the function.
// Vectors of rank greater than one or with scalable dimensions are not | ||
// supported. | ||
if (vecTy.getRank() != 1) | ||
return {elemTy, -1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can you introduce constants for these error codes instead of using integer literals? E.g. kMultiDimensionalVector or similar.
if (!isa<PtrType>(ptrInfo.first)) | ||
/// The pointer-like operand is invalid. | ||
return op ? op->emitError("invalid ptr-like type") : failure(); | ||
// Check shape validity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shape comparison seems to be duplicated here and above? I would try to factor this into a function? Maybe getVecOrScalarInfo
could then just return the element type which seems to be what the remaining checks use. That way there is no need to factor out constants for -1 / -2.
How do we do that if you append more commits? |
My plan is: If I add new commits to this PR, it shouldn't be an issue as the new commits will be on top. Once, the dependent PR is approved and merged, I'll remove the first commit locally and then force push. |
I'd be curious where? I'm only doing manual stack PRs.
I just figured how to select multiple commits to see in the diff, should work. |
This patch initializes the `ptr` dialect directories and some base files. It also add the `!ptr.ptr` type, together with the `DataLayoutTypeInterface` interface. The implementation of the `DataLayoutTypeInterface` interface clones the implementation from `LLVM::LLVMPointerType`.
…cies. This patch introduces the `MemorySpaceAttrInterface` interface. This interface is responsible for handling the semantics of `ptr` operations. For example, this interface can be used to create read-only memory spaces, making any other operation other than a load a verification error, see `TestConstMemorySpaceAttr` for a possible implementation of this concept. This patch also introduces Enum depedencies `AtomicOrdering`, and `AtomicBinOp`, both enumerations are clones of the Enums with same name in the LLVM Dialect.
161d1fc
to
5042d6f
Compare
if (auto intAttr = llvm::dyn_cast_or_null<IntegerAttr>(memorySpaceAttr)) | ||
return intAttr.getInt(); | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed/desirable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it so it exposed a similar method to the one found in memref
(getMemorySpaceAsInt
), however, I missed the deprecated note for the method memref
. I'll remove it.
namespace mlir { | ||
namespace ptr { | ||
/// This class wraps the `MemorySpaceAttrInterface` interface, providing a safe | ||
/// mechanism to specify the default behavior assumed by the ptr dialect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interfaces support default implementation in their specification, so you probably should flesh out the description here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change the description.
/// Compatible types are: | ||
/// Vectors of rank 1, or scalars of `ptr` type. | ||
LogicalResult isValidAddrSpaceCastImpl(Type tgt, Type src, | ||
Operation *diagnosticOp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general we don't pass an operation for diagnostic, instead a function_ref<InFlightDiagnostic()> emitError
works well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change it.
/// IntLikeTy: Vectors of rank 1, or scalars of integer types or `index` type. | ||
/// PtrLikeTy: Vectors of rank 1, or scalars of `ptr` type. | ||
LogicalResult isValidPtrIntCastImpl(Type intLikeTy, Type ptrLikeTy, | ||
Operation *diagnosticOp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to hardcode a bit of things around specific types, does it really belong here? What does it mean for the extensibility of the dialect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just the default implementation used by isValidAddrSpaceCast
. If an users wants to allow a different set of types, then they need to override the method.
This patch introduces the
MemorySpaceAttrInterface
interface. This interface is responsible for handling the semantics ofptr
operations.For example, this interface can be used to create read-only memory spaces, making any other operation other than a load a verification error, see
TestConstMemorySpaceAttr
for a possible implementation of this concept.This patch also introduces Enum dependencies
AtomicOrdering
, andAtomicBinOp
, both enumerations are clones of the Enums with the same name in the LLVM Dialect.Also, see:
ptr
dialect & modularizing ptr ops in the LLVM dialect for rationale.Note: Ignore the first commit, that's being reviewed in #86860 .