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