16 #define GET_OP_CLASSES
17 #include "mlir/Dialect/Transform/SMTExtension/SMTExtensionOps.cpp.inc"
23 void transform::smt::ConstrainParamsOp::getEffects(
42 <<
"op does not have interpreted semantics yet";
46 auto yieldTerminator =
47 dyn_cast<mlir::smt::YieldOp>(getRegion().front().back());
49 return emitOpError() <<
"expected '"
50 << mlir::smt::YieldOp::getOperationName()
53 auto checkTypes = [](
size_t idx,
Type smtType, StringRef smtDesc,
54 Type paramType, StringRef paramDesc,
56 if (!isa<mlir::smt::BoolType, mlir::smt::IntType, mlir::smt::BitVectorType>(
58 return atOp->emitOpError() <<
"the type of " << smtDesc <<
" #" << idx
59 <<
" is expected to be either a !smt.bool, a "
60 "!smt.int, or a !smt.bv";
62 assert(isa<TransformParamTypeInterface>(paramType) &&
63 "ODS specifies params' type should implement param interface");
64 if (isa<transform::AnyParamType>(paramType))
69 Type typeWrappedByParam = cast<ParamType>(paramType).getType();
71 if (isa<mlir::smt::IntType>(smtType)) {
72 if (!isa<IntegerType>(typeWrappedByParam))
73 return atOp->emitOpError()
74 <<
"the type of " << smtDesc <<
" #" << idx
75 <<
" is !smt.int though the corresponding " << paramDesc
76 <<
" type (" << paramType <<
") is not wrapping an integer type";
77 }
else if (isa<mlir::smt::BoolType>(smtType)) {
78 auto wrappedIntType = dyn_cast<IntegerType>(typeWrappedByParam);
79 if (!wrappedIntType || wrappedIntType.getWidth() != 1)
80 return atOp->emitOpError()
81 <<
"the type of " << smtDesc <<
" #" << idx
82 <<
" is !smt.bool though the corresponding " << paramDesc
83 <<
" type (" << paramType <<
") is not wrapping i1";
84 }
else if (
auto bvSmtType = dyn_cast<mlir::smt::BitVectorType>(smtType)) {
85 auto wrappedIntType = dyn_cast<IntegerType>(typeWrappedByParam);
86 if (!wrappedIntType || wrappedIntType.getWidth() != bvSmtType.getWidth())
87 return atOp->emitOpError()
88 <<
"the type of " << smtDesc <<
" #" << idx <<
" is " << smtType
89 <<
" though the corresponding " << paramDesc <<
" type ("
91 <<
") is not wrapping an integer type of the same bitwidth";
97 if (getOperands().size() != getBody().getNumArguments())
99 "must have the same number of block arguments as operands");
101 for (
auto [idx, operandType, blockArgType] :
104 checkTypes(idx, blockArgType,
"block arg", operandType,
"operand",
106 if (LogicalResult(typeCheckResult).
failed())
107 return typeCheckResult;
110 for (
auto &op : getBody().getOps()) {
111 if (!isa<mlir::smt::SMTDialect>(op.getDialect()))
113 "ops contained in region should belong to SMT-dialect");
116 if (yieldTerminator->getNumOperands() != getNumResults())
117 return yieldTerminator.emitOpError()
118 <<
"expected terminator to have as many operands as the parent op "
122 yieldTerminator->getOperands().getType(), getResultTypes())) {
124 checkTypes(idx, termOperandType,
"terminator operand",
125 cast<transform::ParamType>(resultType),
"result",
127 if (LogicalResult(typeCheckResult).
failed())
128 return typeCheckResult;
The result of a transform IR operation application.
This class represents a diagnostic that is inflight and set to be reported.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
DiagnosedSilenceableFailure emitSilenceableFailure(Location loc, const Twine &message={})
Emits a silenceable failure with the given message.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...