23#include <mlir/Dialect/ControlFlow/IR/ControlFlowOps.h>
24#include <mlir/Transforms/InliningUtils.h>
31template <
typename InlinerImpl,
typename DialectImpl,
typename... RequiredDialects>
32struct BaseInlinerInterface :
public DialectInlinerInterface {
33 using DialectInlinerInterface::DialectInlinerInterface;
35 static void registrationHook(MLIRContext *ctx, DialectImpl *dialect) {
36 dialect->template addInterfaces<InlinerImpl>();
37 if constexpr (
sizeof...(RequiredDialects) != 0) {
38 ctx->loadDialect<RequiredDialects...>();
44struct FuncInlinerInterface
45 :
public BaseInlinerInterface<
46 FuncInlinerInterface, function::FunctionDialect, cf::ControlFlowDialect> {
47 using BaseInlinerInterface::BaseInlinerInterface;
50 bool isLegalToInline(Operation *, Operation *,
bool)
const final {
return true; }
51 bool isLegalToInline(Operation *, Region *,
bool, IRMapping &)
const final {
return true; }
52 bool isLegalToInline(Region *, Region *,
bool, IRMapping &)
const final {
return true; }
54 void handleTerminator(Operation *op, Block *newDest)
const final {
60 if (
auto returnOp = llvm::dyn_cast<function::ReturnOp>(op)) {
61 OpBuilder builder(op);
62 builder.create<cf::BranchOp>(op->getLoc(), newDest, returnOp.getOperands());
67 void handleTerminator(Operation *op, ValueRange valuesToRepl)
const final {
69 assert(llvm::isa<function::ReturnOp>(op));
72 auto returnOp = llvm::cast<function::ReturnOp>(op);
73 assert(returnOp.getNumOperands() == valuesToRepl.size());
74 for (
const auto &it : llvm::enumerate(returnOp.getOperands())) {
75 valuesToRepl[it.index()].replaceAllUsesWith(it.value());
80template <
typename DialectImpl>
81struct FullyLegalForInlining
82 :
public BaseInlinerInterface<FullyLegalForInlining<DialectImpl>, DialectImpl> {
83 using BaseInlinerInterface<FullyLegalForInlining<DialectImpl>, DialectImpl>::BaseInlinerInterface;
85 bool isLegalToInline(Operation *, Operation *,
bool)
const override {
return true; }
86 bool isLegalToInline(Region *, Region *,
bool, IRMapping &)
const override {
return true; }
87 bool isLegalToInline(Operation *op, Region *,
bool, IRMapping &)
const override {
return true; }
95 registry.addExtension(FuncInlinerInterface::registrationHook);
96 registry.addExtension(FullyLegalForInlining<component::StructDialect>::registrationHook);
97 registry.addExtension(FullyLegalForInlining<constrain::ConstrainDialect>::registrationHook);
98 registry.addExtension(FullyLegalForInlining<undef::UndefDialect>::registrationHook);
99 registry.addExtension(FullyLegalForInlining<string::StringDialect>::registrationHook);
100 registry.addExtension(FullyLegalForInlining<polymorphic::PolymorphicDialect>::registrationHook);
101 registry.addExtension(FullyLegalForInlining<felt::FeltDialect>::registrationHook);
102 registry.addExtension(FullyLegalForInlining<global::GlobalDialect>::registrationHook);
103 registry.addExtension(FullyLegalForInlining<boolean::BoolDialect>::registrationHook);
104 registry.addExtension(FullyLegalForInlining<array::ArrayDialect>::registrationHook);
void registerInliningExtensions(DialectRegistry ®istry)