xref: /llvm-project/mlir/lib/Dialect/LLVMIR/IR/LLVMInterfaces.cpp (revision 78d00a160f34bffd25fef6e29e35a6b3906d6752)
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 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
15 
16 using namespace mlir;
17 using namespace mlir::LLVM;
18 
19 /// Verifies the given array attribute contains symbol references and checks the
20 /// referenced symbol types using the provided verification function.
21 static LogicalResult
22 verifySymbolRefs(Operation *op, StringRef name, ArrayAttr symbolRefs,
23                  llvm::function_ref<LogicalResult(Operation *, SymbolRefAttr)>
24                      verifySymbolType) {
25   assert(symbolRefs && "expected a non-null attribute");
26 
27   // Verify that the attribute is a symbol ref array attribute,
28   // because this constraint is not verified for all attribute
29   // names processed here (e.g. 'tbaa'). This verification
30   // is redundant in some cases.
31   if (!llvm::all_of(symbolRefs, [](Attribute attr) {
32         return attr && llvm::isa<SymbolRefAttr>(attr);
33       }))
34     return op->emitOpError() << name
35                              << " attribute failed to satisfy constraint: "
36                                 "symbol ref array attribute";
37 
38   for (SymbolRefAttr symbolRef : symbolRefs.getAsRange<SymbolRefAttr>()) {
39     StringAttr metadataName = symbolRef.getRootReference();
40     StringAttr symbolName = symbolRef.getLeafReference();
41     // We want @metadata::@symbol, not just @symbol
42     if (metadataName == symbolName) {
43       return op->emitOpError() << "expected '" << symbolRef
44                                << "' to specify a fully qualified reference";
45     }
46     auto metadataOp = SymbolTable::lookupNearestSymbolFrom<LLVM::MetadataOp>(
47         op->getParentOp(), metadataName);
48     if (!metadataOp)
49       return op->emitOpError()
50              << "expected '" << symbolRef << "' to reference a metadata op";
51     Operation *symbolOp =
52         SymbolTable::lookupNearestSymbolFrom(metadataOp, symbolName);
53     if (!symbolOp)
54       return op->emitOpError()
55              << "expected '" << symbolRef << "' to be a valid reference";
56     if (failed(verifySymbolType(symbolOp, symbolRef))) {
57       return failure();
58     }
59   }
60 
61   return success();
62 }
63 
64 /// Verifies the given array attribute contains symbol references that point to
65 /// metadata operations of the given type.
66 template <typename OpTy>
67 LogicalResult verifySymbolRefsPointTo(Operation *op, StringRef name,
68                                       ArrayAttr symbolRefs) {
69   if (!symbolRefs)
70     return success();
71 
72   auto verifySymbolType = [op](Operation *symbolOp,
73                                SymbolRefAttr symbolRef) -> LogicalResult {
74     if (!isa<OpTy>(symbolOp)) {
75       return op->emitOpError()
76              << "expected '" << symbolRef << "' to resolve to a "
77              << OpTy::getOperationName();
78     }
79     return success();
80   };
81   return verifySymbolRefs(op, name, symbolRefs, verifySymbolType);
82 }
83 
84 //===----------------------------------------------------------------------===//
85 // AccessGroupOpInterface
86 //===----------------------------------------------------------------------===//
87 
88 LogicalResult mlir::LLVM::detail::verifyAccessGroupOpInterface(Operation *op) {
89   auto iface = cast<AccessGroupOpInterface>(op);
90   if (failed(verifySymbolRefsPointTo<LLVM::AccessGroupMetadataOp>(
91           iface, "access groups", iface.getAccessGroupsOrNull())))
92     return failure();
93   return success();
94 }
95 
96 //===----------------------------------------------------------------------===//
97 // AliasAnalysisOpInterface
98 //===----------------------------------------------------------------------===//
99 
100 LogicalResult
101 mlir::LLVM::detail::verifyAliasAnalysisOpInterface(Operation *op) {
102   auto iface = cast<AliasAnalysisOpInterface>(op);
103   if (failed(verifySymbolRefsPointTo<LLVM::TBAATagOp>(
104           iface, "tbaa tags", iface.getTBAATagsOrNull())))
105     return failure();
106   return success();
107 }
108 
109 #include "mlir/Dialect/LLVMIR/LLVMInterfaces.cpp.inc"
110