xref: /llvm-project/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp (revision b43c50490c5964b3b1aa1b95a9025a5b5942a46e)
1 //===----------------------------------------------------------------------===//
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 #include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
10 #include "mlir/Dialect/Arith/IR/Arith.h"
11 #include "mlir/Dialect/MemRef/IR/MemRef.h"
12 #include "mlir/Interfaces/SideEffectInterfaces.h"
13 #include "mlir/Transforms/InliningUtils.h"
14 #include <optional>
15 
16 using namespace mlir;
17 using namespace mlir::memref;
18 
19 #include "mlir/Dialect/MemRef/IR/MemRefOpsDialect.cpp.inc"
20 
21 //===----------------------------------------------------------------------===//
22 // MemRefDialect Dialect Interfaces
23 //===----------------------------------------------------------------------===//
24 
25 namespace {
26 struct MemRefInlinerInterface : public DialectInlinerInterface {
27   using DialectInlinerInterface::DialectInlinerInterface;
28   bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned,
29                        IRMapping &valueMapping) const final {
30     return true;
31   }
32   bool isLegalToInline(Operation *, Region *, bool wouldBeCloned,
33                        IRMapping &) const final {
34     return true;
35   }
36 };
37 } // namespace
38 
39 void mlir::memref::MemRefDialect::initialize() {
40   addOperations<
41 #define GET_OP_LIST
42 #include "mlir/Dialect/MemRef/IR/MemRefOps.cpp.inc"
43       >();
44   addInterfaces<MemRefInlinerInterface>();
45   declarePromisedInterface<MemRefDialect, ConvertToLLVMPatternInterface>();
46 }
47 
48 /// Finds the unique dealloc operation (if one exists) for `allocValue`.
49 std::optional<Operation *> mlir::memref::findDealloc(Value allocValue) {
50   Operation *dealloc = nullptr;
51   for (Operation *user : allocValue.getUsers()) {
52     if (!hasEffect<MemoryEffects::Free>(user, allocValue))
53       continue;
54     // If we found a realloc instead of dealloc, return std::nullopt.
55     if (isa<memref::ReallocOp>(user))
56       return std::nullopt;
57     // If we found > 1 dealloc, return std::nullopt.
58     if (dealloc)
59       return std::nullopt;
60     dealloc = user;
61   }
62   return dealloc;
63 }
64