1 //===- AllocLikeConversion.h - Convert allocation ops to LLVM ---*- 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 #ifndef MLIR_CONVERSION_MEMREFTOLLVM_ALLOCLIKECONVERSION_H 10 #define MLIR_CONVERSION_MEMREFTOLLVM_ALLOCLIKECONVERSION_H 11 12 #include "mlir/Conversion/LLVMCommon/Pattern.h" 13 14 namespace mlir { 15 16 /// Lowering for AllocOp and AllocaOp. 17 struct AllocLikeOpLLVMLowering : public ConvertToLLVMPattern { 18 using ConvertToLLVMPattern::createIndexConstant; 19 using ConvertToLLVMPattern::getIndexType; 20 using ConvertToLLVMPattern::getVoidPtrType; 21 AllocLikeOpLLVMLoweringAllocLikeOpLLVMLowering22 explicit AllocLikeOpLLVMLowering(StringRef opName, 23 LLVMTypeConverter &converter) 24 : ConvertToLLVMPattern(opName, &converter.getContext(), converter) {} 25 26 protected: 27 // Returns 'input' aligned up to 'alignment'. Computes 28 // bumped = input + alignement - 1 29 // aligned = bumped - bumped % alignment 30 static Value createAligned(ConversionPatternRewriter &rewriter, Location loc, 31 Value input, Value alignment); 32 33 /// Allocates the underlying buffer. Returns the allocated pointer and the 34 /// aligned pointer. 35 virtual std::tuple<Value, Value> 36 allocateBuffer(ConversionPatternRewriter &rewriter, Location loc, 37 Value sizeBytes, Operation *op) const = 0; 38 39 private: getMemRefResultTypeAllocLikeOpLLVMLowering40 static MemRefType getMemRefResultType(Operation *op) { 41 return op->getResult(0).getType().cast<MemRefType>(); 42 } 43 44 // An `alloc` is converted into a definition of a memref descriptor value and 45 // a call to `malloc` to allocate the underlying data buffer. The memref 46 // descriptor is of the LLVM structure type where: 47 // 1. the first element is a pointer to the allocated (typed) data buffer, 48 // 2. the second element is a pointer to the (typed) payload, aligned to the 49 // specified alignment, 50 // 3. the remaining elements serve to store all the sizes and strides of the 51 // memref using LLVM-converted `index` type. 52 // 53 // Alignment is performed by allocating `alignment` more bytes than 54 // requested and shifting the aligned pointer relative to the allocated 55 // memory. Note: `alignment - <minimum malloc alignment>` would actually be 56 // sufficient. If alignment is unspecified, the two pointers are equal. 57 58 // An `alloca` is converted into a definition of a memref descriptor value and 59 // an llvm.alloca to allocate the underlying data buffer. 60 LogicalResult 61 matchAndRewrite(Operation *op, ArrayRef<Value> operands, 62 ConversionPatternRewriter &rewriter) const override; 63 }; 64 65 } // namespace mlir 66 67 #endif // MLIR_CONVERSION_MEMREFTOLLVM_ALLOCLIKECONVERSION_H 68