21#include "llvm/Support/DebugLog.h"
24#define GEN_PASS_DEF_INLINERPASS
25#include "mlir/Transforms/Passes.h.inc"
28#define DEBUG_TYPE "inliner-pass"
42class InlinerPass :
public impl::InlinerPassBase<InlinerPass> {
44 using impl::InlinerPassBase<InlinerPass>::InlinerPassBase;
46 InlinerPass(
const InlinerPass &) =
default;
47 InlinerPass(std::function<
void(OpPassManager &)> defaultPipeline);
48 InlinerPass(std::function<
void(OpPassManager &)> defaultPipeline,
49 llvm::StringMap<OpPassManager> opPipelines);
50 void runOnOperation()
override;
59 static LogicalResult runPipelineHelper(Pass &pass, OpPassManager &pipeline,
61 return mlir::cast<InlinerPass>(pass).runPipeline(pipeline, op);
69 LogicalResult initializeOptions(
71 function_ref<LogicalResult(
const Twine &)> errorHandler)
override;
80InlinerPass::InlinerPass(
82 : InlinerPass(std::move(defaultPipelineArg),
85InlinerPass::InlinerPass(std::function<
void(
OpPassManager &)> defaultPipeline,
86 llvm::StringMap<OpPassManager> opPipelines)
87 : config(std::move(defaultPipeline), maxInliningIterations) {
88 if (opPipelines.empty())
92 for (
auto &it : opPipelines)
93 opPipelineList.addValue(it.second);
94 config.setOpPipelines(std::move(opPipelines));
99 unsigned inliningThreshold) {
101 if (inliningThreshold == 0U)
104 if (inliningThreshold == -1U)
110 assert(calleeRegion && callerRegion &&
"unexpected external node");
112 auto countOps = [](
Region *region) {
114 region->walk([&](
Operation *) { ++count; });
118 unsigned callerOps = countOps(callerRegion);
124 unsigned ratio = countOps(calleeRegion) * 100 / callerOps;
125 LDBG() <<
"Callee / caller operation ratio (max: " << inliningThreshold
126 <<
"%): " << ratio <<
"%";
127 return ratio <= inliningThreshold;
130void InlinerPass::runOnOperation() {
131 CallGraph &cg = getAnalysis<CallGraph>();
135 Operation *op = getOperation();
136 if (!op->
hasTrait<OpTrait::SymbolTable>()) {
137 op->
emitOpError() <<
" was scheduled to run under the inliner, but does "
138 "not define a symbol table";
139 return signalPassFailure();
143 auto profitabilityCb = [
this](
const Inliner::ResolvedCall &call) {
148 Inliner inliner(op, cg, *
this, getAnalysisManager(), runPipelineHelper,
149 config, profitabilityCb);
152 if (
failed(inliner.doInlining()))
156LogicalResult InlinerPass::initializeOptions(
158 function_ref<LogicalResult(
const Twine &)> errorHandler) {
166 if (!defaultPipelineStr.empty()) {
167 std::string defaultPipelineCopy = defaultPipelineStr;
171 }
else if (defaultPipelineStr.getNumOccurrences()) {
176 llvm::StringMap<OpPassManager> pipelines;
177 for (OpPassManager pipeline : opPipelineList)
178 if (!pipeline.empty())
179 pipelines.try_emplace(pipeline.getOpAnchorName(), pipeline);
190 std::move(opPipelines));
193 llvm::StringMap<OpPassManager> opPipelines,
194 std::function<
void(
OpPassManager &)> defaultPipelineBuilder) {
195 return std::make_unique<InlinerPass>(std::move(defaultPipelineBuilder),
196 std::move(opPipelines));
static void defaultInlinerOptPipeline(OpPassManager &pm)
This function implements the inliner optimization pipeline.
static bool isProfitableToInline(const Inliner::ResolvedCall &resolvedCall, unsigned inliningThreshold)
static llvm::ManagedStatic< PassManagerOptions > options
Region * getCallableRegion() const
Returns the callable region this node represents.
void setMaxInliningIterations(unsigned max)
void setOpPipelines(OpPipelinesTy pipelines)
void setDefaultPipeline(DefaultPipelineTy pipeline)
This class represents a pass manager that runs passes on either a specific operation type,...
void addPass(std::unique_ptr< Pass > pass)
Add the given pass to this pass manager.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
virtual LogicalResult initializeOptions(StringRef options, function_ref< LogicalResult(const Twine &)> errorHandler)
Attempt to initialize the options of this pass from the given string.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Include the generated interface declarations.
std::unique_ptr< Pass > createInlinerPass(llvm::StringMap< OpPassManager > opPipelines)
Creates an instance of the inliner pass, and use the provided pass managers when optimizing callable ...
std::unique_ptr< Pass > createCanonicalizerPass(const GreedyRewriteConfig &config, ArrayRef< std::string > disabledPatterns={}, ArrayRef< std::string > enabledPatterns={})
Creates an instance of the Canonicalizer pass with the specified config.
LogicalResult parsePassPipeline(StringRef pipeline, OpPassManager &pm, raw_ostream &errorStream=llvm::errs())
Parse the textual representation of a pass pipeline, adding the result to 'pm' on success.
llvm::function_ref< Fn > function_ref
This struct represents a resolved call to a given callgraph node.
CallGraphNode * sourceNode
CallGraphNode * targetNode