|
| 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