#include "mlir/IR/BuiltinDialect.h"
#include "BuiltinDialectBytecode.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectResourceBlobManager.h"
#include "mlir/IR/IRMapping.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/TypeRange.h"
using namespace mlir;
#include "mlir/IR/BuiltinDialect.cpp.inc"
using BuiltinBlobManagerInterface =
ResourceBlobManagerDialectInterfaceBase<DenseResourceElementsHandle>;
namespace {
struct BuiltinOpAsmDialectInterface : public OpAsmDialectInterface {
BuiltinOpAsmDialectInterface(Dialect *dialect,
BuiltinBlobManagerInterface &mgr)
: OpAsmDialectInterface(dialect), blobManager(mgr) {}
AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
if (llvm::isa<AffineMapAttr>(attr)) {
os << "map";
return AliasResult::OverridableAlias;
}
if (llvm::isa<IntegerSetAttr>(attr)) {
os << "set";
return AliasResult::OverridableAlias;
}
if (llvm::isa<LocationAttr>(attr)) {
os << "loc";
return AliasResult::OverridableAlias;
}
if (auto distinct = llvm::dyn_cast<DistinctAttr>(attr))
if (!llvm::isa<UnitAttr>(distinct.getReferencedAttr())) {
os << "distinct";
return AliasResult::OverridableAlias;
}
return AliasResult::NoAlias;
}
AliasResult getAlias(Type type, raw_ostream &os) const final {
if (auto tupleType = llvm::dyn_cast<TupleType>(type)) {
if (tupleType.size() > 16) {
os << "tuple";
return AliasResult::OverridableAlias;
}
}
return AliasResult::NoAlias;
}
std::string
getResourceKey(const AsmDialectResourceHandle &handle) const override {
return cast<DenseResourceElementsHandle>(handle).getKey().str();
}
FailureOr<AsmDialectResourceHandle>
declareResource(StringRef key) const final {
return blobManager.insert(key);
}
LogicalResult parseResource(AsmParsedResourceEntry &entry) const final {
FailureOr<AsmResourceBlob> blob = entry.parseAsBlob();
if (failed(blob))
return failure();
blobManager.update(entry.getKey(), std::move(*blob));
return success();
}
void
buildResources(Operation *op,
const SetVector<AsmDialectResourceHandle> &referencedResources,
AsmResourceBuilder &provider) const final {
blobManager.buildResources(provider, referencedResources.getArrayRef());
}
private:
BuiltinBlobManagerInterface &blobManager;
};
}
void BuiltinDialect::initialize() {
registerTypes();
registerAttributes();
registerLocationAttributes();
addOperations<
#define GET_OP_LIST
#include "mlir/IR/BuiltinOps.cpp.inc"
>();
auto &blobInterface = addInterface<BuiltinBlobManagerInterface>();
addInterface<BuiltinOpAsmDialectInterface>(blobInterface);
builtin_dialect_detail::addBytecodeInterface(this);
}
void ModuleOp::build(OpBuilder &builder, OperationState &state,
std::optional<StringRef> name) {
state.addRegion()->emplaceBlock();
if (name) {
state.attributes.push_back(builder.getNamedAttr(
mlir::SymbolTable::getSymbolAttrName(), builder.getStringAttr(*name)));
}
}
ModuleOp ModuleOp::create(Location loc, std::optional<StringRef> name) {
OpBuilder builder(loc->getContext());
return builder.create<ModuleOp>(loc, name);
}
DataLayoutSpecInterface ModuleOp::getDataLayoutSpec() {
for (NamedAttribute attr : getOperation()->getAttrs())
if (auto spec = llvm::dyn_cast<DataLayoutSpecInterface>(attr.getValue()))
return spec;
return {};
}
TargetSystemSpecInterface ModuleOp::getTargetSystemSpec() {
for (NamedAttribute attr : getOperation()->getAttrs())
if (auto spec = llvm::dyn_cast<TargetSystemSpecInterface>(attr.getValue()))
return spec;
return {};
}
LogicalResult ModuleOp::verify() {
for (auto attr : (*this)->getAttrs()) {
if (!attr.getName().strref().contains('.') &&
!llvm::is_contained(
ArrayRef<StringRef>{mlir::SymbolTable::getSymbolAttrName(),
mlir::SymbolTable::getVisibilityAttrName()},
attr.getName().strref()))
return emitOpError() << "can only contain attributes with "
"dialect-prefixed names, found: '"
<< attr.getName().getValue() << "'";
}
StringRef layoutSpecAttrName;
DataLayoutSpecInterface layoutSpec;
for (const NamedAttribute &na : (*this)->getAttrs()) {
if (auto spec = llvm::dyn_cast<DataLayoutSpecInterface>(na.getValue())) {
if (layoutSpec) {
InFlightDiagnostic diag =
emitOpError() << "expects at most one data layout attribute";
diag.attachNote() << "'" << layoutSpecAttrName
<< "' is a data layout attribute";
diag.attachNote() << "'" << na.getName().getValue()
<< "' is a data layout attribute";
}
layoutSpecAttrName = na.getName().strref();
layoutSpec = spec;
}
}
return success();
}
LogicalResult
UnrealizedConversionCastOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &foldResults) {
OperandRange operands = getInputs();
ResultRange results = getOutputs();
if (operands.getType() == results.getType()) {
foldResults.append(operands.begin(), operands.end());
return success();
}
if (operands.empty())
return failure();
Value firstInput = operands.front();
auto inputOp = firstInput.getDefiningOp<UnrealizedConversionCastOp>();
if (!inputOp || inputOp.getResults() != operands ||
inputOp.getOperandTypes() != results.getTypes())
return failure();
foldResults.append(inputOp->operand_begin(), inputOp->operand_end());
return success();
}
LogicalResult UnrealizedConversionCastOp::verify() {
if (getNumResults() == 0)
return emitOpError() << "expected at least one result for cast operation";
return success();
}
#define GET_OP_CLASSES
#include "mlir/IR/BuiltinOps.cpp.inc"