llvm/mlir/lib/Dialect/IRDL/IRDLLoading.cpp

//===- IRDLLoading.cpp - IRDL dialect loading --------------------- C++ -*-===//
//
// This file is licensed 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
//
//===----------------------------------------------------------------------===//
//
// Manages the loading of MLIR objects from IRDL operations.
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/IRDL/IRDLLoading.h"
#include "mlir/Dialect/IRDL/IR/IRDL.h"
#include "mlir/Dialect/IRDL/IR/IRDLInterfaces.h"
#include "mlir/Dialect/IRDL/IRDLSymbols.h"
#include "mlir/Dialect/IRDL/IRDLVerifiers.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/ExtensibleDialect.h"
#include "mlir/IR/OperationSupport.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/SMLoc.h"
#include <numeric>

usingnamespacemlir;
usingnamespacemlir::irdl;

/// Verify that the given list of parameters satisfy the given constraints.
/// This encodes the logic of the verification method for attributes and types
/// defined with IRDL.
static LogicalResult
irdlAttrOrTypeVerifier(function_ref<InFlightDiagnostic()> emitError,
                       ArrayRef<Attribute> params,
                       ArrayRef<std::unique_ptr<Constraint>> constraints,
                       ArrayRef<size_t> paramConstraints) {}

/// Get the operand segment sizes from the attribute dictionary.
LogicalResult getSegmentSizesFromAttr(Operation *op, StringRef elemName,
                                      StringRef attrName, unsigned numElements,
                                      ArrayRef<Variadicity> variadicities,
                                      SmallVectorImpl<int> &segmentSizes) {}

/// Compute the segment sizes of the given element (operands, results).
/// If the operation has more than two non-single elements (optional or
/// variadic), then get the segment sizes from the attribute dictionary.
/// Otherwise, compute the segment sizes from the number of elements.
/// `elemName` should be either `"operand"` or `"result"`.
LogicalResult getSegmentSizes(Operation *op, StringRef elemName,
                              StringRef attrName, unsigned numElements,
                              ArrayRef<Variadicity> variadicities,
                              SmallVectorImpl<int> &segmentSizes) {}

/// Compute the segment sizes of the given operands.
/// If the operation has more than two non-single operands (optional or
/// variadic), then get the segment sizes from the attribute dictionary.
/// Otherwise, compute the segment sizes from the number of operands.
LogicalResult getOperandSegmentSizes(Operation *op,
                                     ArrayRef<Variadicity> variadicities,
                                     SmallVectorImpl<int> &segmentSizes) {}

/// Compute the segment sizes of the given results.
/// If the operation has more than two non-single results (optional or
/// variadic), then get the segment sizes from the attribute dictionary.
/// Otherwise, compute the segment sizes from the number of results.
LogicalResult getResultSegmentSizes(Operation *op,
                                    ArrayRef<Variadicity> variadicities,
                                    SmallVectorImpl<int> &segmentSizes) {}

/// Verify that the given operation satisfies the given constraints.
/// This encodes the logic of the verification method for operations defined
/// with IRDL.
static LogicalResult irdlOpVerifier(
    Operation *op, ConstraintVerifier &verifier,
    ArrayRef<size_t> operandConstrs, ArrayRef<Variadicity> operandVariadicity,
    ArrayRef<size_t> resultConstrs, ArrayRef<Variadicity> resultVariadicity,
    const DenseMap<StringAttr, size_t> &attributeConstrs) {}

static LogicalResult irdlRegionVerifier(
    Operation *op, ConstraintVerifier &verifier,
    ArrayRef<std::unique_ptr<RegionConstraint>> regionsConstraints) {}

llvm::unique_function<LogicalResult(Operation *) const>
mlir::irdl::createVerifier(
    OperationOp op,
    const DenseMap<irdl::TypeOp, std::unique_ptr<DynamicTypeDefinition>> &types,
    const DenseMap<irdl::AttributeOp, std::unique_ptr<DynamicAttrDefinition>>
        &attrs) {}

/// Define and load an operation represented by a `irdl.operation`
/// operation.
static WalkResult loadOperation(
    OperationOp op, ExtensibleDialect *dialect,
    const DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> &types,
    const DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>>
        &attrs) {}

/// Get the verifier of a type or attribute definition.
/// Return nullptr if the definition is invalid.
static DynamicAttrDefinition::VerifierFn getAttrOrTypeVerifier(
    Operation *attrOrTypeDef, ExtensibleDialect *dialect,
    DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> &types,
    DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> &attrs) {}

/// Get the possible bases of a constraint. Return `true` if all bases can
/// potentially be matched.
/// A base is a type or an attribute definition. For instance, the base of
/// `irdl.parametric "!builtin.complex"(...)` is `builtin.complex`.
/// This function returns the following information through arguments:
/// - `paramIds`: the set of type or attribute IDs that are used as bases.
/// - `paramIrdlOps`: the set of IRDL operations that are used as bases.
/// - `isIds`: the set of type or attribute IDs that are used in `irdl.is`
///   constraints.
static bool getBases(Operation *op, SmallPtrSet<TypeID, 4> &paramIds,
                     SmallPtrSet<Operation *, 4> &paramIrdlOps,
                     SmallPtrSet<TypeID, 4> &isIds) {}

/// Check that an any_of is in the subset IRDL can handle.
/// IRDL uses a greedy algorithm to match constraints. This means that if we
/// encounter an `any_of` with multiple constraints, we will match the first
/// constraint that is satisfied. Thus, the order of constraints matter in
/// `any_of` with our current algorithm.
/// In order to make the order of constraints irrelevant, we require that
/// all `any_of` constraint parameters are disjoint. For this, we check that
/// the base parameters are all disjoints between `parametric` operations, and
/// that they are disjoint between `parametric` and `is` operations.
/// This restriction will be relaxed in the future, when we will change our
/// algorithm to be non-greedy.
static LogicalResult checkCorrectAnyOf(AnyOfOp anyOf) {}

/// Load all dialects in the given module, without loading any operation, type
/// or attribute definitions.
static DenseMap<DialectOp, ExtensibleDialect *> loadEmptyDialects(ModuleOp op) {}

/// Preallocate type definitions objects with empty verifiers.
/// This in particular allocates a TypeID for each type definition.
static DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>>
preallocateTypeDefs(ModuleOp op,
                    DenseMap<DialectOp, ExtensibleDialect *> dialects) {}

/// Preallocate attribute definitions objects with empty verifiers.
/// This in particular allocates a TypeID for each attribute definition.
static DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>>
preallocateAttrDefs(ModuleOp op,
                    DenseMap<DialectOp, ExtensibleDialect *> dialects) {}

LogicalResult mlir::irdl::loadDialects(ModuleOp op) {}