|
| 1 | +#ifndef TPTR_DIALECT |
| 2 | +#define TPTR_DIALECT |
| 3 | + |
| 4 | +include "mlir/IR/OpBase.td" |
| 5 | +include "mlir/Interfaces/SideEffectInterfaces.td" |
| 6 | +include "mlir/Dialect/Ptr/IR/PtrDialect.td" |
| 7 | +include "mlir/IR/AttrTypeBase.td" |
| 8 | +include "mlir/IR/BuiltinTypeInterfaces.td" |
| 9 | + |
| 10 | +def TPtr_Dialect : Dialect { |
| 11 | + let name = "tptr"; |
| 12 | + |
| 13 | + let cppNamespace = "::mlir::tptr"; |
| 14 | + |
| 15 | + let summary = "Temporary Pointer Dialect"; |
| 16 | + |
| 17 | + let description = [{ |
| 18 | + Typed Pointer Dialect. |
| 19 | + }]; |
| 20 | + |
| 21 | + let extraClassDeclaration = [{ |
| 22 | + void registerTypes(); |
| 23 | + }]; |
| 24 | + |
| 25 | + let dependentDialects = [ |
| 26 | + "mlir::ptr::PtrDialect" |
| 27 | + ]; |
| 28 | + |
| 29 | + let usePropertiesForAttributes = 1; |
| 30 | +} |
| 31 | + |
| 32 | +class TPtrTypeDef<string name, string _mnemonic, list<Trait> traits = []> |
| 33 | + : TypeDef<TPtr_Dialect, name, traits> { |
| 34 | + // Used by printer/parser |
| 35 | + let mnemonic = _mnemonic; |
| 36 | +} |
| 37 | + |
| 38 | +// |
| 39 | +// Op Base |
| 40 | +// |
| 41 | +class TPTR_Op<string mnemonic, list<Trait> traits = []> : |
| 42 | + Op<TPtr_Dialect, mnemonic, traits> { |
| 43 | +} |
| 44 | + |
| 45 | +def TPTR_IntToPtrOp : TPTR_Op<"inttoptr", [ |
| 46 | + Pure |
| 47 | + ]> { |
| 48 | + let summary = "Integer to a pointer operation"; |
| 49 | + let description = [{ |
| 50 | + The `inttoptr` operation casts an int or index value to a pointer. |
| 51 | + |
| 52 | + Example: |
| 53 | + ```mlir |
| 54 | + %ptr = ptr.inttoptr %int : i32 to !ptr.ptr<1 : i32> |
| 55 | + ``` |
| 56 | + }]; |
| 57 | + let arguments = (ins AnySignlessIntegerOrIndex:$arg); |
| 58 | + let results = (outs Ptr_PtrType:$res); |
| 59 | + let assemblyFormat = "$arg attr-dict `:` type($arg) `to` type($res)"; |
| 60 | +} |
| 61 | + |
| 62 | +def TPTR_PtrToIntOp : TPTR_Op<"ptrtoint", [ |
| 63 | + Pure |
| 64 | + ]> { |
| 65 | + let summary = "Pointer to an integer operation"; |
| 66 | + let description = [{ |
| 67 | + The `ptrtoint` operation casts a pointer value to an int or index. |
| 68 | + |
| 69 | + Example: |
| 70 | + ```mlir |
| 71 | + %int = ptr.ptrtoint %ptr : !ptr.ptr<1 : i32> to i32 |
| 72 | + ``` |
| 73 | + }]; |
| 74 | + let arguments = (ins Ptr_PtrType:$arg); |
| 75 | + let results = (outs AnySignlessIntegerOrIndex:$res); |
| 76 | + let assemblyFormat = "$arg attr-dict `:` type($arg) `to` type($res)"; |
| 77 | +} |
| 78 | + |
| 79 | +def TPTR_TypeOffsetOp : TPTR_Op<"type_offset", [ConstantLike, Pure]> { |
| 80 | + let summary = "Creates a type offset constant."; |
| 81 | + let description = [{ |
| 82 | + The `addr.type_offset` operation produces an int or index-typed SSA value |
| 83 | + equal to a target-specific constant representing the offset of a single |
| 84 | + element of the given type. The default return type is `index`. |
| 85 | + Example: |
| 86 | + |
| 87 | + ```mlir |
| 88 | + %0 = addr.type_offset f32 |
| 89 | + %1 = addr.type_offset memref<12 x f64> : i32 |
| 90 | + ``` |
| 91 | + }]; |
| 92 | + |
| 93 | + let arguments = (ins TypeAttr:$baseType); |
| 94 | + let results = (outs AnySignlessIntegerOrIndex:$result); |
| 95 | + let builders = [ |
| 96 | + OpBuilder<(ins "TypeAttr":$baseType, CArg<"Type", "nullptr">:$resultTy)> |
| 97 | + ]; |
| 98 | + let assemblyFormat = [{ |
| 99 | + attr-dict $baseType custom<IntType>(type($result)) |
| 100 | + }]; |
| 101 | + let hasFolder = 1; |
| 102 | +} |
| 103 | + |
| 104 | +def TPTR_FromMemrefOp : TPTR_Op<"from_memref", [Pure]> { |
| 105 | + let arguments = (ins AnyMemRef:$input); |
| 106 | + let results = (outs Ptr_PtrType:$result); |
| 107 | + let assemblyFormat = "$input attr-dict `:` type($input) `to` type($result)"; |
| 108 | +} |
| 109 | + |
| 110 | +def TPTR_ToMemrefOp : TPTR_Op<"to_memref", [ |
| 111 | + Pure ]> { |
| 112 | + let arguments = (ins Ptr_PtrType:$arg); |
| 113 | + let results = (outs AnyStaticShapeMemRef:$res); |
| 114 | + let assemblyFormat = "$arg attr-dict `:` type($arg) `to` type($res)"; |
| 115 | +} |
| 116 | + |
| 117 | +def TPTR_PtrAddOp : TPTR_Op<"ptradd", [Pure, AllTypesMatch<["base", "result"]>]> { |
| 118 | + let summary = "Pointer-index add operation"; |
| 119 | + let description = [{ |
| 120 | + The `ptradd` operation adds an `address` and an integer or index to |
| 121 | + produce a new address. |
| 122 | + |
| 123 | + Example: |
| 124 | + ```mlir |
| 125 | + %addr = ptr.ptradd %addr : !ptr.ptr<3 : i32>, %c10 : i32 |
| 126 | + ``` |
| 127 | + }]; |
| 128 | + |
| 129 | + let arguments = (ins Ptr_PtrType:$base, AnySignlessIntegerOrIndex:$offset); |
| 130 | + let results = (outs Ptr_PtrType:$result); |
| 131 | + let assemblyFormat = "$base $offset attr-dict `:` type($base) `,` type($offset) `to` type($result)"; |
| 132 | +} |
| 133 | + |
| 134 | +def TPTR_LoadOp : TPTR_Op<"load", [ |
| 135 | + DeclareOpInterfaceMethods<MemoryEffectsOpInterface> |
| 136 | + ]> { |
| 137 | + let summary = "Load operation"; |
| 138 | + let description = [{ |
| 139 | + The `load` operation is used to read from memory. A load may be marked as |
| 140 | + atomic, volatile, and/or nontemporal, and takes a number of optional |
| 141 | + attributes that specify aliasing information. |
| 142 | + |
| 143 | + An atomic load only supports a limited set of pointer, integer, and |
| 144 | + floating point types, and requires an explicit alignment. |
| 145 | + |
| 146 | + Examples: |
| 147 | + ```mlir |
| 148 | + // A volatile load of a float variable. |
| 149 | + %0 = ptr.load volatile %ptr : !ptr.ptr -> f32 |
| 150 | + |
| 151 | + // A nontemporal load of a float variable. |
| 152 | + %0 = ptr.load %ptr {nontemporal} : !ptr.ptr -> f32 |
| 153 | + |
| 154 | + // An atomic load of an integer variable. |
| 155 | + %0 = ptr.load %ptr atomic monotonic {alignment = 8 : i64} |
| 156 | + : !ptr.ptr -> i64 |
| 157 | + ``` |
| 158 | + }]; |
| 159 | + let arguments = (ins AnyType:$addr); |
| 160 | + let results = (outs AnyType:$res); |
| 161 | + let assemblyFormat = [{ |
| 162 | + $addr |
| 163 | + attr-dict `:` qualified(type($addr)) `->` type($res) |
| 164 | + }]; |
| 165 | +} |
| 166 | + |
| 167 | +def TTPTR_StoreOp : TPTR_Op<"store", [ |
| 168 | + DeclareOpInterfaceMethods<MemoryEffectsOpInterface> |
| 169 | + ]> { |
| 170 | + let summary = "Store operation"; |
| 171 | + let description = [{ |
| 172 | + The `store` operation is used to write to memory. A store may be marked as |
| 173 | + atomic, volatile, and/or nontemporal, and takes a number of optional |
| 174 | + attributes that specify aliasing information. |
| 175 | + |
| 176 | + An atomic store only supports a limited set of pointer, integer, and |
| 177 | + floating point types, and requires an explicit alignment. |
| 178 | + |
| 179 | + Examples: |
| 180 | + ```mlir |
| 181 | + // A volatile store of a float variable. |
| 182 | + ptr.store volatile %val, %ptr : f32, !ptr.ptr |
| 183 | + |
| 184 | + // A nontemporal store of a float variable. |
| 185 | + ptr.store %val, %ptr {nontemporal} : f32, !ptr.ptr |
| 186 | + |
| 187 | + // An atomic store of an integer variable. |
| 188 | + ptr.store %val, %ptr atomic monotonic {alignment = 8 : i64} |
| 189 | + : i64, !ptr.ptr |
| 190 | + ``` |
| 191 | + }]; |
| 192 | + let arguments = (ins AnyType:$value, |
| 193 | + AnyType:$addr); |
| 194 | + let assemblyFormat = [{ |
| 195 | + $value `,` $addr |
| 196 | + attr-dict `:` type($value) `,` qualified(type($addr)) |
| 197 | + }]; |
| 198 | +} |
| 199 | + |
| 200 | +#endif // TPTR_DIALECT |
0 commit comments