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"
52 if (alignment.value() <= 0)
53 return emitError() <<
"alignment must be positive";
54 if (!llvm::isPowerOf2_64(alignment.value()))
55 return emitError() <<
"alignment must be a power of 2";
63 OpFoldResult ConstantOp::fold(FoldAdaptor adaptor) {
return getValue(); }
77 FromPtrOp fromPtr = *
this;
78 while (fromPtr !=
nullptr) {
82 if (!toPtr || toPtr.getPtr().getType() != fromPtr.getType())
84 Value md = fromPtr.getMetadata();
86 if (!fromPtr.getType().hasPtrMetadata()) {
87 ptrLike = toPtr.getPtr();
91 mdOp && mdOp.getPtr() == toPtr.getPtr())
92 ptrLike = toPtr.getPtr();
95 fromPtr = ptrLike ? ptrLike.
getDefiningOp<FromPtrOp>() :
nullptr;
102 return emitError() <<
"the result type cannot be `!ptr.ptr`";
103 if (
getType().getMemorySpace() != getPtr().
getType().getMemorySpace()) {
105 <<
"expected the input and output to have the same memory space";
114 void GatherOp::getEffects(
125 MemorySpaceAttrInterface ms =
128 if (!ms.isValidLoad(getResult().
getType(), AtomicOrdering::not_atomic,
129 getAlignment(), &dataLayout,
emitDiag))
138 unsigned alignment) {
139 build(builder, state, resultType, ptrs, mask, passthrough,
140 alignment ? std::optional<int64_t>(alignment) : std::nullopt);
148 template <
typename OpTy>
151 if (memOp.getOrdering() != AtomicOrdering::not_atomic) {
152 if (llvm::is_contained(unsupportedOrderings, memOp.getOrdering()))
153 return memOp.emitOpError(
"unsupported ordering '")
154 << stringifyAtomicOrdering(memOp.getOrdering()) <<
"'";
155 if (!memOp.getAlignment())
156 return memOp.emitOpError(
"expected alignment for atomic access");
159 if (memOp.getSyncscope()) {
160 return memOp.emitOpError(
161 "expected syncscope to be null for non-atomic access");
166 void LoadOp::getEffects(
175 if (getVolatile_() || (getOrdering() != AtomicOrdering::not_atomic &&
176 getOrdering() != AtomicOrdering::unordered)) {
184 MemorySpaceAttrInterface ms = getPtr().getType().getMemorySpace();
186 if (!ms.isValidLoad(getResult().
getType(), getOrdering(), getAlignment(),
192 {AtomicOrdering::release, AtomicOrdering::acq_rel});
196 Value addr,
unsigned alignment,
bool isVolatile,
197 bool isNonTemporal,
bool isInvariant,
bool isInvariantGroup,
198 AtomicOrdering ordering, StringRef syncscope) {
199 build(builder, state, type, addr,
200 alignment ? std::optional<int64_t>(alignment) : std::nullopt,
201 isVolatile, isNonTemporal, isInvariant, isInvariantGroup, ordering,
202 syncscope.empty() ?
nullptr : builder.
getStringAttr(syncscope));
208 void MaskedLoadOp::getEffects(
218 MemorySpaceAttrInterface ms = getPtr().getType().getMemorySpace();
220 if (!ms.isValidLoad(getResult().
getType(), AtomicOrdering::not_atomic,
221 getAlignment(), &dataLayout,
emitDiag))
230 Value passthrough,
unsigned alignment) {
231 build(builder, state, resultType, ptr, mask, passthrough,
232 alignment ? std::optional<int64_t>(alignment) : std::nullopt);
239 void MaskedStoreOp::getEffects(
249 MemorySpaceAttrInterface ms = getPtr().getType().getMemorySpace();
251 if (!ms.isValidStore(getValue().
getType(), AtomicOrdering::not_atomic,
252 getAlignment(), &dataLayout,
emitDiag))
261 unsigned alignment) {
262 build(builder, state, value, ptr, mask,
263 alignment ? std::optional<int64_t>(alignment) : std::nullopt);
270 void ScatterOp::getEffects(
281 MemorySpaceAttrInterface ms =
284 if (!ms.isValidStore(getValue().
getType(), AtomicOrdering::not_atomic,
285 getAlignment(), &dataLayout,
emitDiag))
294 build(builder, state, value, ptrs, mask,
295 alignment ? std::optional<int64_t>(alignment) : std::nullopt);
302 void StoreOp::getEffects(
311 if (getVolatile_() || (getOrdering() != AtomicOrdering::not_atomic &&
312 getOrdering() != AtomicOrdering::unordered)) {
320 MemorySpaceAttrInterface ms = getPtr().getType().getMemorySpace();
322 if (!ms.isValidStore(getValue().
getType(), getOrdering(), getAlignment(),
328 {AtomicOrdering::acquire, AtomicOrdering::acq_rel});
332 Value addr,
unsigned alignment,
bool isVolatile,
333 bool isNonTemporal,
bool isInvariantGroup,
334 AtomicOrdering ordering, StringRef syncscope) {
335 build(builder, state, value, addr,
336 alignment ? std::optional<int64_t>(alignment) : std::nullopt,
337 isVolatile, isNonTemporal, isInvariantGroup, ordering,
338 syncscope.empty() ?
nullptr : builder.
getStringAttr(syncscope));
355 LogicalResult PtrAddOp::inferReturnTypes(
363 auto offTy = dyn_cast<ShapedType>(offsetType);
366 inferredReturnTypes.push_back(baseType);
369 auto baseTy = dyn_cast<ShapedType>(baseType);
373 inferredReturnTypes.push_back(offTy.clone(baseType));
378 if (offTy.getShape() != baseTy.getShape()) {
390 inferredReturnTypes.push_back(baseType);
405 ToPtrOp toPtr = *
this;
406 while (toPtr !=
nullptr) {
411 ptr = fromPtr.getPtr();
419 if (isa<PtrType>(getPtr().
getType()))
420 return emitError() <<
"the input value cannot be of type `!ptr.ptr`";
421 if (
getType().getMemorySpace() != getPtr().
getType().getMemorySpace()) {
423 <<
"expected the input and output to have the same memory space";
432 llvm::TypeSize TypeOffsetOp::getTypeSize(std::optional<DataLayout> layout) {
443 #include "mlir/Dialect/Ptr/IR/PtrOpsDialect.cpp.inc"
445 #define GET_ATTRDEF_CLASSES
446 #include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.cpp.inc"
448 #include "mlir/Dialect/Ptr/IR/PtrOpsEnums.cpp.inc"
450 #define GET_TYPEDEF_CLASSES
451 #include "mlir/Dialect/Ptr/IR/PtrOpsTypes.cpp.inc"
453 #define GET_OP_CLASSES
454 #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.
MLIRContext is the top-level object for a collection of MLIR operations.
This class helps build Operations.
This class represents a single result from folding an operation.
Simple wrapper around a void* in order to express generically how to pass in op properties through AP...
This class provides an abstraction over the different types of ranges over Regions.
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...
TypeID getTypeID()
Return a unique identifier for the concrete type.
This class provides an abstraction over the different types of ranges over Values.
type_range getType() const
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)