diff --git a/mlir/include/mlir/Transforms/InliningUtils.h b/mlir/include/mlir/Transforms/InliningUtils.h --- a/mlir/include/mlir/Transforms/InliningUtils.h +++ b/mlir/include/mlir/Transforms/InliningUtils.h @@ -194,14 +194,16 @@ /// remappings for the entry arguments to the region. 'resultsToReplace' /// corresponds to any results that should be replaced by terminators within the /// inlined region. 'regionResultTypes' specifies the expected return types of -/// the terminators in the region. 'inlineLoc' is an optional Location that, if -/// provided, will be used to update the inlined operations' location +/// the terminators in the region. 'inlinedOps' collects all the inlined +/// operations for a successful inlining. 'inlineLoc' is an optional Location +/// that, if provided, will be used to update the inlined operations' location /// information. 'shouldCloneInlinedRegion' corresponds to whether the source /// region should be cloned into the 'inlinePoint' or spliced directly. LogicalResult inlineRegion(InlinerInterface &interface, Region *src, Operation *inlinePoint, BlockAndValueMapping &mapper, ValueRange resultsToReplace, TypeRange regionResultTypes, + SmallVectorImpl &inlinedOps, Optional inlineLoc = llvm::None, bool shouldCloneInlinedRegion = true); @@ -218,11 +220,13 @@ /// This function inlines a given region, 'src', of a callable operation, /// 'callable', into the location defined by the given call operation. This /// function returns failure if inlining is not possible, success otherwise. On -/// failure, no changes are made to the module. 'shouldCloneInlinedRegion' +/// failure, no changes are made to the module. 'inlinedOps' collects all the +/// inlined operations for a successful inlining. 'shouldCloneInlinedRegion' /// corresponds to whether the source region should be cloned into the 'call' or /// spliced directly. LogicalResult inlineCall(InlinerInterface &interface, CallOpInterface call, CallableOpInterface callable, Region *src, + SmallVectorImpl &inlinedOps, bool shouldCloneInlinedRegion = true); } // end namespace mlir diff --git a/mlir/lib/Transforms/Inliner.cpp b/mlir/lib/Transforms/Inliner.cpp --- a/mlir/lib/Transforms/Inliner.cpp +++ b/mlir/lib/Transforms/Inliner.cpp @@ -468,9 +468,11 @@ // then inline it in-place and delete the node if successful. bool inlineInPlace = useList.hasOneUseAndDiscardable(it.targetNode); + SmallVector inlinedOps; LogicalResult inlineResult = inlineCall( inliner, call, cast(targetRegion->getParentOp()), - targetRegion, /*shouldCloneInlinedRegion=*/!inlineInPlace); + targetRegion, inlinedOps, + /*shouldCloneInlinedRegion=*/!inlineInPlace); if (failed(inlineResult)) { LLVM_DEBUG(llvm::dbgs() << "** Failed to inline\n"); continue; diff --git a/mlir/lib/Transforms/Utils/InliningUtils.cpp b/mlir/lib/Transforms/Utils/InliningUtils.cpp --- a/mlir/lib/Transforms/Utils/InliningUtils.cpp +++ b/mlir/lib/Transforms/Utils/InliningUtils.cpp @@ -137,13 +137,11 @@ // Inline Methods //===----------------------------------------------------------------------===// -LogicalResult mlir::inlineRegion(InlinerInterface &interface, Region *src, - Operation *inlinePoint, - BlockAndValueMapping &mapper, - ValueRange resultsToReplace, - TypeRange regionResultTypes, - Optional inlineLoc, - bool shouldCloneInlinedRegion) { +LogicalResult mlir::inlineRegion( + InlinerInterface &interface, Region *src, Operation *inlinePoint, + BlockAndValueMapping &mapper, ValueRange resultsToReplace, + TypeRange regionResultTypes, llvm::SmallVectorImpl &inlinedOps, + Optional inlineLoc, bool shouldCloneInlinedRegion) { assert(resultsToReplace.size() == regionResultTypes.size()); // We expect the region to have at least one block. if (src->empty()) @@ -200,6 +198,10 @@ // Process the newly inlined blocks. interface.processInlinedBlocks(newBlocks); + // Collect all the inlined operations. + for (auto &block : newBlocks) + inlinedOps.append(block.begin(), block.end()); + // Handle the case where only a single block was inlined. if (std::next(newBlocks.begin()) == newBlocks.end()) { // Have the interface handle the terminator of this block. @@ -261,8 +263,9 @@ } // Call into the main region inliner function. + SmallVector inlinedOps; return inlineRegion(interface, src, inlinePoint, mapper, resultsToReplace, - resultsToReplace.getTypes(), inlineLoc, + resultsToReplace.getTypes(), inlinedOps, inlineLoc, shouldCloneInlinedRegion); } @@ -291,12 +294,14 @@ /// This function inlines a given region, 'src', of a callable operation, /// 'callable', into the location defined by the given call operation. This /// function returns failure if inlining is not possible, success otherwise. On -/// failure, no changes are made to the module. 'shouldCloneInlinedRegion' -/// corresponds to whether the source region should be cloned into the 'call' or -/// spliced directly. +/// failure, no changes are made to the module. 'inlinedOps' collects all the +/// newly copied operations for a successful inlining. +/// 'shouldCloneInlinedRegion' corresponds to whether the source region should +/// be cloned into the 'call' or spliced directly. LogicalResult mlir::inlineCall(InlinerInterface &interface, CallOpInterface call, CallableOpInterface callable, Region *src, + SmallVectorImpl &inlinedOps, bool shouldCloneInlinedRegion) { // We expect the region to have at least one block. if (src->empty()) @@ -372,7 +377,7 @@ // Attempt to inline the call. if (failed(inlineRegion(interface, src, call, mapper, callResults, - callableResultTypes, call.getLoc(), + callableResultTypes, inlinedOps, call.getLoc(), shouldCloneInlinedRegion))) return cleanupState(); return success();