1//===- Inliner.h - Inliner pass utilities -----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This header file declares utility structures for the inliner pass.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_TRANSFORMS_INLINER_H
14#define MLIR_TRANSFORMS_INLINER_H
15
16#include "mlir/Analysis/CallGraph.h"
17#include "mlir/Interfaces/CallInterfaces.h"
18#include "mlir/Pass/AnalysisManager.h"
19#include "mlir/Pass/PassManager.h"
20#include "mlir/Support/LogicalResult.h"
21#include "llvm/ADT/StringMap.h"
22
23namespace mlir {
24class OpPassManager;
25class Operation;
26
27class InlinerConfig {
28public:
29 using DefaultPipelineTy = std::function<void(OpPassManager &)>;
30 using OpPipelinesTy = llvm::StringMap<OpPassManager>;
31
32 InlinerConfig() = default;
33 InlinerConfig(DefaultPipelineTy defaultPipeline,
34 unsigned maxInliningIterations)
35 : defaultPipeline(std::move(defaultPipeline)),
36 maxInliningIterations(maxInliningIterations) {}
37
38 const DefaultPipelineTy &getDefaultPipeline() const {
39 return defaultPipeline;
40 }
41 const OpPipelinesTy &getOpPipelines() const { return opPipelines; }
42 unsigned getMaxInliningIterations() const { return maxInliningIterations; }
43 void setDefaultPipeline(DefaultPipelineTy pipeline) {
44 defaultPipeline = std::move(pipeline);
45 }
46 void setOpPipelines(OpPipelinesTy pipelines) {
47 opPipelines = std::move(pipelines);
48 }
49 void setMaxInliningIterations(unsigned max) { maxInliningIterations = max; }
50
51private:
52 /// An optional function that constructs an optimization pipeline for
53 /// a given operation. This optimization pipeline is applied
54 /// only to those callable operations that do not have dedicated
55 /// optimization pipeline in opPipelines (based on the operation name).
56 DefaultPipelineTy defaultPipeline;
57 /// A map of operation names to pass pipelines to use when optimizing
58 /// callable operations of these types. This provides a specialized pipeline
59 /// instead of the one produced by defaultPipeline.
60 OpPipelinesTy opPipelines;
61 /// For SCC-based inlining algorithms, specifies maximum number of iterations
62 /// when inlining within an SCC.
63 unsigned maxInliningIterations{0};
64};
65
66/// This is an implementation of the inliner
67/// that operates bottom up over the Strongly Connected Components(SCCs)
68/// of the CallGraph. This enables a more incremental propagation
69/// of inlining decisions from the leafs to the roots of the callgraph.
70class Inliner {
71public:
72 /// This struct represents a resolved call to a given callgraph node. Given
73 /// that the call does not actually contain a direct reference to the
74 /// Region(CallGraphNode) that it is dispatching to, we need to resolve them
75 /// explicitly.
76 struct ResolvedCall {
77 ResolvedCall(CallOpInterface call, CallGraphNode *sourceNode,
78 CallGraphNode *targetNode)
79 : call(call), sourceNode(sourceNode), targetNode(targetNode) {}
80 CallOpInterface call;
81 CallGraphNode *sourceNode, *targetNode;
82 };
83
84 using RunPipelineHelperTy = std::function<LogicalResult(
85 Pass &pass, OpPassManager &pipeline, Operation *op)>;
86
87 /// Type of the callback answering if it is profitable
88 /// to inline a callable operation at a call site.
89 /// It might be the case that the ResolvedCall does not provide
90 /// enough context to make the profitability decision, so
91 /// this hook's interface might need to be extended in future.
92 using ProfitabilityCallbackTy = std::function<bool(const ResolvedCall &)>;
93
94 Inliner(Operation *op, CallGraph &cg, Pass &pass, AnalysisManager am,
95 RunPipelineHelperTy runPipelineHelper, const InlinerConfig &config,
96 ProfitabilityCallbackTy isProfitableToInline)
97 : op(op), cg(cg), pass(pass), am(am),
98 runPipelineHelper(std::move(runPipelineHelper)), config(config),
99 isProfitableToInline(std::move(isProfitableToInline)) {}
100 Inliner(Inliner &) = delete;
101 void operator=(const Inliner &) = delete;
102
103 /// Perform inlining on a OpTrait::SymbolTable operation.
104 LogicalResult doInlining();
105
106private:
107 /// An OpTrait::SymbolTable operation to run the inlining on.
108 Operation *op;
109 /// A CallGraph analysis for the given operation.
110 CallGraph &cg;
111 /// A reference to the pass using this inliner.
112 Pass &pass;
113 /// Analysis manager for the given operation instance.
114 AnalysisManager am;
115 /// A callback for running a nested pass pipeline on the operation
116 /// contained within the main operation.
117 const RunPipelineHelperTy runPipelineHelper;
118 /// The inliner configuration parameters.
119 const InlinerConfig &config;
120 /// Returns true, if it is profitable to inline the callable operation
121 /// at the call site.
122 ProfitabilityCallbackTy isProfitableToInline;
123
124 /// Forward declaration of the class providing the actual implementation.
125 class Impl;
126};
127} // namespace mlir
128
129#endif // MLIR_TRANSFORMS_INLINER_H
130

source code of mlir/include/mlir/Transforms/Inliner.h