LLVM 23.0.0git
MachineOutliner.h
Go to the documentation of this file.
1//===---- MachineOutliner.h - Outliner data structures ------*- 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/// \file
10/// Contains all data structures shared between the outliner implemented in
11/// MachineOutliner.cpp and target implementations of the outliner.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_MACHINEOUTLINER_H
16#define LLVM_CODEGEN_MACHINEOUTLINER_H
17
22#include <initializer_list>
23
24namespace llvm {
25namespace outliner {
26
27/// Represents how an instruction should be mapped by the outliner.
28/// \p Legal instructions are those which are safe to outline.
29/// \p LegalTerminator instructions are safe to outline, but only as the
30/// last instruction in a sequence.
31/// \p Illegal instructions are those which cannot be outlined.
32/// \p Invisible instructions are instructions which can be outlined, but
33/// shouldn't actually impact the outlining result.
35
36/// An individual sequence of instructions to be replaced with a call to
37/// an outlined function.
38struct Candidate {
39private:
40 /// The start index of this \p Candidate in the instruction list.
41 unsigned StartIdx = 0;
42
43 /// The number of instructions in this \p Candidate.
44 unsigned Len = 0;
45
46 // The first instruction in this \p Candidate.
48
49 // The last instruction in this \p Candidate.
51
52 // The basic block that contains this Candidate.
53 MachineBasicBlock *MBB = nullptr;
54
55 /// Cost of calling an outlined function from this point as defined by the
56 /// target.
57 unsigned CallOverhead = 0;
58
59 /// Liveness information for this Candidate. Tracks from the end of the
60 /// block containing this Candidate to the beginning of its sequence.
61 ///
62 /// Optional. Can be used to fine-tune the cost model, or fine-tune legality
63 /// decisions.
64 LiveRegUnits FromEndOfBlockToStartOfSeq;
65
66 /// Liveness information restricted to this Candidate's instruction sequence.
67 ///
68 /// Optional. Can be used to fine-tune the cost model, or fine-tune legality
69 /// decisions.
70 LiveRegUnits InSeq;
71
72 /// True if FromEndOfBlockToStartOfSeq has been initialized.
73 bool FromEndOfBlockToStartOfSeqWasSet = false;
74
75 /// True if InSeq has been initialized.
76 bool InSeqWasSet = false;
77
78 /// Populate FromEndOfBlockToStartOfSeq with liveness information.
79 void initFromEndOfBlockToStartOfSeq(const TargetRegisterInfo &TRI) {
80 assert(MBB->getParent()->getRegInfo().tracksLiveness() &&
81 "Candidate's Machine Function must track liveness");
82 // Only initialize once.
83 if (FromEndOfBlockToStartOfSeqWasSet)
84 return;
85 FromEndOfBlockToStartOfSeqWasSet = true;
86 FromEndOfBlockToStartOfSeq.init(TRI);
87 FromEndOfBlockToStartOfSeq.addLiveOuts(*MBB);
88 // Compute liveness from the end of the block up to the beginning of the
89 // outlining candidate.
90 for (auto &MI : make_range(MBB->rbegin(),
92 if (!MI.isDebugInstr())
93 FromEndOfBlockToStartOfSeq.stepBackward(MI);
94 }
95
96 /// Populate InSeq with liveness information.
97 void initInSeq(const TargetRegisterInfo &TRI) {
98 assert(MBB->getParent()->getRegInfo().tracksLiveness() &&
99 "Candidate's Machine Function must track liveness");
100 // Only initialize once.
101 if (InSeqWasSet)
102 return;
103 InSeqWasSet = true;
104 InSeq.init(TRI);
105 for (auto &MI : *this)
106 InSeq.accumulate(MI);
107 }
108
109public:
110 /// The index of this \p Candidate's \p OutlinedFunction in the list of
111 /// \p OutlinedFunctions.
112 unsigned FunctionIdx = 0;
113
114 /// Identifier denoting the instructions to emit to call an outlined function
115 /// from this point. Defined by the target.
116 unsigned CallConstructionID = 0;
117
118 /// Target-specific flags for this Candidate's MBB.
119 unsigned Flags = 0x0;
120
121 /// Return the number of instructions in this Candidate.
122 unsigned getLength() const { return Len; }
123
124 /// Return the start index of this candidate.
125 unsigned getStartIdx() const { return StartIdx; }
126
127 /// Return the end index of this candidate.
128 unsigned getEndIdx() const { return StartIdx + Len - 1; }
129
130 /// Set the CallConstructionID and CallOverhead of this candidate to CID and
131 /// CO respectively.
132 void setCallInfo(unsigned CID, unsigned CO) {
133 CallConstructionID = CID;
134 CallOverhead = CO;
135 }
136
137 /// Returns the call overhead of this candidate if it is in the list.
138 unsigned getCallOverhead() const { return CallOverhead; }
139
140 MachineBasicBlock::iterator begin() { return FirstInst; }
141 MachineBasicBlock::iterator end() { return std::next(LastInst); }
142
143 MachineInstr &front() { return *FirstInst; }
144 MachineInstr &back() { return *LastInst; }
145 MachineFunction *getMF() const { return MBB->getParent(); }
146 MachineBasicBlock *getMBB() const { return MBB; }
147
148 /// \returns True if \p Reg is available from the end of the block to the
149 /// beginning of the sequence.
150 ///
151 /// This query considers the following range:
152 ///
153 /// in_seq_1
154 /// in_seq_2
155 /// ...
156 /// in_seq_n
157 /// not_in_seq_1
158 /// ...
159 /// <end of block>
161 const TargetRegisterInfo &TRI) {
162 if (!FromEndOfBlockToStartOfSeqWasSet)
163 initFromEndOfBlockToStartOfSeq(TRI);
164 return FromEndOfBlockToStartOfSeq.available(Reg);
165 }
166
167 /// \returns True if `isAvailableAcrossAndOutOfSeq` fails for any register
168 /// in \p Regs.
169 bool isAnyUnavailableAcrossOrOutOfSeq(std::initializer_list<Register> Regs,
170 const TargetRegisterInfo &TRI) {
171 if (!FromEndOfBlockToStartOfSeqWasSet)
172 initFromEndOfBlockToStartOfSeq(TRI);
173 return any_of(Regs, [&](Register Reg) {
174 return !FromEndOfBlockToStartOfSeq.available(Reg);
175 });
176 }
177
178 /// \returns True if \p Reg is available within the sequence itself.
179 ///
180 /// This query considers the following range:
181 ///
182 /// in_seq_1
183 /// in_seq_2
184 /// ...
185 /// in_seq_n
187 if (!InSeqWasSet)
188 initInSeq(TRI);
189 return InSeq.available(Reg);
190 }
191
192 /// The number of instructions that would be saved by outlining every
193 /// candidate of this type.
194 ///
195 /// This is a fixed value which is not updated during the candidate pruning
196 /// process. It is only used for deciding which candidate to keep if two
197 /// candidates overlap. The true benefit is stored in the OutlinedFunction
198 /// for some given candidate.
199 unsigned Benefit = 0;
200
201 Candidate(unsigned StartIdx, unsigned Len,
204 unsigned FunctionIdx, unsigned Flags)
205 : StartIdx(StartIdx), Len(Len), FirstInst(FirstInst), LastInst(LastInst),
206 MBB(MBB), FunctionIdx(FunctionIdx), Flags(Flags) {}
207 Candidate() = delete;
208
209 /// Used to ensure that \p Candidates are outlined in an order that
210 /// preserves the start and end indices of other \p Candidates.
211 bool operator<(const Candidate &RHS) const {
212 return getStartIdx() > RHS.getStartIdx();
213 }
214
215};
216
217/// The information necessary to create an outlined function for some
218/// class of candidate.
220
221public:
222 std::vector<Candidate> Candidates;
223
224 /// The actual outlined function created.
225 /// This is initialized after we go through and create the actual function.
226 MachineFunction *MF = nullptr;
227
228 /// Represents the size of a sequence in bytes. (Some instructions vary
229 /// widely in size, so just counting the instructions isn't very useful.)
230 unsigned SequenceSize = 0;
231
232 /// Target-defined overhead of constructing a frame for this function.
233 unsigned FrameOverhead = 0;
234
235 /// Target-defined identifier for constructing a frame for this function.
237
238 /// Return the number of candidates for this \p OutlinedFunction.
239 virtual unsigned getOccurrenceCount() const { return Candidates.size(); }
240
241 /// Return the number of bytes it would take to outline this
242 /// function.
243 virtual unsigned getOutliningCost() const {
244 unsigned CallOverhead = 0;
245 for (const Candidate &C : Candidates)
246 CallOverhead += C.getCallOverhead();
247 return CallOverhead + SequenceSize + FrameOverhead;
248 }
249
250 /// Return the size in bytes of the unoutlined sequences.
251 unsigned getNotOutlinedCost() const {
253 }
254
255 /// Return the number of instructions that would be saved by outlining
256 /// this function.
257 unsigned getBenefit() const {
258 unsigned NotOutlinedCost = getNotOutlinedCost();
259 unsigned OutlinedCost = getOutliningCost();
260 return (NotOutlinedCost < OutlinedCost) ? 0
261 : NotOutlinedCost - OutlinedCost;
262 }
263
264 /// Return the number of instructions in this sequence.
265 unsigned getNumInstrs() const { return Candidates[0].getLength(); }
266
267 OutlinedFunction(std::vector<Candidate> &Candidates, unsigned SequenceSize,
268 unsigned FrameOverhead, unsigned FrameConstructionID)
271 const unsigned B = getBenefit();
272 for (Candidate &C : Candidates)
273 C.Benefit = B;
274 }
275
277 virtual ~OutlinedFunction() = default;
278};
279
280/// The information necessary to create an outlined function that is matched
281/// globally.
283 explicit GlobalOutlinedFunction(std::unique_ptr<OutlinedFunction> OF,
284 unsigned GlobalOccurrenceCount)
286
288
289 /// Return the number of times that appear globally.
290 /// Global outlining candidate is uniquely created per each match, but this
291 /// might be erased out when it's overlapped with the previous outlining
292 /// instance.
293 unsigned getOccurrenceCount() const override {
294 assert(Candidates.size() <= 1);
295 return Candidates.empty() ? 0 : GlobalOccurrenceCount;
296 }
297
298 /// Return the outlining cost using the global occurrence count
299 /// with the same cost as the first (unique) candidate.
300 unsigned getOutliningCost() const override {
301 assert(Candidates.size() <= 1);
302 unsigned CallOverhead =
303 Candidates.empty()
304 ? 0
305 : Candidates[0].getCallOverhead() * getOccurrenceCount();
306 return CallOverhead + SequenceSize + FrameOverhead;
307 }
308
310 ~GlobalOutlinedFunction() override = default;
311};
312
313} // namespace outliner
314} // namespace llvm
315
316#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
IRTranslator LLVM IR MI
A set of register units.
Register Reg
Register const TargetRegisterInfo * TRI
Value * RHS
A set of register units used to track register liveness.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1745
An individual sequence of instructions to be replaced with a call to an outlined function.
unsigned Flags
Target-specific flags for this Candidate's MBB.
bool isAnyUnavailableAcrossOrOutOfSeq(std::initializer_list< Register > Regs, const TargetRegisterInfo &TRI)
unsigned getCallOverhead() const
Returns the call overhead of this candidate if it is in the list.
void setCallInfo(unsigned CID, unsigned CO)
Set the CallConstructionID and CallOverhead of this candidate to CID and CO respectively.
unsigned Benefit
The number of instructions that would be saved by outlining every candidate of this type.
MachineBasicBlock * getMBB() const
MachineFunction * getMF() const
MachineBasicBlock::iterator begin()
bool operator<(const Candidate &RHS) const
Used to ensure that Candidates are outlined in an order that preserves the start and end indices of o...
unsigned getEndIdx() const
Return the end index of this candidate.
Candidate(unsigned StartIdx, unsigned Len, MachineBasicBlock::iterator &FirstInst, MachineBasicBlock::iterator &LastInst, MachineBasicBlock *MBB, unsigned FunctionIdx, unsigned Flags)
unsigned CallConstructionID
Identifier denoting the instructions to emit to call an outlined function from this point.
bool isAvailableInsideSeq(Register Reg, const TargetRegisterInfo &TRI)
unsigned getStartIdx() const
Return the start index of this candidate.
MachineBasicBlock::iterator end()
bool isAvailableAcrossAndOutOfSeq(Register Reg, const TargetRegisterInfo &TRI)
unsigned getLength() const
Return the number of instructions in this Candidate.
unsigned FunctionIdx
The index of this Candidate's OutlinedFunction in the list of OutlinedFunctions.
~GlobalOutlinedFunction() override=default
GlobalOutlinedFunction(std::unique_ptr< OutlinedFunction > OF, unsigned GlobalOccurrenceCount)
unsigned getOccurrenceCount() const override
Return the number of times that appear globally.
unsigned getOutliningCost() const override
Return the outlining cost using the global occurrence count with the same cost as the first (unique) ...
virtual unsigned getOccurrenceCount() const
Return the number of candidates for this OutlinedFunction.
virtual unsigned getOutliningCost() const
Return the number of bytes it would take to outline this function.
unsigned getBenefit() const
Return the number of instructions that would be saved by outlining this function.
unsigned getNotOutlinedCost() const
Return the size in bytes of the unoutlined sequences.
MachineFunction * MF
The actual outlined function created.
unsigned FrameConstructionID
Target-defined identifier for constructing a frame for this function.
unsigned getNumInstrs() const
Return the number of instructions in this sequence.
OutlinedFunction(std::vector< Candidate > &Candidates, unsigned SequenceSize, unsigned FrameOverhead, unsigned FrameConstructionID)
unsigned FrameOverhead
Target-defined overhead of constructing a frame for this function.
unsigned SequenceSize
Represents the size of a sequence in bytes.
virtual ~OutlinedFunction()=default
std::vector< Candidate > Candidates