15#include <mlir/Dialect/SCF/IR/SCF.h>
16#include <mlir/IR/DialectImplementation.h>
17#include <mlir/IR/DialectRegistry.h>
18#include <mlir/IR/MLIRContext.h>
19#include <mlir/Support/LLVM.h>
20#include <mlir/Support/TypeID.h>
22#include <llvm/ADT/SmallVector.h>
23#include <llvm/ADT/SmallVectorExtras.h>
24#include <llvm/ADT/TypeSwitch.h>
38static FailureOr<StringRef> getLabelImpl(Operation *op) {
39 auto attr = dyn_cast_or_null<StringAttr>(op->getDiscardableAttr(
"loop_label"));
43 return attr.getValue();
46struct ScfWhileExternalModel :
public llzk::verif::InvariantTargetOpInterface::ExternalModel<
47 ScfWhileExternalModel, scf::WhileOp> {
48 FailureOr<StringRef> getLabel(Operation *op)
const {
return getLabelImpl(op); }
50 SmallVector<Type> getArgumentTypes(Operation *op)
const {
51 auto whileOp = cast<scf::WhileOp>(op);
60 return llvm::map_to_vector(whileOp.getBeforeArguments(), [](
auto arg) {
66struct ScfForExternalModel :
public llzk::verif::InvariantTargetOpInterface::ExternalModel<
67 ScfForExternalModel, scf::ForOp> {
68 FailureOr<StringRef> getLabel(Operation *op)
const {
return getLabelImpl(op); }
70 SmallVector<Type> getArgumentTypes(Operation *op)
const {
71 auto forOp = cast<scf::ForOp>(op);
75 SmallVector<Type, 4> types;
76 types.reserve(forOp.getNumRegionIterArgs() + 4);
78 {forOp.getLowerBound().getType(), forOp.getInductionVar().getType(),
79 forOp.getUpperBound().getType(), forOp.getStep().getType()}
81 types.append(llvm::map_to_vector(forOp.getInitArgs(), [](
auto arg) { return arg.getType(); }));
87struct InterfacesExtension
88 :
public DialectExtension<InterfacesExtension, llzk::verif::VerifDialect, scf::SCFDialect> {
89 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(InterfacesExtension)
91 void apply(MLIRContext *context, llzk::verif::VerifDialect *, scf::SCFDialect *)
const final {
103 scf::WhileOp::attachInterface<ScfWhileExternalModel>(context);
104 scf::ForOp::attachInterface<ScfForExternalModel>(context);
108 registry.addExtension(
109 TypeID::get<InterfacesExtension>(), std::make_unique<InterfacesExtension>()
113auto llzk::verif::VerifDialect::initialize() ->
void {
120 addInterfaces<LLZKDialectBytecodeInterface<VerifDialect>>();
121 declarePromisedInterface<llzk::verif::InvariantTargetOpInterface, scf::WhileOp>();
122 declarePromisedInterface<llzk::verif::InvariantTargetOpInterface, scf::ForOp>();
void registerExtensions(mlir::DialectRegistry ®istry)
Registers dialect extensions for the verif dialect.
void attachInterfaces(mlir::MLIRContext &context)
Attaches the interfaces defined by the verif dialect to upstream IR elements.