18 #include "llvm/ADT/TypeSwitch.h"
27 void PtrDialect::initialize() {
30 #include "mlir/Dialect/Ptr/IR/PtrOps.cpp.inc"
33 #define GET_ATTRDEF_LIST
34 #include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.cpp.inc"
37 #define GET_TYPEDEF_LIST
38 #include "mlir/Dialect/Ptr/IR/PtrOpsTypes.cpp.inc"
54 FromPtrOp fromPtr = *
this;
55 while (fromPtr !=
nullptr) {
59 if (!toPtr || toPtr.getPtr().getType() != fromPtr.getType())
61 Value md = fromPtr.getMetadata();
63 if (!fromPtr.getType().hasPtrMetadata()) {
64 ptrLike = toPtr.getPtr();
68 mdOp && mdOp.getPtr() == toPtr.getPtr())
69 ptrLike = toPtr.getPtr();
72 fromPtr = ptrLike ? ptrLike.
getDefiningOp<FromPtrOp>() :
nullptr;
79 return emitError() <<
"the result type cannot be `!ptr.ptr`";
80 if (
getType().getMemorySpace() != getPtr().
getType().getMemorySpace()) {
82 <<
"expected the input and output to have the same memory space";
92 template <
typename OpTy>
95 if (memOp.getOrdering() != AtomicOrdering::not_atomic) {
96 if (llvm::is_contained(unsupportedOrderings, memOp.getOrdering()))
97 return memOp.emitOpError(
"unsupported ordering '")
98 << stringifyAtomicOrdering(memOp.getOrdering()) <<
"'";
99 if (!memOp.getAlignment())
100 return memOp.emitOpError(
"expected alignment for atomic access");
103 if (memOp.getSyncscope()) {
104 return memOp.emitOpError(
105 "expected syncscope to be null for non-atomic access");
116 if (alignment.value() <= 0)
117 return emitError() <<
"alignment must be positive";
118 if (!llvm::isPowerOf2_64(alignment.value()))
119 return emitError() <<
"alignment must be a power of 2";
123 void LoadOp::getEffects(
132 if (getVolatile_() || (getOrdering() != AtomicOrdering::not_atomic &&
133 getOrdering() != AtomicOrdering::unordered)) {
141 MemorySpaceAttrInterface ms = getPtr().getType().getMemorySpace();
142 if (!ms.isValidLoad(getResult().
getType(), getOrdering(), getAlignment(),
148 {AtomicOrdering::release, AtomicOrdering::acq_rel});
152 Value addr,
unsigned alignment,
bool isVolatile,
153 bool isNonTemporal,
bool isInvariant,
bool isInvariantGroup,
154 AtomicOrdering ordering, StringRef syncscope) {
155 build(builder, state, type, addr,
156 alignment ? std::optional<int64_t>(alignment) : std::nullopt,
157 isVolatile, isNonTemporal, isInvariant, isInvariantGroup, ordering,
158 syncscope.empty() ?
nullptr : builder.
getStringAttr(syncscope));
165 void StoreOp::getEffects(
174 if (getVolatile_() || (getOrdering() != AtomicOrdering::not_atomic &&
175 getOrdering() != AtomicOrdering::unordered)) {
183 MemorySpaceAttrInterface ms = getPtr().getType().getMemorySpace();
184 if (!ms.isValidStore(getValue().
getType(), getOrdering(), getAlignment(),
190 {AtomicOrdering::acquire, AtomicOrdering::acq_rel});
194 Value addr,
unsigned alignment,
bool isVolatile,
195 bool isNonTemporal,
bool isInvariantGroup,
196 AtomicOrdering ordering, StringRef syncscope) {
197 build(builder, state, value, addr,
198 alignment ? std::optional<int64_t>(alignment) : std::nullopt,
199 isVolatile, isNonTemporal, isInvariantGroup, ordering,
200 syncscope.empty() ?
nullptr : builder.
getStringAttr(syncscope));
228 ToPtrOp toPtr = *
this;
229 while (toPtr !=
nullptr) {
234 ptr = fromPtr.getPtr();
242 if (isa<PtrType>(getPtr().
getType()))
243 return emitError() <<
"the input value cannot be of type `!ptr.ptr`";
244 if (
getType().getMemorySpace() != getPtr().
getType().getMemorySpace()) {
246 <<
"expected the input and output to have the same memory space";
255 llvm::TypeSize TypeOffsetOp::getTypeSize(std::optional<DataLayout> layout) {
266 #include "mlir/Dialect/Ptr/IR/PtrOpsDialect.cpp.inc"
268 #define GET_ATTRDEF_CLASSES
269 #include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.cpp.inc"
271 #include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.cpp.inc"
273 #include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.cpp.inc"
275 #include "mlir/Dialect/Ptr/IR/PtrOpsEnums.cpp.inc"
277 #define GET_TYPEDEF_CLASSES
278 #include "mlir/Dialect/Ptr/IR/PtrOpsTypes.cpp.inc"
280 #define GET_OP_CLASSES
281 #include "mlir/Dialect/Ptr/IR/PtrOps.cpp.inc"
static Value getBase(Value v)
Looks through known "view-like" ops to find the base memref.
static InFlightDiagnostic emitDiag(Location location, DiagnosticSeverity severity, const Twine &message)
Helper function used to emit a diagnostic with an optionally empty twine message.
static Type getElementType(Type type)
Determine the element type of type.
static LogicalResult verifyAtomicMemOp(OpTy memOp, ArrayRef< AtomicOrdering > unsupportedOrderings)
Verifies the attributes and the type of atomic memory access operations.
static LogicalResult verifyAlignment(std::optional< int64_t > alignment, function_ref< InFlightDiagnostic()> emitError)
Verifies that the alignment attribute is a power of 2 if present.
Attributes are known-constant values of operations.
StringAttr getStringAttr(const Twine &bytes)
The main mechanism for performing data layout queries.
static DataLayout closest(Operation *op)
Returns the layout of the closest parent operation carrying layout info.
llvm::TypeSize getTypeSize(Type t) const
Returns the size of the given type in the current scope.
This class represents a diagnostic that is inflight and set to be reported.
This class helps build Operations.
This class represents a single result from folding an operation.
This class represents a specific instance of an effect.
static DerivedEffect * get()
Returns a unique instance for the derived effect class.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Include the generated interface declarations.
detail::constant_int_value_binder m_ConstantInt(IntegerAttr::ValueType *bind_value)
Matches a constant holding a scalar/vector/tensor integer (splat) and writes the integer value to bin...
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
This represents an operation in an abstracted form, suitable for use with the builder APIs.
bool match(Attribute attr)