//===- Verifier.cpp - MLIR Verifier Implementation ------------------------===// // // 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 implements the verify() methods on the various IR types, performing // (potentially expensive) checks on the holistic structure of the code. This // can be used for detecting bugs in compiler transformations and hand written // .mlir files. // // The checks in this file are only for things that can occur as part of IR // transformations: e.g. violation of dominance information, malformed operation // attributes, etc. MLIR supports transformations moving IR through locally // invalid states (e.g. unlinking an operation from a block before re-inserting // it in a new place), but each transformation must complete with the IR in a // valid form. // // This should not check for things that are always wrong by construction (e.g. // attributes or other immutable structures that are incorrect), because those // are not mutable and can be checked at time of construction. // //===----------------------------------------------------------------------===// #include "mlir/IR/Verifier.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/Dominance.h" #include "mlir/IR/Operation.h" #include "mlir/IR/RegionKindInterface.h" #include "mlir/IR/Threading.h" #include "llvm/ADT/DenseMapInfoVariant.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Regex.h" #include <atomic> #include <optional> usingnamespacemlir; namespace { /// This class encapsulates all the state used to verify an operation region. class OperationVerifier { … }; } // namespace LogicalResult OperationVerifier::verifyOpAndDominance(Operation &op) { … } /// Returns true if this block may be valid without terminator. That is if: /// - it does not have a parent region. /// - Or the parent region have a single block and: /// - This region does not have a parent op. /// - Or the parent op is unregistered. /// - Or the parent op has the NoTerminator trait. static bool mayBeValidWithoutTerminator(Block *block) { … } LogicalResult OperationVerifier::verifyOnEntrance(Block &block) { … } LogicalResult OperationVerifier::verifyOnExit(Block &block) { … } LogicalResult OperationVerifier::verifyOnEntrance(Operation &op) { … } LogicalResult OperationVerifier::verifyOnExit(Operation &op) { … } /// Verify the properties and dominance relationships of this operation, /// stopping region "recursion" at any "isolated from above operations". /// Such ops are collected separately and verified inside /// verifyBlockPostChildren. LogicalResult OperationVerifier::verifyOperation(Operation &op) { … } //===----------------------------------------------------------------------===// // Dominance Checking //===----------------------------------------------------------------------===// /// Emit an error when the specified operand of the specified operation is an /// invalid use because of dominance properties. static void diagnoseInvalidOperandDominance(Operation &op, unsigned operandNo) { … } /// Verify the dominance of each of the nested blocks within the given operation LogicalResult OperationVerifier::verifyDominanceOfContainedRegions(Operation &op, DominanceInfo &domInfo) { … } //===----------------------------------------------------------------------===// // Entrypoint //===----------------------------------------------------------------------===// LogicalResult mlir::verify(Operation *op, bool verifyRecursively) { … }