diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 78a8ed9c5c6f..034975e0cbca 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -40,6 +40,7 @@ #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Support/LLVM.h" #include "mlir/Support/LogicalResult.h" +#include "mlir/Transforms/InliningUtils.h" using namespace mlir; @@ -114,6 +115,40 @@ struct CIROpAsmDialectInterface : public OpAsmDialectInterface { return AliasResult::NoAlias; } }; + +// Minimal interface to inline region with only one block for now (not handling +// the terminator remapping), assuming everything is inlinable. +struct CIRInlinerInterface : DialectInlinerInterface { + using DialectInlinerInterface::DialectInlinerInterface; + // Always allows inlining. + bool isLegalToInline(Operation *call, Operation *callable, + bool wouldBeCloned) const final override { + return true; + } + + // Always allows inlining. + bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned, + IRMapping &valueMapping) const final override { + return true; + } + + // Always allows inlining. + bool isLegalToInline(Operation *op, Region *, bool wouldBeCloned, + IRMapping &) const final override { + return true; + } + + // Handle the terminator in the case of a single block + void handleTerminator(Operation *op, + ValueRange valuesToReplace) const final override { + // Only handle cir.return for now + if (auto returnOp = dyn_cast(op)) + for (auto &&[value, operand] : + llvm::zip(valuesToReplace, returnOp.getOperands())) + value.replaceAllUsesWith(operand); + } +}; + } // namespace /// Dialect initialization, the instance will be owned by the context. This is @@ -125,7 +160,7 @@ void cir::CIRDialect::initialize() { #define GET_OP_LIST #include "clang/CIR/Dialect/IR/CIROps.cpp.inc" >(); - addInterfaces(); + addInterfaces(); } Operation *cir::CIRDialect::materializeConstant(mlir::OpBuilder &builder,