llvm-project/mlir/lib/Dialect/LLVMIR/IR/LLVMInterfaces.cpp
Tobias Gysi edfefd7fc5 [mlir][llvm] Add AliasAnalysis and AccessGroup interfaces.
The revision introduces two interfaces that provide access to
the alias analysis and access group metadata attributes. The
AliasAnalysis interface combines all alias analysis related
attributes (alias, noalias, and tbaa) similar to LLVM's getAAMetadata
method, while the AccessGroup interface is dedicated to the
access group metadata.

Previously, only the load and store operations supported alias analysis
and access group metadata. This revision extends this support to the
atomic operations. A follow up revision will also add support for the
memcopy, memset, and memove intrinsics. The interfaces then provide
convenient access to the metadata attributes and eliminate the need
of TypeSwitch or string based attribute access.

The revision still relies on string based attribute access for
the translation to LLVM IR (except for tbaa metadata). Only once
the the memory access intrinsics also implement the new interfaces,
the translation to LLVM IR can be fully switched to use interface
based attribute accesses.

Depends on D144875

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D144851
2023-03-01 09:27:06 +01:00

116 lines
4.6 KiB
C++

//===- LLVMInterfaces.cpp - LLVM Interfaces ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines op interfaces for the LLVM dialect in MLIR.
//
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/LLVMIR/LLVMInterfaces.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
using namespace mlir;
using namespace mlir::LLVM;
/// Verifies the given array attribute contains symbol references and checks the
/// referenced symbol types using the provided verification function.
static LogicalResult
verifySymbolRefs(Operation *op, StringRef name, ArrayAttr symbolRefs,
llvm::function_ref<LogicalResult(Operation *, SymbolRefAttr)>
verifySymbolType) {
assert(symbolRefs && "expected a non-null attribute");
// Verify that the attribute is a symbol ref array attribute,
// because this constraint is not verified for all attribute
// names processed here (e.g. 'tbaa'). This verification
// is redundant in some cases.
if (!llvm::all_of(symbolRefs, [](Attribute attr) {
return attr && attr.isa<SymbolRefAttr>();
}))
return op->emitOpError() << name
<< " attribute failed to satisfy constraint: "
"symbol ref array attribute";
for (SymbolRefAttr symbolRef : symbolRefs.getAsRange<SymbolRefAttr>()) {
StringAttr metadataName = symbolRef.getRootReference();
StringAttr symbolName = symbolRef.getLeafReference();
// We want @metadata::@symbol, not just @symbol
if (metadataName == symbolName) {
return op->emitOpError() << "expected '" << symbolRef
<< "' to specify a fully qualified reference";
}
auto metadataOp = SymbolTable::lookupNearestSymbolFrom<LLVM::MetadataOp>(
op->getParentOp(), metadataName);
if (!metadataOp)
return op->emitOpError()
<< "expected '" << symbolRef << "' to reference a metadata op";
Operation *symbolOp =
SymbolTable::lookupNearestSymbolFrom(metadataOp, symbolName);
if (!symbolOp)
return op->emitOpError()
<< "expected '" << symbolRef << "' to be a valid reference";
if (failed(verifySymbolType(symbolOp, symbolRef))) {
return failure();
}
}
return success();
}
/// Verifies the given array attribute contains symbol references that point to
/// metadata operations of the given type.
template <typename OpTy>
LogicalResult verifySymbolRefsPointTo(Operation *op, StringRef name,
ArrayAttr symbolRefs) {
if (!symbolRefs)
return success();
auto verifySymbolType = [op](Operation *symbolOp,
SymbolRefAttr symbolRef) -> LogicalResult {
if (!isa<OpTy>(symbolOp)) {
return op->emitOpError()
<< "expected '" << symbolRef << "' to resolve to a "
<< OpTy::getOperationName();
}
return success();
};
return verifySymbolRefs(op, name, symbolRefs, verifySymbolType);
}
//===----------------------------------------------------------------------===//
// AccessGroupOpInterface
//===----------------------------------------------------------------------===//
LogicalResult mlir::LLVM::detail::verifyAccessGroupOpInterface(Operation *op) {
auto iface = cast<AccessGroupOpInterface>(op);
if (failed(verifySymbolRefsPointTo<LLVM::AccessGroupMetadataOp>(
iface, "access groups", iface.getAccessGroupsOrNull())))
return failure();
return success();
}
//===----------------------------------------------------------------------===//
// AliasAnalysisOpInterface
//===----------------------------------------------------------------------===//
LogicalResult
mlir::LLVM::detail::verifyAliasAnalysisOpInterface(Operation *op) {
auto iface = cast<AliasAnalysisOpInterface>(op);
if (failed(verifySymbolRefsPointTo<LLVM::AliasScopeMetadataOp>(
iface, "alias scopes", iface.getAliasScopesOrNull())))
return failure();
if (failed(verifySymbolRefsPointTo<LLVM::AliasScopeMetadataOp>(
iface, "noalias scopes", iface.getNoAliasScopesOrNull())))
return failure();
if (failed(verifySymbolRefsPointTo<LLVM::TBAATagOp>(
iface, "tbaa tags", iface.getTBAATagsOrNull())))
return failure();
return success();
}
#include "mlir/Dialect/LLVMIR/LLVMInterfaces.cpp.inc"