|
| 1 | +//===-- MemorySpace.h - ptr dialect memory space ---------------*- 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 the ptr's dialect memory space class and related |
| 10 | +// interfaces. |
| 11 | +// |
| 12 | +//===----------------------------------------------------------------------===// |
| 13 | + |
| 14 | +#ifndef MLIR_DIALECT_PTR_IR_MEMORYSPACE_H |
| 15 | +#define MLIR_DIALECT_PTR_IR_MEMORYSPACE_H |
| 16 | + |
| 17 | +#include "mlir/IR/Attributes.h" |
| 18 | +#include "mlir/IR/BuiltinAttributes.h" |
| 19 | +#include "mlir/IR/OpDefinition.h" |
| 20 | + |
| 21 | +namespace mlir { |
| 22 | +class Operation; |
| 23 | +namespace ptr { |
| 24 | +/// This method checks if it's valid to perform an `addrspacecast` op in the |
| 25 | +/// memory space. |
| 26 | +/// Compatible types are: |
| 27 | +/// Vectors of rank 1, or scalars of `ptr` type. |
| 28 | +LogicalResult isValidAddrSpaceCastImpl(Type tgt, Type src, |
| 29 | + Operation *diagnosticOp); |
| 30 | + |
| 31 | +/// This method checks if it's valid to perform a `ptrtoint` or `inttoptr` op in |
| 32 | +/// 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 isValidPtrIntCastImpl(Type intLikeTy, Type ptrLikeTy, |
| 37 | + Operation *diagnosticOp); |
| 38 | + |
| 39 | +enum class AtomicBinOp : uint64_t; |
| 40 | +enum class AtomicOrdering : uint64_t; |
| 41 | +} // namespace ptr |
| 42 | +} // namespace mlir |
| 43 | + |
| 44 | +#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.h.inc" |
| 45 | + |
| 46 | +namespace mlir { |
| 47 | +namespace ptr { |
| 48 | +/// This class wraps the `MemorySpaceAttrInterface` interface, providing a safe |
| 49 | +/// mechanism to specify the default behavior assumed by the ptr dialect. |
| 50 | +class MemorySpace { |
| 51 | +public: |
| 52 | + MemorySpace() = default; |
| 53 | + MemorySpace(std::nullptr_t) {} |
| 54 | + MemorySpace(MemorySpaceAttrInterface memorySpace) |
| 55 | + : memorySpaceAttr(memorySpace), memorySpace(memorySpace) {} |
| 56 | + MemorySpace(Attribute memorySpace) |
| 57 | + : memorySpaceAttr(memorySpace), |
| 58 | + memorySpace(dyn_cast_or_null<MemorySpaceAttrInterface>(memorySpace)) {} |
| 59 | + |
| 60 | + operator Attribute() const { return memorySpaceAttr; } |
| 61 | + operator MemorySpaceAttrInterface() const { return memorySpace; } |
| 62 | + bool operator==(const MemorySpace &memSpace) const { |
| 63 | + return memSpace.memorySpaceAttr == memorySpaceAttr; |
| 64 | + } |
| 65 | + |
| 66 | + /// Returns the underlying memory space. |
| 67 | + Attribute getUnderlyingSpace() const { return memorySpaceAttr; } |
| 68 | + |
| 69 | + /// Returns true if the underlying memory space is null. |
| 70 | + bool isDefaultModel() const { return memorySpace == nullptr; } |
| 71 | + |
| 72 | + /// Returns the memory space as an integer, or 0 if using the default space. |
| 73 | + unsigned getAddressSpace() const { |
| 74 | + if (memorySpace) |
| 75 | + return memorySpace.getAddressSpace(); |
| 76 | + if (auto intAttr = llvm::dyn_cast_or_null<IntegerAttr>(memorySpaceAttr)) |
| 77 | + return intAttr.getInt(); |
| 78 | + return 0; |
| 79 | + } |
| 80 | + |
| 81 | + /// Returns the default memory space as an attribute, or nullptr if using the |
| 82 | + /// default model. |
| 83 | + Attribute getDefaultMemorySpace() const { |
| 84 | + return memorySpace ? memorySpace.getDefaultMemorySpace() : nullptr; |
| 85 | + } |
| 86 | + |
| 87 | + /// This method checks if it's valid to load a value from the memory space |
| 88 | + /// with a specific type, alignment, and atomic ordering. The default model |
| 89 | + /// assumes all values are loadable. |
| 90 | + LogicalResult isValidLoad(Type type, AtomicOrdering ordering, |
| 91 | + IntegerAttr alignment, |
| 92 | + Operation *diagnosticOp = nullptr) const { |
| 93 | + return memorySpace ? memorySpace.isValidLoad(type, ordering, alignment, |
| 94 | + diagnosticOp) |
| 95 | + : success(); |
| 96 | + } |
| 97 | + |
| 98 | + /// This method checks if it's valid to store a value in the memory space with |
| 99 | + /// a specific type, alignment, and atomic ordering. The default model assumes |
| 100 | + /// all values are loadable. |
| 101 | + LogicalResult isValidStore(Type type, AtomicOrdering ordering, |
| 102 | + IntegerAttr alignment, |
| 103 | + Operation *diagnosticOp = nullptr) const { |
| 104 | + return memorySpace ? memorySpace.isValidStore(type, ordering, alignment, |
| 105 | + diagnosticOp) |
| 106 | + : success(); |
| 107 | + } |
| 108 | + |
| 109 | + /// This method checks if it's valid to perform an atomic operation in the |
| 110 | + /// memory space with a specific type, alignment, and atomic ordering. |
| 111 | + LogicalResult isValidAtomicOp(AtomicBinOp op, Type type, |
| 112 | + AtomicOrdering ordering, IntegerAttr alignment, |
| 113 | + Operation *diagnosticOp = nullptr) const { |
| 114 | + return memorySpace ? memorySpace.isValidAtomicOp(op, type, ordering, |
| 115 | + alignment, diagnosticOp) |
| 116 | + : success(); |
| 117 | + } |
| 118 | + |
| 119 | + /// This method checks if it's valid to perform an atomic operation in the |
| 120 | + /// memory space with a specific type, alignment, and atomic ordering. |
| 121 | + LogicalResult isValidAtomicXchg(Type type, AtomicOrdering successOrdering, |
| 122 | + AtomicOrdering failureOrdering, |
| 123 | + IntegerAttr alignment, |
| 124 | + Operation *diagnosticOp = nullptr) const { |
| 125 | + return memorySpace ? memorySpace.isValidAtomicXchg(type, successOrdering, |
| 126 | + failureOrdering, |
| 127 | + alignment, diagnosticOp) |
| 128 | + : success(); |
| 129 | + } |
| 130 | + |
| 131 | + /// This method checks if it's valid to perform an `addrspacecast` op in the |
| 132 | + /// memory space. |
| 133 | + LogicalResult isValidAddrSpaceCast(Type tgt, Type src, |
| 134 | + Operation *diagnosticOp = nullptr) const { |
| 135 | + return memorySpace |
| 136 | + ? memorySpace.isValidAddrSpaceCast(tgt, src, diagnosticOp) |
| 137 | + : isValidAddrSpaceCastImpl(tgt, src, diagnosticOp); |
| 138 | + } |
| 139 | + |
| 140 | + /// This method checks if it's valid to perform a `ptrtoint` or `inttoptr` op |
| 141 | + /// in the memory space. |
| 142 | + LogicalResult isValidPtrIntCast(Type intLikeTy, Type ptrLikeTy, |
| 143 | + Operation *diagnosticOp = nullptr) const { |
| 144 | + return memorySpace |
| 145 | + ? memorySpace.isValidPtrIntCast(intLikeTy, ptrLikeTy, |
| 146 | + diagnosticOp) |
| 147 | + : isValidPtrIntCastImpl(intLikeTy, ptrLikeTy, diagnosticOp); |
| 148 | + } |
| 149 | + |
| 150 | +protected: |
| 151 | + /// Underlying memory space. |
| 152 | + Attribute memorySpaceAttr{}; |
| 153 | + /// Memory space. |
| 154 | + MemorySpaceAttrInterface memorySpace{}; |
| 155 | +}; |
| 156 | +} // namespace ptr |
| 157 | +} // namespace mlir |
| 158 | + |
| 159 | +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h.inc" |
| 160 | + |
| 161 | +#endif // MLIR_DIALECT_PTR_IR_MEMORYSPACE_H |
0 commit comments