1 //===- MemRefBuilder.h - Helper for LLVM MemRef equivalents -----*- 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 // Provides a convenience API for emitting IR that inspects or constructs values 10 // of LLVM dialect structure type that correspond to ranked or unranked memref. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef MLIR_CONVERSION_LLVMCOMMON_MEMREFBUILDER_H 15 #define MLIR_CONVERSION_LLVMCOMMON_MEMREFBUILDER_H 16 17 #include "mlir/Conversion/LLVMCommon/StructBuilder.h" 18 #include "mlir/IR/OperationSupport.h" 19 20 namespace mlir { 21 22 class LLVMTypeConverter; 23 class MemRefType; 24 class UnrankedMemRefType; 25 26 namespace LLVM { 27 class LLVMPointerType; 28 } // namespace LLVM 29 30 /// Helper class to produce LLVM dialect operations extracting or inserting 31 /// elements of a MemRef descriptor. Wraps a Value pointing to the descriptor. 32 /// The Value may be null, in which case none of the operations are valid. 33 class MemRefDescriptor : public StructBuilder { 34 public: 35 /// Construct a helper for the given descriptor value. 36 explicit MemRefDescriptor(Value descriptor); 37 /// Builds IR creating an `undef` value of the descriptor type. 38 static MemRefDescriptor undef(OpBuilder &builder, Location loc, 39 Type descriptorType); 40 /// Builds IR creating a MemRef descriptor that represents `type` and 41 /// populates it with static shape and stride information extracted from the 42 /// type. 43 static MemRefDescriptor fromStaticShape(OpBuilder &builder, Location loc, 44 LLVMTypeConverter &typeConverter, 45 MemRefType type, Value memory); 46 47 /// Builds IR extracting the allocated pointer from the descriptor. 48 Value allocatedPtr(OpBuilder &builder, Location loc); 49 /// Builds IR inserting the allocated pointer into the descriptor. 50 void setAllocatedPtr(OpBuilder &builder, Location loc, Value ptr); 51 52 /// Builds IR extracting the aligned pointer from the descriptor. 53 Value alignedPtr(OpBuilder &builder, Location loc); 54 55 /// Builds IR inserting the aligned pointer into the descriptor. 56 void setAlignedPtr(OpBuilder &builder, Location loc, Value ptr); 57 58 /// Builds IR extracting the offset from the descriptor. 59 Value offset(OpBuilder &builder, Location loc); 60 61 /// Builds IR inserting the offset into the descriptor. 62 void setOffset(OpBuilder &builder, Location loc, Value offset); 63 void setConstantOffset(OpBuilder &builder, Location loc, uint64_t offset); 64 65 /// Builds IR extracting the pos-th size from the descriptor. 66 Value size(OpBuilder &builder, Location loc, unsigned pos); 67 Value size(OpBuilder &builder, Location loc, Value pos, int64_t rank); 68 69 /// Builds IR inserting the pos-th size into the descriptor 70 void setSize(OpBuilder &builder, Location loc, unsigned pos, Value size); 71 void setConstantSize(OpBuilder &builder, Location loc, unsigned pos, 72 uint64_t size); 73 74 /// Builds IR extracting the pos-th size from the descriptor. 75 Value stride(OpBuilder &builder, Location loc, unsigned pos); 76 77 /// Builds IR inserting the pos-th stride into the descriptor 78 void setStride(OpBuilder &builder, Location loc, unsigned pos, Value stride); 79 void setConstantStride(OpBuilder &builder, Location loc, unsigned pos, 80 uint64_t stride); 81 82 /// Returns the type of array element in this descriptor. getIndexType()83 Type getIndexType() { return indexType; }; 84 85 /// Returns the (LLVM) pointer type this descriptor contains. 86 LLVM::LLVMPointerType getElementPtrType(); 87 88 /// Builds IR populating a MemRef descriptor structure from a list of 89 /// individual values composing that descriptor, in the following order: 90 /// - allocated pointer; 91 /// - aligned pointer; 92 /// - offset; 93 /// - <rank> sizes; 94 /// - <rank> shapes; 95 /// where <rank> is the MemRef rank as provided in `type`. 96 static Value pack(OpBuilder &builder, Location loc, 97 LLVMTypeConverter &converter, MemRefType type, 98 ValueRange values); 99 100 /// Builds IR extracting individual elements of a MemRef descriptor structure 101 /// and returning them as `results` list. 102 static void unpack(OpBuilder &builder, Location loc, Value packed, 103 MemRefType type, SmallVectorImpl<Value> &results); 104 105 /// Returns the number of non-aggregate values that would be produced by 106 /// `unpack`. 107 static unsigned getNumUnpackedValues(MemRefType type); 108 109 private: 110 // Cached index type. 111 Type indexType; 112 }; 113 114 /// Helper class allowing the user to access a range of Values that correspond 115 /// to an unpacked memref descriptor using named accessors. This does not own 116 /// the values. 117 class MemRefDescriptorView { 118 public: 119 /// Constructs the view from a range of values. Infers the rank from the size 120 /// of the range. 121 explicit MemRefDescriptorView(ValueRange range); 122 123 /// Returns the allocated pointer Value. 124 Value allocatedPtr(); 125 126 /// Returns the aligned pointer Value. 127 Value alignedPtr(); 128 129 /// Returns the offset Value. 130 Value offset(); 131 132 /// Returns the pos-th size Value. 133 Value size(unsigned pos); 134 135 /// Returns the pos-th stride Value. 136 Value stride(unsigned pos); 137 138 private: 139 /// Rank of the memref the descriptor is pointing to. 140 int rank; 141 /// Underlying range of Values. 142 ValueRange elements; 143 }; 144 145 class UnrankedMemRefDescriptor : public StructBuilder { 146 public: 147 /// Construct a helper for the given descriptor value. 148 explicit UnrankedMemRefDescriptor(Value descriptor); 149 /// Builds IR creating an `undef` value of the descriptor type. 150 static UnrankedMemRefDescriptor undef(OpBuilder &builder, Location loc, 151 Type descriptorType); 152 153 /// Builds IR extracting the rank from the descriptor 154 Value rank(OpBuilder &builder, Location loc); 155 /// Builds IR setting the rank in the descriptor 156 void setRank(OpBuilder &builder, Location loc, Value value); 157 /// Builds IR extracting ranked memref descriptor ptr 158 Value memRefDescPtr(OpBuilder &builder, Location loc); 159 /// Builds IR setting ranked memref descriptor ptr 160 void setMemRefDescPtr(OpBuilder &builder, Location loc, Value value); 161 162 /// Builds IR populating an unranked MemRef descriptor structure from a list 163 /// of individual constituent values in the following order: 164 /// - rank of the memref; 165 /// - pointer to the memref descriptor. 166 static Value pack(OpBuilder &builder, Location loc, 167 LLVMTypeConverter &converter, UnrankedMemRefType type, 168 ValueRange values); 169 170 /// Builds IR extracting individual elements that compose an unranked memref 171 /// descriptor and returns them as `results` list. 172 static void unpack(OpBuilder &builder, Location loc, Value packed, 173 SmallVectorImpl<Value> &results); 174 175 /// Returns the number of non-aggregate values that would be produced by 176 /// `unpack`. getNumUnpackedValues()177 static unsigned getNumUnpackedValues() { return 2; } 178 179 /// Builds IR computing the sizes in bytes (suitable for opaque allocation) 180 /// and appends the corresponding values into `sizes`. 181 static void computeSizes(OpBuilder &builder, Location loc, 182 LLVMTypeConverter &typeConverter, 183 ArrayRef<UnrankedMemRefDescriptor> values, 184 SmallVectorImpl<Value> &sizes); 185 186 /// TODO: The following accessors don't take alignment rules between elements 187 /// of the descriptor struct into account. For some architectures, it might be 188 /// necessary to extend them and to use `llvm::DataLayout` contained in 189 /// `LLVMTypeConverter`. 190 191 /// Builds IR extracting the allocated pointer from the descriptor. 192 static Value allocatedPtr(OpBuilder &builder, Location loc, 193 Value memRefDescPtr, Type elemPtrPtrType); 194 /// Builds IR inserting the allocated pointer into the descriptor. 195 static void setAllocatedPtr(OpBuilder &builder, Location loc, 196 Value memRefDescPtr, Type elemPtrPtrType, 197 Value allocatedPtr); 198 199 /// Builds IR extracting the aligned pointer from the descriptor. 200 static Value alignedPtr(OpBuilder &builder, Location loc, 201 LLVMTypeConverter &typeConverter, Value memRefDescPtr, 202 Type elemPtrPtrType); 203 /// Builds IR inserting the aligned pointer into the descriptor. 204 static void setAlignedPtr(OpBuilder &builder, Location loc, 205 LLVMTypeConverter &typeConverter, 206 Value memRefDescPtr, Type elemPtrPtrType, 207 Value alignedPtr); 208 209 /// Builds IR extracting the offset from the descriptor. 210 static Value offset(OpBuilder &builder, Location loc, 211 LLVMTypeConverter &typeConverter, Value memRefDescPtr, 212 Type elemPtrPtrType); 213 /// Builds IR inserting the offset into the descriptor. 214 static void setOffset(OpBuilder &builder, Location loc, 215 LLVMTypeConverter &typeConverter, Value memRefDescPtr, 216 Type elemPtrPtrType, Value offset); 217 218 /// Builds IR extracting the pointer to the first element of the size array. 219 static Value sizeBasePtr(OpBuilder &builder, Location loc, 220 LLVMTypeConverter &typeConverter, 221 Value memRefDescPtr, 222 LLVM::LLVMPointerType elemPtrPtrType); 223 /// Builds IR extracting the size[index] from the descriptor. 224 static Value size(OpBuilder &builder, Location loc, 225 LLVMTypeConverter &typeConverter, Value sizeBasePtr, 226 Value index); 227 /// Builds IR inserting the size[index] into the descriptor. 228 static void setSize(OpBuilder &builder, Location loc, 229 LLVMTypeConverter &typeConverter, Value sizeBasePtr, 230 Value index, Value size); 231 232 /// Builds IR extracting the pointer to the first element of the stride array. 233 static Value strideBasePtr(OpBuilder &builder, Location loc, 234 LLVMTypeConverter &typeConverter, 235 Value sizeBasePtr, Value rank); 236 /// Builds IR extracting the stride[index] from the descriptor. 237 static Value stride(OpBuilder &builder, Location loc, 238 LLVMTypeConverter &typeConverter, Value strideBasePtr, 239 Value index, Value stride); 240 /// Builds IR inserting the stride[index] into the descriptor. 241 static void setStride(OpBuilder &builder, Location loc, 242 LLVMTypeConverter &typeConverter, Value strideBasePtr, 243 Value index, Value stride); 244 }; 245 246 } // namespace mlir 247 248 #endif // MLIR_CONVERSION_LLVMCOMMON_MEMREFBUILDER_H 249