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