MLIR  21.0.0git
Inliner.h
Go to the documentation of this file.
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 
19 #include "mlir/Pass/PassManager.h"
21 #include "llvm/ADT/StringMap.h"
22 
23 namespace mlir {
24 class OpPassManager;
25 class Operation;
26 
28 public:
29  using DefaultPipelineTy = std::function<void(OpPassManager &)>;
30  using OpPipelinesTy = llvm::StringMap<OpPassManager>;
31 
32  InlinerConfig() = default;
34  unsigned maxInliningIterations)
35  : defaultPipeline(std::move(defaultPipeline)),
36  maxInliningIterations(maxInliningIterations) {}
37 
39  return defaultPipeline;
40  }
41  const OpPipelinesTy &getOpPipelines() const { return opPipelines; }
42  unsigned getMaxInliningIterations() const { return maxInliningIterations; }
44  return cloneCallback;
45  }
46  bool getCanHandleMultipleBlocks() const { return canHandleMultipleBlocks; }
47 
49  defaultPipeline = std::move(pipeline);
50  }
51  void setOpPipelines(OpPipelinesTy pipelines) {
52  opPipelines = std::move(pipelines);
53  }
54  void setMaxInliningIterations(unsigned max) { maxInliningIterations = max; }
56  cloneCallback = std::move(callback);
57  }
58  void setCanHandleMultipleBlocks(bool value = true) {
59  canHandleMultipleBlocks = value;
60  }
61 
62 private:
63  /// An optional function that constructs an optimization pipeline for
64  /// a given operation. This optimization pipeline is applied
65  /// only to those callable operations that do not have dedicated
66  /// optimization pipeline in opPipelines (based on the operation name).
67  DefaultPipelineTy defaultPipeline;
68  /// A map of operation names to pass pipelines to use when optimizing
69  /// callable operations of these types. This provides a specialized pipeline
70  /// instead of the one produced by defaultPipeline.
71  OpPipelinesTy opPipelines;
72  /// For SCC-based inlining algorithms, specifies maximum number of iterations
73  /// when inlining within an SCC.
74  unsigned maxInliningIterations{0};
75  /// Callback for cloning operations during inlining
76  InlinerInterface::CloneCallbackTy cloneCallback =
77  [](OpBuilder &builder, Region *src, Block *inlineBlock,
78  Block *postInsertBlock, IRMapping &mapper,
79  bool shouldCloneInlinedRegion) {
80  // Check to see if the region is being cloned, or moved inline. In
81  // either case, move the new blocks after the 'insertBlock' to improve
82  // IR readability.
83  Region *insertRegion = inlineBlock->getParent();
84  if (shouldCloneInlinedRegion)
85  src->cloneInto(insertRegion, postInsertBlock->getIterator(), mapper);
86  else
87  insertRegion->getBlocks().splice(postInsertBlock->getIterator(),
88  src->getBlocks(), src->begin(),
89  src->end());
90  };
91  /// Determine if the inliner can inline a function containing multiple
92  /// blocks into a region that requires a single block. By default, it is
93  /// not allowed. If it is true, cloneCallback should perform the extra
94  /// transformation. see the example in
95  /// mlir/test/lib/Transforms/TestInliningCallback.cpp
96  bool canHandleMultipleBlocks{false};
97 };
98 
99 /// This is an implementation of the inliner
100 /// that operates bottom up over the Strongly Connected Components(SCCs)
101 /// of the CallGraph. This enables a more incremental propagation
102 /// of inlining decisions from the leafs to the roots of the callgraph.
103 class Inliner {
104 public:
105  /// This struct represents a resolved call to a given callgraph node. Given
106  /// that the call does not actually contain a direct reference to the
107  /// Region(CallGraphNode) that it is dispatching to, we need to resolve them
108  /// explicitly.
109  struct ResolvedCall {
113  CallOpInterface call;
115  };
116 
117  using RunPipelineHelperTy = std::function<LogicalResult(
118  Pass &pass, OpPassManager &pipeline, Operation *op)>;
119 
120  /// Type of the callback answering if it is profitable
121  /// to inline a callable operation at a call site.
122  /// It might be the case that the ResolvedCall does not provide
123  /// enough context to make the profitability decision, so
124  /// this hook's interface might need to be extended in future.
125  using ProfitabilityCallbackTy = std::function<bool(const ResolvedCall &)>;
126 
128  RunPipelineHelperTy runPipelineHelper, const InlinerConfig &config,
129  ProfitabilityCallbackTy isProfitableToInline)
130  : op(op), cg(cg), pass(pass), am(am),
131  runPipelineHelper(std::move(runPipelineHelper)), config(config),
132  isProfitableToInline(std::move(isProfitableToInline)) {}
133  Inliner(Inliner &) = delete;
134  void operator=(const Inliner &) = delete;
135 
136  /// Perform inlining on a OpTrait::SymbolTable operation.
137  LogicalResult doInlining();
138 
139 private:
140  /// An OpTrait::SymbolTable operation to run the inlining on.
141  Operation *op;
142  /// A CallGraph analysis for the given operation.
143  CallGraph &cg;
144  /// A reference to the pass using this inliner.
145  Pass &pass;
146  /// Analysis manager for the given operation instance.
147  AnalysisManager am;
148  /// A callback for running a nested pass pipeline on the operation
149  /// contained within the main operation.
150  const RunPipelineHelperTy runPipelineHelper;
151  /// The inliner configuration parameters.
152  const InlinerConfig &config;
153  /// Returns true, if it is profitable to inline the callable operation
154  /// at the call site.
155  ProfitabilityCallbackTy isProfitableToInline;
156 
157  /// Forward declaration of the class providing the actual implementation.
158  class Impl;
159 };
160 } // namespace mlir
161 
162 #endif // MLIR_TRANSFORMS_INLINER_H
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
This class represents an analysis manager for a particular operation instance.
This class represents a single callable in the callgraph.
Definition: CallGraph.h:40
void setMaxInliningIterations(unsigned max)
Definition: Inliner.h:54
const DefaultPipelineTy & getDefaultPipeline() const
Definition: Inliner.h:38
const OpPipelinesTy & getOpPipelines() const
Definition: Inliner.h:41
void setCanHandleMultipleBlocks(bool value=true)
Definition: Inliner.h:58
void setOpPipelines(OpPipelinesTy pipelines)
Definition: Inliner.h:51
std::function< void(OpPassManager &)> DefaultPipelineTy
Definition: Inliner.h:29
const InlinerInterface::CloneCallbackTy & getCloneCallback() const
Definition: Inliner.h:43
void setCloneCallback(InlinerInterface::CloneCallbackTy callback)
Definition: Inliner.h:55
InlinerConfig(DefaultPipelineTy defaultPipeline, unsigned maxInliningIterations)
Definition: Inliner.h:33
InlinerConfig()=default
bool getCanHandleMultipleBlocks() const
Definition: Inliner.h:46
void setDefaultPipeline(DefaultPipelineTy pipeline)
Definition: Inliner.h:48
unsigned getMaxInliningIterations() const
Definition: Inliner.h:42
llvm::StringMap< OpPassManager > OpPipelinesTy
Definition: Inliner.h:30
std::function< CloneCallbackSigTy > CloneCallbackTy
This is an implementation of the inliner that operates bottom up over the Strongly Connected Componen...
Definition: Inliner.h:103
void operator=(const Inliner &)=delete
std::function< LogicalResult(Pass &pass, OpPassManager &pipeline, Operation *op)> RunPipelineHelperTy
Definition: Inliner.h:118
Inliner(Operation *op, CallGraph &cg, Pass &pass, AnalysisManager am, RunPipelineHelperTy runPipelineHelper, const InlinerConfig &config, ProfitabilityCallbackTy isProfitableToInline)
Definition: Inliner.h:127
LogicalResult doInlining()
Perform inlining on a OpTrait::SymbolTable operation.
Definition: Inliner.cpp:757
std::function< bool(const ResolvedCall &)> ProfitabilityCallbackTy
Type of the callback answering if it is profitable to inline a callable operation at a call site.
Definition: Inliner.h:125
Inliner(Inliner &)=delete
This class represents a pass manager that runs passes on either a specific operation type,...
Definition: PassManager.h:46
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
The abstract base pass class.
Definition: Pass.h:51
Include the generated interface declarations.
const FrozenRewritePatternSet GreedyRewriteConfig config
This struct represents a resolved call to a given callgraph node.
Definition: Inliner.h:109
CallGraphNode * sourceNode
Definition: Inliner.h:114
ResolvedCall(CallOpInterface call, CallGraphNode *sourceNode, CallGraphNode *targetNode)
Definition: Inliner.h:110
CallOpInterface call
Definition: Inliner.h:113
CallGraphNode * targetNode
Definition: Inliner.h:114