34 #include "llvm/ADT/StringMap.h" 35 #include "llvm/Support/FormatVariadic.h" 36 #include "llvm/Support/PrettyStackTrace.h" 37 #include "llvm/Support/Regex.h" 44 class OperationVerifier {
48 explicit OperationVerifier(
bool verifyRecursively)
49 : verifyRecursively(verifyRecursively) {}
58 verifyBlock(
Block &block,
71 bool verifyRecursively;
77 if (
failed(verifyOperation(op)))
86 if (
failed(verifyDominanceOfContainedRegions(op, domInfo)))
102 if (!llvm::hasSingleElement(*block->
getParent()))
112 if (arg.getOwner() != &block)
113 return emitError(arg.getLoc(),
"block argument not owned by block");
120 "empty block: expect at least a terminator");
129 "operation with block successors must terminate its parent block");
132 if (!verifyRecursively)
139 opsWithIsolatedRegions.push_back(&op);
142 }
else if (
failed(verifyOperation(op))) {
150 if (successor->getParent() != block.getParent())
151 return block.back().emitOpError(
152 "branching to block of a different region");
160 return block.back().
emitError(
"block with no terminator, has ")
173 return op.
emitError(
"null operand found");
178 if (
auto *dialect = attr.getNameDialect())
179 if (
failed(dialect->verifyOperationAttribute(&op, attr)))
186 if (registeredInfo &&
failed(registeredInfo->verifyInvariants(&op)))
192 auto kindInterface = dyn_cast<RegionKindInterface>(op);
196 for (
unsigned i = 0; i < numRegions; ++i) {
197 Region ®ion = regions[i];
209 << i <<
" to have 0 or 1 blocks";
219 "entry block of region may not have predecessors");
223 if (verifyRecursively) {
224 for (
Block &block : region)
225 if (
failed(verifyBlock(block, opsWithIsolatedRegions)))
234 [&](
Operation *op) {
return verifyOpAndDominance(*op); })))
239 if (registeredInfo &&
failed(registeredInfo->verifyRegionInvariants(&op)))
251 <<
"created with unregistered dialect. If this is " 252 "intended, please call allowUnregisteredDialects() on the " 253 "MLIRContext, or use -allow-unregistered-dialect with " 254 "the MLIR opt tool used";
260 return op.
emitError(
"unregistered operation '")
262 <<
"') that does not allow unknown operations";
276 << operandNo <<
" does not dominate this use";
284 note <<
"operand defined here";
286 Block *block2 = useOp->getBlock();
289 if (block1 == block2)
290 note <<
" (op in the same block)";
291 else if (region1 == region2)
292 note <<
" (op in the same region)";
294 note <<
" (op in a parent region)";
296 note <<
" (op in a child region)";
298 note <<
" (op is neither in a parent nor in a child region)";
311 note <<
" (block without parent)";
314 if (block1 == block2)
315 llvm::report_fatal_error(
"Internal error in dominance verification");
316 int index = std::distance(region2->
begin(), block2->getIterator());
317 note <<
"operand defined as a block argument (block #" << index;
318 if (region1 == region2)
319 note <<
" in the same region)";
321 note <<
" in a parent region)";
323 note <<
" in a child region)";
325 note <<
" neither in a parent nor in a child region)";
330 OperationVerifier::verifyDominanceOfContainedRegions(
Operation &op,
334 for (
Block &block : region) {
359 if (
failed(verifyDominanceOfContainedRegions(op, domInfo)))
373 OperationVerifier verifier(verifyRecursively);
374 return verifier.verifyOpAndDominance(*op);
bool properlyDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly dominates operation B, i.e.
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
This class contains a list of basic blocks and a link to the parent operation it is attached to...
static std::string diag(llvm::Value &v)
Operation is a basic unit of execution within MLIR.
RegionKind
The kinds of regions contained in an operation.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
operand_range getOperands()
Returns an iterator on the underlying Value's.
unsigned getNumRegions()
Returns the number of regions held by this operation.
This class represents a diagnostic that is inflight and set to be reported.
Block represents an ordered list of Operations.
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Value getOperand(unsigned idx)
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
A class for computing basic dominance information.
This class provides the API for ops that are known to be terminators.
unsigned getNumSuccessors()
bool isRegistered()
Returns true if this operation has a registered operation description, otherwise false.
Block * getBlock()
Returns the operation block that contains this operation.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
static bool mayBeValidWithoutTerminator(Block *block)
Returns true if this block may be valid without terminator.
bool hasOneBlock()
Return true if this region has exactly one block.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext * getContext()
Return the context this operation is associated with.
LogicalResult failableParallelForEach(MLIRContext *context, IteratorT begin, IteratorT end, FuncT &&func)
Invoke the given function on the elements between [begin, end) asynchronously.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
This class contains all of the information necessary to report a diagnostic to the DiagnosticEngine...
This class represents an efficient way to signal success or failure.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Diagnostic & attachNote(Optional< Location > noteLoc=llvm::None)
Attaches a note to this diagnostic.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, None otherwise.
Location getLoc()
The source location the operation was defined or derived from.
static void diagnoseInvalidOperandDominance(Operation &op, unsigned operandNo)
Emit an error when the specified operand of the specified operation is an invalid use because of domi...
BlockArgListType getArguments()
This class represents an argument of a Block.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
This class indicates that the regions associated with this op don't have terminators.
bool isReachableFromEntry(Block *a) const
Return true if the specified block is reachable from the entry block of its region.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
This class provides the API for ops that are known to be isolated from above.
StringRef getNamespace() const
bool isProperAncestor(Region *other)
Return true if this region is a proper ancestor of the other region.
bool hasNoPredecessors()
Return true if this block has no predecessors.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
bool allowsUnregisteredDialects()
Return true if we allow to create operation for unregistered dialects.
bool allowsUnknownOperations() const
Returns true if this dialect allows for unregistered operations, i.e.
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs, on this operation and any nested operations.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers...
SuccessorRange getSuccessors()
Location getLoc()
Return a location for this region.
OperationName getName()
The name of an operation is the key identifier for it.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...