1 | //===- LLVMInterfaces.cpp - LLVM Interfaces ---------------------*- 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 | // This file defines op interfaces for the LLVM dialect in MLIR. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "mlir/Dialect/LLVMIR/LLVMInterfaces.h" |
14 | |
15 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
16 | #include "mlir/IR/PatternMatch.h" |
17 | |
18 | using namespace mlir; |
19 | using namespace mlir::LLVM; |
20 | |
21 | /// Verifies that all elements of `array` are instances of `Attr`. |
22 | template <class AttrT> |
23 | static LogicalResult isArrayOf(Operation *op, ArrayAttr array) { |
24 | for (Attribute iter : array) |
25 | if (!isa<AttrT>(iter)) |
26 | return op->emitOpError("expected op to return array of " ) |
27 | << AttrT::getMnemonic() << " attributes" ; |
28 | return success(); |
29 | } |
30 | |
31 | //===----------------------------------------------------------------------===// |
32 | // AccessGroupOpInterface |
33 | //===----------------------------------------------------------------------===// |
34 | |
35 | LogicalResult mlir::LLVM::detail::verifyAccessGroupOpInterface(Operation *op) { |
36 | auto iface = cast<AccessGroupOpInterface>(op); |
37 | ArrayAttr accessGroups = iface.getAccessGroupsOrNull(); |
38 | if (!accessGroups) |
39 | return success(); |
40 | |
41 | return isArrayOf<AccessGroupAttr>(op, accessGroups); |
42 | } |
43 | |
44 | //===----------------------------------------------------------------------===// |
45 | // AliasAnalysisOpInterface |
46 | //===----------------------------------------------------------------------===// |
47 | |
48 | LogicalResult |
49 | mlir::LLVM::detail::verifyAliasAnalysisOpInterface(Operation *op) { |
50 | auto iface = cast<AliasAnalysisOpInterface>(op); |
51 | |
52 | if (auto aliasScopes = iface.getAliasScopesOrNull()) |
53 | if (failed(isArrayOf<AliasScopeAttr>(op, aliasScopes))) |
54 | return failure(); |
55 | |
56 | if (auto noAliasScopes = iface.getNoAliasScopesOrNull()) |
57 | if (failed(isArrayOf<AliasScopeAttr>(op, noAliasScopes))) |
58 | return failure(); |
59 | |
60 | ArrayAttr tags = iface.getTBAATagsOrNull(); |
61 | if (!tags) |
62 | return success(); |
63 | |
64 | return isArrayOf<TBAATagAttr>(op, tags); |
65 | } |
66 | |
67 | //===----------------------------------------------------------------------===// |
68 | // DereferenceableOpInterface |
69 | //===----------------------------------------------------------------------===// |
70 | |
71 | LogicalResult |
72 | mlir::LLVM::detail::verifyDereferenceableOpInterface(Operation *op) { |
73 | auto iface = cast<DereferenceableOpInterface>(op); |
74 | |
75 | if (auto derefAttr = iface.getDereferenceableOrNull()) |
76 | if (op->getNumResults() != 1 || |
77 | !mlir::isa<LLVMPointerType>(op->getResult(0).getType())) |
78 | return op->emitOpError( |
79 | message: "expected op to return a single LLVM pointer type" ); |
80 | |
81 | return success(); |
82 | } |
83 | |
84 | SmallVector<Value> mlir::LLVM::AtomicCmpXchgOp::getAccessedOperands() { |
85 | return {getPtr()}; |
86 | } |
87 | |
88 | SmallVector<Value> mlir::LLVM::AtomicRMWOp::getAccessedOperands() { |
89 | return {getPtr()}; |
90 | } |
91 | |
92 | SmallVector<Value> mlir::LLVM::LoadOp::getAccessedOperands() { |
93 | return {getAddr()}; |
94 | } |
95 | |
96 | SmallVector<Value> mlir::LLVM::StoreOp::getAccessedOperands() { |
97 | return {getAddr()}; |
98 | } |
99 | |
100 | SmallVector<Value> mlir::LLVM::MemcpyOp::getAccessedOperands() { |
101 | return {getDst(), getSrc()}; |
102 | } |
103 | |
104 | SmallVector<Value> mlir::LLVM::MemcpyInlineOp::getAccessedOperands() { |
105 | return {getDst(), getSrc()}; |
106 | } |
107 | |
108 | SmallVector<Value> mlir::LLVM::MemmoveOp::getAccessedOperands() { |
109 | return {getDst(), getSrc()}; |
110 | } |
111 | |
112 | SmallVector<Value> mlir::LLVM::MemsetOp::getAccessedOperands() { |
113 | return {getDst()}; |
114 | } |
115 | |
116 | SmallVector<Value> mlir::LLVM::MemsetInlineOp::getAccessedOperands() { |
117 | return {getDst()}; |
118 | } |
119 | |
120 | SmallVector<Value> mlir::LLVM::CallOp::getAccessedOperands() { |
121 | return llvm::filter_to_vector(getArgOperands(), [](Value arg) { |
122 | return isa<LLVMPointerType>(arg.getType()); |
123 | }); |
124 | } |
125 | |
126 | #include "mlir/Dialect/LLVMIR/LLVMInterfaces.cpp.inc" |
127 | |