blob: d60cc58e20af178494ea454636f5a74a552c6946 [file] [log] [blame]
Jessica Paquette596f4832017-03-06 21:31:18 +00001//===---- MachineOutliner.cpp - Outline instructions -----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// Replaces repeated sequences of instructions with function calls.
12///
13/// This works by placing every instruction from every basic block in a
14/// suffix tree, and repeatedly querying that tree for repeated sequences of
15/// instructions. If a sequence of instructions appears often, then it ought
16/// to be beneficial to pull out into a function.
17///
Jessica Paquette4cf187b2017-09-27 20:47:39 +000018/// The MachineOutliner communicates with a given target using hooks defined in
19/// TargetInstrInfo.h. The target supplies the outliner with information on how
20/// a specific sequence of instructions should be outlined. This information
21/// is used to deduce the number of instructions necessary to
22///
23/// * Create an outlined function
24/// * Call that outlined function
25///
26/// Targets must implement
27/// * getOutliningCandidateInfo
28/// * insertOutlinerEpilogue
29/// * insertOutlinedCall
30/// * insertOutlinerPrologue
31/// * isFunctionSafeToOutlineFrom
32///
33/// in order to make use of the MachineOutliner.
34///
Jessica Paquette596f4832017-03-06 21:31:18 +000035/// This was originally presented at the 2016 LLVM Developers' Meeting in the
36/// talk "Reducing Code Size Using Outlining". For a high-level overview of
37/// how this pass works, the talk is available on YouTube at
38///
39/// https://www.youtube.com/watch?v=yorld-WSOeU
40///
41/// The slides for the talk are available at
42///
43/// http://www.llvm.org/devmtg/2016-11/Slides/Paquette-Outliner.pdf
44///
45/// The talk provides an overview of how the outliner finds candidates and
46/// ultimately outlines them. It describes how the main data structure for this
47/// pass, the suffix tree, is queried and purged for candidates. It also gives
48/// a simplified suffix tree construction algorithm for suffix trees based off
49/// of the algorithm actually used here, Ukkonen's algorithm.
50///
51/// For the original RFC for this pass, please see
52///
53/// http://lists.llvm.org/pipermail/llvm-dev/2016-August/104170.html
54///
55/// For more information on the suffix tree data structure, please see
56/// https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
57///
58//===----------------------------------------------------------------------===//
59#include "llvm/ADT/DenseMap.h"
60#include "llvm/ADT/Statistic.h"
61#include "llvm/ADT/Twine.h"
Jessica Paquette596f4832017-03-06 21:31:18 +000062#include "llvm/CodeGen/MachineFunction.h"
Jessica Paquette596f4832017-03-06 21:31:18 +000063#include "llvm/CodeGen/MachineModuleInfo.h"
Jessica Paquetteffe4abc2017-08-31 21:02:45 +000064#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
Geoff Berry82203c42018-01-31 20:15:16 +000065#include "llvm/CodeGen/MachineRegisterInfo.h"
Jessica Paquette596f4832017-03-06 21:31:18 +000066#include "llvm/CodeGen/Passes.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000067#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000068#include "llvm/CodeGen/TargetRegisterInfo.h"
69#include "llvm/CodeGen/TargetSubtargetInfo.h"
Jessica Paquette729e6862018-01-18 00:00:58 +000070#include "llvm/IR/DIBuilder.h"
Jessica Paquette596f4832017-03-06 21:31:18 +000071#include "llvm/IR/IRBuilder.h"
Jessica Paquettea499c3c2018-01-19 21:21:49 +000072#include "llvm/IR/Mangler.h"
Jessica Paquette596f4832017-03-06 21:31:18 +000073#include "llvm/Support/Allocator.h"
74#include "llvm/Support/Debug.h"
75#include "llvm/Support/raw_ostream.h"
Jessica Paquette596f4832017-03-06 21:31:18 +000076#include <functional>
77#include <map>
78#include <sstream>
79#include <tuple>
80#include <vector>
81
82#define DEBUG_TYPE "machine-outliner"
83
84using namespace llvm;
Jessica Paquetteffe4abc2017-08-31 21:02:45 +000085using namespace ore;
Jessica Paquette596f4832017-03-06 21:31:18 +000086
87STATISTIC(NumOutlined, "Number of candidates outlined");
88STATISTIC(FunctionsCreated, "Number of functions created");
89
90namespace {
91
Jessica Paquetteacffa282017-03-23 21:27:38 +000092/// \brief An individual sequence of instructions to be replaced with a call to
93/// an outlined function.
94struct Candidate {
Jessica Paquettec9ab4c22017-10-17 18:43:15 +000095private:
96 /// The start index of this \p Candidate in the instruction list.
Jessica Paquette4cf187b2017-09-27 20:47:39 +000097 unsigned StartIdx;
Jessica Paquetteacffa282017-03-23 21:27:38 +000098
99 /// The number of instructions in this \p Candidate.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000100 unsigned Len;
Jessica Paquetteacffa282017-03-23 21:27:38 +0000101
Jessica Paquettea499c3c2018-01-19 21:21:49 +0000102 /// The MachineFunction containing this \p Candidate.
103 MachineFunction *MF = nullptr;
104
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000105public:
106 /// Set to false if the candidate overlapped with another candidate.
107 bool InCandidateList = true;
108
109 /// \brief The index of this \p Candidate's \p OutlinedFunction in the list of
Jessica Paquetteacffa282017-03-23 21:27:38 +0000110 /// \p OutlinedFunctions.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000111 unsigned FunctionIdx;
Jessica Paquetteacffa282017-03-23 21:27:38 +0000112
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000113 /// Contains all target-specific information for this \p Candidate.
114 TargetInstrInfo::MachineOutlinerInfo MInfo;
Jessica Paquetted87f5442017-07-29 02:55:46 +0000115
Jessica Paquettea499c3c2018-01-19 21:21:49 +0000116 /// If there is a DISubprogram associated with the function that this
117 /// Candidate lives in, return it.
118 DISubprogram *getSubprogramOrNull() const {
119 assert(MF && "Candidate has no MF!");
120 if (DISubprogram *SP = MF->getFunction().getSubprogram())
121 return SP;
122 return nullptr;
123 }
124
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000125 /// Return the number of instructions in this Candidate.
Jessica Paquette1934fd22017-10-23 16:25:53 +0000126 unsigned getLength() const { return Len; }
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000127
128 /// Return the start index of this candidate.
Jessica Paquette1934fd22017-10-23 16:25:53 +0000129 unsigned getStartIdx() const { return StartIdx; }
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000130
131 // Return the end index of this candidate.
Jessica Paquette1934fd22017-10-23 16:25:53 +0000132 unsigned getEndIdx() const { return StartIdx + Len - 1; }
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000133
Jessica Paquetteacffa282017-03-23 21:27:38 +0000134 /// \brief The number of instructions that would be saved by outlining every
135 /// candidate of this type.
136 ///
137 /// This is a fixed value which is not updated during the candidate pruning
138 /// process. It is only used for deciding which candidate to keep if two
139 /// candidates overlap. The true benefit is stored in the OutlinedFunction
140 /// for some given candidate.
141 unsigned Benefit = 0;
142
Jessica Paquettea499c3c2018-01-19 21:21:49 +0000143 Candidate(unsigned StartIdx, unsigned Len, unsigned FunctionIdx,
144 MachineFunction *MF)
145 : StartIdx(StartIdx), Len(Len), MF(MF), FunctionIdx(FunctionIdx) {}
Jessica Paquetteacffa282017-03-23 21:27:38 +0000146
147 Candidate() {}
148
149 /// \brief Used to ensure that \p Candidates are outlined in an order that
150 /// preserves the start and end indices of other \p Candidates.
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000151 bool operator<(const Candidate &RHS) const {
Jessica Paquette1934fd22017-10-23 16:25:53 +0000152 return getStartIdx() > RHS.getStartIdx();
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000153 }
Jessica Paquetteacffa282017-03-23 21:27:38 +0000154};
155
156/// \brief The information necessary to create an outlined function for some
157/// class of candidate.
158struct OutlinedFunction {
159
Jessica Paquette85af63d2017-10-17 19:03:23 +0000160private:
161 /// The number of candidates for this \p OutlinedFunction.
162 unsigned OccurrenceCount = 0;
163
164public:
Jessica Paquette9df7fde2017-10-23 23:36:46 +0000165 std::vector<std::shared_ptr<Candidate>> Candidates;
166
Jessica Paquetteacffa282017-03-23 21:27:38 +0000167 /// The actual outlined function created.
168 /// This is initialized after we go through and create the actual function.
169 MachineFunction *MF = nullptr;
170
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000171 /// A number assigned to this function which appears at the end of its name.
172 unsigned Name;
Jessica Paquetteacffa282017-03-23 21:27:38 +0000173
Jessica Paquetteacffa282017-03-23 21:27:38 +0000174 /// \brief The sequence of integers corresponding to the instructions in this
175 /// function.
176 std::vector<unsigned> Sequence;
177
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000178 /// Contains all target-specific information for this \p OutlinedFunction.
179 TargetInstrInfo::MachineOutlinerInfo MInfo;
Jessica Paquetteacffa282017-03-23 21:27:38 +0000180
Jessica Paquettea499c3c2018-01-19 21:21:49 +0000181 /// If there is a DISubprogram for any Candidate for this outlined function,
182 /// then return it. Otherwise, return nullptr.
183 DISubprogram *getSubprogramOrNull() const {
184 for (const auto &C : Candidates)
185 if (DISubprogram *SP = C->getSubprogramOrNull())
186 return SP;
187 return nullptr;
188 }
189
Jessica Paquette85af63d2017-10-17 19:03:23 +0000190 /// Return the number of candidates for this \p OutlinedFunction.
Jessica Paquette60d31fc2017-10-17 21:11:58 +0000191 unsigned getOccurrenceCount() { return OccurrenceCount; }
Jessica Paquette85af63d2017-10-17 19:03:23 +0000192
193 /// Decrement the occurrence count of this OutlinedFunction and return the
194 /// new count.
195 unsigned decrement() {
196 assert(OccurrenceCount > 0 && "Can't decrement an empty function!");
197 OccurrenceCount--;
198 return getOccurrenceCount();
199 }
200
Jessica Paquetteacc15e12017-10-03 20:32:55 +0000201 /// \brief Return the number of instructions it would take to outline this
202 /// function.
203 unsigned getOutliningCost() {
204 return (OccurrenceCount * MInfo.CallOverhead) + Sequence.size() +
205 MInfo.FrameOverhead;
206 }
207
208 /// \brief Return the number of instructions that would be saved by outlining
209 /// this function.
210 unsigned getBenefit() {
211 unsigned NotOutlinedCost = OccurrenceCount * Sequence.size();
212 unsigned OutlinedCost = getOutliningCost();
213 return (NotOutlinedCost < OutlinedCost) ? 0
214 : NotOutlinedCost - OutlinedCost;
215 }
216
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000217 OutlinedFunction(unsigned Name, unsigned OccurrenceCount,
Jessica Paquetteacc15e12017-10-03 20:32:55 +0000218 const std::vector<unsigned> &Sequence,
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000219 TargetInstrInfo::MachineOutlinerInfo &MInfo)
Jessica Paquette85af63d2017-10-17 19:03:23 +0000220 : OccurrenceCount(OccurrenceCount), Name(Name), Sequence(Sequence),
Jessica Paquetteacc15e12017-10-03 20:32:55 +0000221 MInfo(MInfo) {}
Jessica Paquetteacffa282017-03-23 21:27:38 +0000222};
223
Jessica Paquette596f4832017-03-06 21:31:18 +0000224/// Represents an undefined index in the suffix tree.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000225const unsigned EmptyIdx = -1;
Jessica Paquette596f4832017-03-06 21:31:18 +0000226
227/// A node in a suffix tree which represents a substring or suffix.
228///
229/// Each node has either no children or at least two children, with the root
230/// being a exception in the empty tree.
231///
232/// Children are represented as a map between unsigned integers and nodes. If
233/// a node N has a child M on unsigned integer k, then the mapping represented
234/// by N is a proper prefix of the mapping represented by M. Note that this,
235/// although similar to a trie is somewhat different: each node stores a full
236/// substring of the full mapping rather than a single character state.
237///
238/// Each internal node contains a pointer to the internal node representing
239/// the same string, but with the first character chopped off. This is stored
240/// in \p Link. Each leaf node stores the start index of its respective
241/// suffix in \p SuffixIdx.
242struct SuffixTreeNode {
243
244 /// The children of this node.
245 ///
246 /// A child existing on an unsigned integer implies that from the mapping
247 /// represented by the current node, there is a way to reach another
248 /// mapping by tacking that character on the end of the current string.
249 DenseMap<unsigned, SuffixTreeNode *> Children;
250
251 /// A flag set to false if the node has been pruned from the tree.
252 bool IsInTree = true;
253
254 /// The start index of this node's substring in the main string.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000255 unsigned StartIdx = EmptyIdx;
Jessica Paquette596f4832017-03-06 21:31:18 +0000256
257 /// The end index of this node's substring in the main string.
258 ///
259 /// Every leaf node must have its \p EndIdx incremented at the end of every
260 /// step in the construction algorithm. To avoid having to update O(N)
261 /// nodes individually at the end of every step, the end index is stored
262 /// as a pointer.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000263 unsigned *EndIdx = nullptr;
Jessica Paquette596f4832017-03-06 21:31:18 +0000264
265 /// For leaves, the start index of the suffix represented by this node.
266 ///
267 /// For all other nodes, this is ignored.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000268 unsigned SuffixIdx = EmptyIdx;
Jessica Paquette596f4832017-03-06 21:31:18 +0000269
270 /// \brief For internal nodes, a pointer to the internal node representing
271 /// the same sequence with the first character chopped off.
272 ///
Jessica Paquette4602c342017-07-28 05:59:30 +0000273 /// This acts as a shortcut in Ukkonen's algorithm. One of the things that
Jessica Paquette596f4832017-03-06 21:31:18 +0000274 /// Ukkonen's algorithm does to achieve linear-time construction is
275 /// keep track of which node the next insert should be at. This makes each
276 /// insert O(1), and there are a total of O(N) inserts. The suffix link
277 /// helps with inserting children of internal nodes.
278 ///
Jessica Paquette78681be2017-07-27 23:24:43 +0000279 /// Say we add a child to an internal node with associated mapping S. The
Jessica Paquette596f4832017-03-06 21:31:18 +0000280 /// next insertion must be at the node representing S - its first character.
281 /// This is given by the way that we iteratively build the tree in Ukkonen's
282 /// algorithm. The main idea is to look at the suffixes of each prefix in the
283 /// string, starting with the longest suffix of the prefix, and ending with
284 /// the shortest. Therefore, if we keep pointers between such nodes, we can
285 /// move to the next insertion point in O(1) time. If we don't, then we'd
286 /// have to query from the root, which takes O(N) time. This would make the
287 /// construction algorithm O(N^2) rather than O(N).
Jessica Paquette596f4832017-03-06 21:31:18 +0000288 SuffixTreeNode *Link = nullptr;
289
290 /// The parent of this node. Every node except for the root has a parent.
291 SuffixTreeNode *Parent = nullptr;
292
293 /// The number of times this node's string appears in the tree.
294 ///
295 /// This is equal to the number of leaf children of the string. It represents
296 /// the number of suffixes that the node's string is a prefix of.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000297 unsigned OccurrenceCount = 0;
Jessica Paquette596f4832017-03-06 21:31:18 +0000298
Jessica Paquetteacffa282017-03-23 21:27:38 +0000299 /// The length of the string formed by concatenating the edge labels from the
300 /// root to this node.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000301 unsigned ConcatLen = 0;
Jessica Paquetteacffa282017-03-23 21:27:38 +0000302
Jessica Paquette596f4832017-03-06 21:31:18 +0000303 /// Returns true if this node is a leaf.
304 bool isLeaf() const { return SuffixIdx != EmptyIdx; }
305
306 /// Returns true if this node is the root of its owning \p SuffixTree.
307 bool isRoot() const { return StartIdx == EmptyIdx; }
308
309 /// Return the number of elements in the substring associated with this node.
310 size_t size() const {
311
312 // Is it the root? If so, it's the empty string so return 0.
313 if (isRoot())
314 return 0;
315
316 assert(*EndIdx != EmptyIdx && "EndIdx is undefined!");
317
318 // Size = the number of elements in the string.
319 // For example, [0 1 2 3] has length 4, not 3. 3-0 = 3, so we have 3-0+1.
320 return *EndIdx - StartIdx + 1;
321 }
322
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000323 SuffixTreeNode(unsigned StartIdx, unsigned *EndIdx, SuffixTreeNode *Link,
Jessica Paquette596f4832017-03-06 21:31:18 +0000324 SuffixTreeNode *Parent)
325 : StartIdx(StartIdx), EndIdx(EndIdx), Link(Link), Parent(Parent) {}
326
327 SuffixTreeNode() {}
328};
329
330/// A data structure for fast substring queries.
331///
332/// Suffix trees represent the suffixes of their input strings in their leaves.
333/// A suffix tree is a type of compressed trie structure where each node
334/// represents an entire substring rather than a single character. Each leaf
335/// of the tree is a suffix.
336///
337/// A suffix tree can be seen as a type of state machine where each state is a
338/// substring of the full string. The tree is structured so that, for a string
339/// of length N, there are exactly N leaves in the tree. This structure allows
340/// us to quickly find repeated substrings of the input string.
341///
342/// In this implementation, a "string" is a vector of unsigned integers.
343/// These integers may result from hashing some data type. A suffix tree can
344/// contain 1 or many strings, which can then be queried as one large string.
345///
346/// The suffix tree is implemented using Ukkonen's algorithm for linear-time
347/// suffix tree construction. Ukkonen's algorithm is explained in more detail
348/// in the paper by Esko Ukkonen "On-line construction of suffix trees. The
349/// paper is available at
350///
351/// https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
352class SuffixTree {
Jessica Paquette78681be2017-07-27 23:24:43 +0000353public:
354 /// Stores each leaf node in the tree.
355 ///
356 /// This is used for finding outlining candidates.
357 std::vector<SuffixTreeNode *> LeafVector;
358
Jessica Paquette596f4832017-03-06 21:31:18 +0000359 /// Each element is an integer representing an instruction in the module.
360 ArrayRef<unsigned> Str;
361
Jessica Paquette78681be2017-07-27 23:24:43 +0000362private:
Jessica Paquette596f4832017-03-06 21:31:18 +0000363 /// Maintains each node in the tree.
Jessica Paquetted4cb9c62017-03-08 23:55:33 +0000364 SpecificBumpPtrAllocator<SuffixTreeNode> NodeAllocator;
Jessica Paquette596f4832017-03-06 21:31:18 +0000365
366 /// The root of the suffix tree.
367 ///
368 /// The root represents the empty string. It is maintained by the
369 /// \p NodeAllocator like every other node in the tree.
370 SuffixTreeNode *Root = nullptr;
371
Jessica Paquette596f4832017-03-06 21:31:18 +0000372 /// Maintains the end indices of the internal nodes in the tree.
373 ///
374 /// Each internal node is guaranteed to never have its end index change
375 /// during the construction algorithm; however, leaves must be updated at
376 /// every step. Therefore, we need to store leaf end indices by reference
377 /// to avoid updating O(N) leaves at every step of construction. Thus,
378 /// every internal node must be allocated its own end index.
379 BumpPtrAllocator InternalEndIdxAllocator;
380
381 /// The end index of each leaf in the tree.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000382 unsigned LeafEndIdx = -1;
Jessica Paquette596f4832017-03-06 21:31:18 +0000383
384 /// \brief Helper struct which keeps track of the next insertion point in
385 /// Ukkonen's algorithm.
386 struct ActiveState {
387 /// The next node to insert at.
388 SuffixTreeNode *Node;
389
390 /// The index of the first character in the substring currently being added.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000391 unsigned Idx = EmptyIdx;
Jessica Paquette596f4832017-03-06 21:31:18 +0000392
393 /// The length of the substring we have to add at the current step.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000394 unsigned Len = 0;
Jessica Paquette596f4832017-03-06 21:31:18 +0000395 };
396
397 /// \brief The point the next insertion will take place at in the
398 /// construction algorithm.
399 ActiveState Active;
400
401 /// Allocate a leaf node and add it to the tree.
402 ///
403 /// \param Parent The parent of this node.
404 /// \param StartIdx The start index of this node's associated string.
405 /// \param Edge The label on the edge leaving \p Parent to this node.
406 ///
407 /// \returns A pointer to the allocated leaf node.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000408 SuffixTreeNode *insertLeaf(SuffixTreeNode &Parent, unsigned StartIdx,
Jessica Paquette596f4832017-03-06 21:31:18 +0000409 unsigned Edge) {
410
411 assert(StartIdx <= LeafEndIdx && "String can't start after it ends!");
412
Jessica Paquette78681be2017-07-27 23:24:43 +0000413 SuffixTreeNode *N = new (NodeAllocator.Allocate())
414 SuffixTreeNode(StartIdx, &LeafEndIdx, nullptr, &Parent);
Jessica Paquette596f4832017-03-06 21:31:18 +0000415 Parent.Children[Edge] = N;
416
417 return N;
418 }
419
420 /// Allocate an internal node and add it to the tree.
421 ///
422 /// \param Parent The parent of this node. Only null when allocating the root.
423 /// \param StartIdx The start index of this node's associated string.
424 /// \param EndIdx The end index of this node's associated string.
425 /// \param Edge The label on the edge leaving \p Parent to this node.
426 ///
427 /// \returns A pointer to the allocated internal node.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000428 SuffixTreeNode *insertInternalNode(SuffixTreeNode *Parent, unsigned StartIdx,
429 unsigned EndIdx, unsigned Edge) {
Jessica Paquette596f4832017-03-06 21:31:18 +0000430
431 assert(StartIdx <= EndIdx && "String can't start after it ends!");
432 assert(!(!Parent && StartIdx != EmptyIdx) &&
Jessica Paquette78681be2017-07-27 23:24:43 +0000433 "Non-root internal nodes must have parents!");
Jessica Paquette596f4832017-03-06 21:31:18 +0000434
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000435 unsigned *E = new (InternalEndIdxAllocator) unsigned(EndIdx);
Jessica Paquette78681be2017-07-27 23:24:43 +0000436 SuffixTreeNode *N = new (NodeAllocator.Allocate())
437 SuffixTreeNode(StartIdx, E, Root, Parent);
Jessica Paquette596f4832017-03-06 21:31:18 +0000438 if (Parent)
439 Parent->Children[Edge] = N;
440
441 return N;
442 }
443
444 /// \brief Set the suffix indices of the leaves to the start indices of their
445 /// respective suffixes. Also stores each leaf in \p LeafVector at its
446 /// respective suffix index.
447 ///
448 /// \param[in] CurrNode The node currently being visited.
449 /// \param CurrIdx The current index of the string being visited.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000450 void setSuffixIndices(SuffixTreeNode &CurrNode, unsigned CurrIdx) {
Jessica Paquette596f4832017-03-06 21:31:18 +0000451
452 bool IsLeaf = CurrNode.Children.size() == 0 && !CurrNode.isRoot();
453
Jessica Paquetteacffa282017-03-23 21:27:38 +0000454 // Store the length of the concatenation of all strings from the root to
455 // this node.
456 if (!CurrNode.isRoot()) {
457 if (CurrNode.ConcatLen == 0)
458 CurrNode.ConcatLen = CurrNode.size();
459
460 if (CurrNode.Parent)
Jessica Paquette78681be2017-07-27 23:24:43 +0000461 CurrNode.ConcatLen += CurrNode.Parent->ConcatLen;
Jessica Paquetteacffa282017-03-23 21:27:38 +0000462 }
463
Jessica Paquette596f4832017-03-06 21:31:18 +0000464 // Traverse the tree depth-first.
465 for (auto &ChildPair : CurrNode.Children) {
466 assert(ChildPair.second && "Node had a null child!");
Jessica Paquette78681be2017-07-27 23:24:43 +0000467 setSuffixIndices(*ChildPair.second, CurrIdx + ChildPair.second->size());
Jessica Paquette596f4832017-03-06 21:31:18 +0000468 }
469
470 // Is this node a leaf?
471 if (IsLeaf) {
472 // If yes, give it a suffix index and bump its parent's occurrence count.
473 CurrNode.SuffixIdx = Str.size() - CurrIdx;
474 assert(CurrNode.Parent && "CurrNode had no parent!");
475 CurrNode.Parent->OccurrenceCount++;
476
477 // Store the leaf in the leaf vector for pruning later.
478 LeafVector[CurrNode.SuffixIdx] = &CurrNode;
479 }
480 }
481
482 /// \brief Construct the suffix tree for the prefix of the input ending at
483 /// \p EndIdx.
484 ///
485 /// Used to construct the full suffix tree iteratively. At the end of each
486 /// step, the constructed suffix tree is either a valid suffix tree, or a
487 /// suffix tree with implicit suffixes. At the end of the final step, the
488 /// suffix tree is a valid tree.
489 ///
490 /// \param EndIdx The end index of the current prefix in the main string.
491 /// \param SuffixesToAdd The number of suffixes that must be added
492 /// to complete the suffix tree at the current phase.
493 ///
494 /// \returns The number of suffixes that have not been added at the end of
495 /// this step.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000496 unsigned extend(unsigned EndIdx, unsigned SuffixesToAdd) {
Jessica Paquette596f4832017-03-06 21:31:18 +0000497 SuffixTreeNode *NeedsLink = nullptr;
498
499 while (SuffixesToAdd > 0) {
Jessica Paquette78681be2017-07-27 23:24:43 +0000500
Jessica Paquette596f4832017-03-06 21:31:18 +0000501 // Are we waiting to add anything other than just the last character?
502 if (Active.Len == 0) {
503 // If not, then say the active index is the end index.
504 Active.Idx = EndIdx;
505 }
506
507 assert(Active.Idx <= EndIdx && "Start index can't be after end index!");
508
509 // The first character in the current substring we're looking at.
510 unsigned FirstChar = Str[Active.Idx];
511
512 // Have we inserted anything starting with FirstChar at the current node?
513 if (Active.Node->Children.count(FirstChar) == 0) {
514 // If not, then we can just insert a leaf and move too the next step.
515 insertLeaf(*Active.Node, EndIdx, FirstChar);
516
517 // The active node is an internal node, and we visited it, so it must
518 // need a link if it doesn't have one.
519 if (NeedsLink) {
520 NeedsLink->Link = Active.Node;
521 NeedsLink = nullptr;
522 }
523 } else {
524 // There's a match with FirstChar, so look for the point in the tree to
525 // insert a new node.
526 SuffixTreeNode *NextNode = Active.Node->Children[FirstChar];
527
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000528 unsigned SubstringLen = NextNode->size();
Jessica Paquette596f4832017-03-06 21:31:18 +0000529
530 // Is the current suffix we're trying to insert longer than the size of
531 // the child we want to move to?
532 if (Active.Len >= SubstringLen) {
533 // If yes, then consume the characters we've seen and move to the next
534 // node.
535 Active.Idx += SubstringLen;
536 Active.Len -= SubstringLen;
537 Active.Node = NextNode;
538 continue;
539 }
540
541 // Otherwise, the suffix we're trying to insert must be contained in the
542 // next node we want to move to.
543 unsigned LastChar = Str[EndIdx];
544
545 // Is the string we're trying to insert a substring of the next node?
546 if (Str[NextNode->StartIdx + Active.Len] == LastChar) {
547 // If yes, then we're done for this step. Remember our insertion point
548 // and move to the next end index. At this point, we have an implicit
549 // suffix tree.
550 if (NeedsLink && !Active.Node->isRoot()) {
551 NeedsLink->Link = Active.Node;
552 NeedsLink = nullptr;
553 }
554
555 Active.Len++;
556 break;
557 }
558
559 // The string we're trying to insert isn't a substring of the next node,
560 // but matches up to a point. Split the node.
561 //
562 // For example, say we ended our search at a node n and we're trying to
563 // insert ABD. Then we'll create a new node s for AB, reduce n to just
564 // representing C, and insert a new leaf node l to represent d. This
565 // allows us to ensure that if n was a leaf, it remains a leaf.
566 //
567 // | ABC ---split---> | AB
568 // n s
569 // C / \ D
570 // n l
571
572 // The node s from the diagram
573 SuffixTreeNode *SplitNode =
Jessica Paquette78681be2017-07-27 23:24:43 +0000574 insertInternalNode(Active.Node, NextNode->StartIdx,
575 NextNode->StartIdx + Active.Len - 1, FirstChar);
Jessica Paquette596f4832017-03-06 21:31:18 +0000576
577 // Insert the new node representing the new substring into the tree as
578 // a child of the split node. This is the node l from the diagram.
579 insertLeaf(*SplitNode, EndIdx, LastChar);
580
581 // Make the old node a child of the split node and update its start
582 // index. This is the node n from the diagram.
583 NextNode->StartIdx += Active.Len;
584 NextNode->Parent = SplitNode;
585 SplitNode->Children[Str[NextNode->StartIdx]] = NextNode;
586
587 // SplitNode is an internal node, update the suffix link.
588 if (NeedsLink)
589 NeedsLink->Link = SplitNode;
590
591 NeedsLink = SplitNode;
592 }
593
594 // We've added something new to the tree, so there's one less suffix to
595 // add.
596 SuffixesToAdd--;
597
598 if (Active.Node->isRoot()) {
599 if (Active.Len > 0) {
600 Active.Len--;
601 Active.Idx = EndIdx - SuffixesToAdd + 1;
602 }
603 } else {
604 // Start the next phase at the next smallest suffix.
605 Active.Node = Active.Node->Link;
606 }
607 }
608
609 return SuffixesToAdd;
610 }
611
Jessica Paquette596f4832017-03-06 21:31:18 +0000612public:
Jessica Paquette596f4832017-03-06 21:31:18 +0000613 /// Construct a suffix tree from a sequence of unsigned integers.
614 ///
615 /// \param Str The string to construct the suffix tree for.
616 SuffixTree(const std::vector<unsigned> &Str) : Str(Str) {
617 Root = insertInternalNode(nullptr, EmptyIdx, EmptyIdx, 0);
618 Root->IsInTree = true;
619 Active.Node = Root;
Jessica Paquette78681be2017-07-27 23:24:43 +0000620 LeafVector = std::vector<SuffixTreeNode *>(Str.size());
Jessica Paquette596f4832017-03-06 21:31:18 +0000621
622 // Keep track of the number of suffixes we have to add of the current
623 // prefix.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000624 unsigned SuffixesToAdd = 0;
Jessica Paquette596f4832017-03-06 21:31:18 +0000625 Active.Node = Root;
626
627 // Construct the suffix tree iteratively on each prefix of the string.
628 // PfxEndIdx is the end index of the current prefix.
629 // End is one past the last element in the string.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000630 for (unsigned PfxEndIdx = 0, End = Str.size(); PfxEndIdx < End;
631 PfxEndIdx++) {
Jessica Paquette596f4832017-03-06 21:31:18 +0000632 SuffixesToAdd++;
633 LeafEndIdx = PfxEndIdx; // Extend each of the leaves.
634 SuffixesToAdd = extend(PfxEndIdx, SuffixesToAdd);
635 }
636
637 // Set the suffix indices of each leaf.
638 assert(Root && "Root node can't be nullptr!");
639 setSuffixIndices(*Root, 0);
640 }
641};
642
Jessica Paquette596f4832017-03-06 21:31:18 +0000643/// \brief Maps \p MachineInstrs to unsigned integers and stores the mappings.
644struct InstructionMapper {
645
646 /// \brief The next available integer to assign to a \p MachineInstr that
647 /// cannot be outlined.
648 ///
649 /// Set to -3 for compatability with \p DenseMapInfo<unsigned>.
650 unsigned IllegalInstrNumber = -3;
651
652 /// \brief The next available integer to assign to a \p MachineInstr that can
653 /// be outlined.
654 unsigned LegalInstrNumber = 0;
655
656 /// Correspondence from \p MachineInstrs to unsigned integers.
657 DenseMap<MachineInstr *, unsigned, MachineInstrExpressionTrait>
658 InstructionIntegerMap;
659
660 /// Corresponcence from unsigned integers to \p MachineInstrs.
661 /// Inverse of \p InstructionIntegerMap.
662 DenseMap<unsigned, MachineInstr *> IntegerInstructionMap;
663
664 /// The vector of unsigned integers that the module is mapped to.
665 std::vector<unsigned> UnsignedVec;
666
667 /// \brief Stores the location of the instruction associated with the integer
668 /// at index i in \p UnsignedVec for each index i.
669 std::vector<MachineBasicBlock::iterator> InstrList;
670
671 /// \brief Maps \p *It to a legal integer.
672 ///
673 /// Updates \p InstrList, \p UnsignedVec, \p InstructionIntegerMap,
674 /// \p IntegerInstructionMap, and \p LegalInstrNumber.
675 ///
676 /// \returns The integer that \p *It was mapped to.
677 unsigned mapToLegalUnsigned(MachineBasicBlock::iterator &It) {
678
679 // Get the integer for this instruction or give it the current
680 // LegalInstrNumber.
681 InstrList.push_back(It);
682 MachineInstr &MI = *It;
683 bool WasInserted;
684 DenseMap<MachineInstr *, unsigned, MachineInstrExpressionTrait>::iterator
Jessica Paquette78681be2017-07-27 23:24:43 +0000685 ResultIt;
Jessica Paquette596f4832017-03-06 21:31:18 +0000686 std::tie(ResultIt, WasInserted) =
Jessica Paquette78681be2017-07-27 23:24:43 +0000687 InstructionIntegerMap.insert(std::make_pair(&MI, LegalInstrNumber));
Jessica Paquette596f4832017-03-06 21:31:18 +0000688 unsigned MINumber = ResultIt->second;
689
690 // There was an insertion.
691 if (WasInserted) {
692 LegalInstrNumber++;
693 IntegerInstructionMap.insert(std::make_pair(MINumber, &MI));
694 }
695
696 UnsignedVec.push_back(MINumber);
697
698 // Make sure we don't overflow or use any integers reserved by the DenseMap.
699 if (LegalInstrNumber >= IllegalInstrNumber)
700 report_fatal_error("Instruction mapping overflow!");
701
Jessica Paquette78681be2017-07-27 23:24:43 +0000702 assert(LegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
703 "Tried to assign DenseMap tombstone or empty key to instruction.");
704 assert(LegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
705 "Tried to assign DenseMap tombstone or empty key to instruction.");
Jessica Paquette596f4832017-03-06 21:31:18 +0000706
707 return MINumber;
708 }
709
710 /// Maps \p *It to an illegal integer.
711 ///
712 /// Updates \p InstrList, \p UnsignedVec, and \p IllegalInstrNumber.
713 ///
714 /// \returns The integer that \p *It was mapped to.
715 unsigned mapToIllegalUnsigned(MachineBasicBlock::iterator &It) {
716 unsigned MINumber = IllegalInstrNumber;
717
718 InstrList.push_back(It);
719 UnsignedVec.push_back(IllegalInstrNumber);
720 IllegalInstrNumber--;
721
722 assert(LegalInstrNumber < IllegalInstrNumber &&
723 "Instruction mapping overflow!");
724
Jessica Paquette78681be2017-07-27 23:24:43 +0000725 assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
726 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
Jessica Paquette596f4832017-03-06 21:31:18 +0000727
Jessica Paquette78681be2017-07-27 23:24:43 +0000728 assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
729 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
Jessica Paquette596f4832017-03-06 21:31:18 +0000730
731 return MINumber;
732 }
733
734 /// \brief Transforms a \p MachineBasicBlock into a \p vector of \p unsigneds
735 /// and appends it to \p UnsignedVec and \p InstrList.
736 ///
737 /// Two instructions are assigned the same integer if they are identical.
738 /// If an instruction is deemed unsafe to outline, then it will be assigned an
739 /// unique integer. The resulting mapping is placed into a suffix tree and
740 /// queried for candidates.
741 ///
742 /// \param MBB The \p MachineBasicBlock to be translated into integers.
743 /// \param TRI \p TargetRegisterInfo for the module.
744 /// \param TII \p TargetInstrInfo for the module.
745 void convertToUnsignedVec(MachineBasicBlock &MBB,
746 const TargetRegisterInfo &TRI,
747 const TargetInstrInfo &TII) {
Jessica Paquette3291e732018-01-09 00:26:18 +0000748 unsigned Flags = TII.getMachineOutlinerMBBFlags(MBB);
749
Jessica Paquette596f4832017-03-06 21:31:18 +0000750 for (MachineBasicBlock::iterator It = MBB.begin(), Et = MBB.end(); It != Et;
751 It++) {
752
753 // Keep track of where this instruction is in the module.
Jessica Paquette3291e732018-01-09 00:26:18 +0000754 switch (TII.getOutliningType(It, Flags)) {
Jessica Paquette78681be2017-07-27 23:24:43 +0000755 case TargetInstrInfo::MachineOutlinerInstrType::Illegal:
756 mapToIllegalUnsigned(It);
757 break;
Jessica Paquette596f4832017-03-06 21:31:18 +0000758
Jessica Paquette78681be2017-07-27 23:24:43 +0000759 case TargetInstrInfo::MachineOutlinerInstrType::Legal:
760 mapToLegalUnsigned(It);
761 break;
Jessica Paquette596f4832017-03-06 21:31:18 +0000762
Jessica Paquette78681be2017-07-27 23:24:43 +0000763 case TargetInstrInfo::MachineOutlinerInstrType::Invisible:
764 break;
Jessica Paquette596f4832017-03-06 21:31:18 +0000765 }
766 }
767
768 // After we're done every insertion, uniquely terminate this part of the
769 // "string". This makes sure we won't match across basic block or function
770 // boundaries since the "end" is encoded uniquely and thus appears in no
771 // repeated substring.
772 InstrList.push_back(MBB.end());
773 UnsignedVec.push_back(IllegalInstrNumber);
774 IllegalInstrNumber--;
775 }
776
777 InstructionMapper() {
778 // Make sure that the implementation of DenseMapInfo<unsigned> hasn't
779 // changed.
780 assert(DenseMapInfo<unsigned>::getEmptyKey() == (unsigned)-1 &&
Jessica Paquette78681be2017-07-27 23:24:43 +0000781 "DenseMapInfo<unsigned>'s empty key isn't -1!");
Jessica Paquette596f4832017-03-06 21:31:18 +0000782 assert(DenseMapInfo<unsigned>::getTombstoneKey() == (unsigned)-2 &&
Jessica Paquette78681be2017-07-27 23:24:43 +0000783 "DenseMapInfo<unsigned>'s tombstone key isn't -2!");
Jessica Paquette596f4832017-03-06 21:31:18 +0000784 }
785};
786
787/// \brief An interprocedural pass which finds repeated sequences of
788/// instructions and replaces them with calls to functions.
789///
790/// Each instruction is mapped to an unsigned integer and placed in a string.
791/// The resulting mapping is then placed in a \p SuffixTree. The \p SuffixTree
792/// is then repeatedly queried for repeated sequences of instructions. Each
793/// non-overlapping repeated sequence is then placed in its own
794/// \p MachineFunction and each instance is then replaced with a call to that
795/// function.
796struct MachineOutliner : public ModulePass {
797
798 static char ID;
799
Jessica Paquette13593842017-10-07 00:16:34 +0000800 /// \brief Set to true if the outliner should consider functions with
801 /// linkonceodr linkage.
802 bool OutlineFromLinkOnceODRs = false;
803
Jessica Paquette729e6862018-01-18 00:00:58 +0000804 // Collection of IR functions created by the outliner.
805 std::vector<Function *> CreatedIRFunctions;
806
Jessica Paquette596f4832017-03-06 21:31:18 +0000807 StringRef getPassName() const override { return "Machine Outliner"; }
808
809 void getAnalysisUsage(AnalysisUsage &AU) const override {
810 AU.addRequired<MachineModuleInfo>();
811 AU.addPreserved<MachineModuleInfo>();
812 AU.setPreservesAll();
813 ModulePass::getAnalysisUsage(AU);
814 }
815
Jessica Paquettec9ab4c22017-10-17 18:43:15 +0000816 MachineOutliner(bool OutlineFromLinkOnceODRs = false)
817 : ModulePass(ID), OutlineFromLinkOnceODRs(OutlineFromLinkOnceODRs) {
Jessica Paquette596f4832017-03-06 21:31:18 +0000818 initializeMachineOutlinerPass(*PassRegistry::getPassRegistry());
819 }
820
Jessica Paquette78681be2017-07-27 23:24:43 +0000821 /// Find all repeated substrings that satisfy the outlining cost model.
822 ///
823 /// If a substring appears at least twice, then it must be represented by
824 /// an internal node which appears in at least two suffixes. Each suffix is
825 /// represented by a leaf node. To do this, we visit each internal node in
826 /// the tree, using the leaf children of each internal node. If an internal
827 /// node represents a beneficial substring, then we use each of its leaf
828 /// children to find the locations of its substring.
829 ///
830 /// \param ST A suffix tree to query.
831 /// \param TII TargetInstrInfo for the target.
832 /// \param Mapper Contains outlining mapping information.
833 /// \param[out] CandidateList Filled with candidates representing each
834 /// beneficial substring.
835 /// \param[out] FunctionList Filled with a list of \p OutlinedFunctions each
836 /// type of candidate.
837 ///
838 /// \returns The length of the longest candidate found.
Jessica Paquette9df7fde2017-10-23 23:36:46 +0000839 unsigned
840 findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
841 InstructionMapper &Mapper,
842 std::vector<std::shared_ptr<Candidate>> &CandidateList,
843 std::vector<OutlinedFunction> &FunctionList);
Jessica Paquette78681be2017-07-27 23:24:43 +0000844
Jessica Paquette596f4832017-03-06 21:31:18 +0000845 /// \brief Replace the sequences of instructions represented by the
846 /// \p Candidates in \p CandidateList with calls to \p MachineFunctions
847 /// described in \p FunctionList.
848 ///
849 /// \param M The module we are outlining from.
850 /// \param CandidateList A list of candidates to be outlined.
851 /// \param FunctionList A list of functions to be inserted into the module.
852 /// \param Mapper Contains the instruction mappings for the module.
Jessica Paquette9df7fde2017-10-23 23:36:46 +0000853 bool outline(Module &M,
854 const ArrayRef<std::shared_ptr<Candidate>> &CandidateList,
Jessica Paquette596f4832017-03-06 21:31:18 +0000855 std::vector<OutlinedFunction> &FunctionList,
856 InstructionMapper &Mapper);
857
858 /// Creates a function for \p OF and inserts it into the module.
859 MachineFunction *createOutlinedFunction(Module &M, const OutlinedFunction &OF,
860 InstructionMapper &Mapper);
861
862 /// Find potential outlining candidates and store them in \p CandidateList.
863 ///
864 /// For each type of potential candidate, also build an \p OutlinedFunction
865 /// struct containing the information to build the function for that
866 /// candidate.
867 ///
868 /// \param[out] CandidateList Filled with outlining candidates for the module.
869 /// \param[out] FunctionList Filled with functions corresponding to each type
870 /// of \p Candidate.
871 /// \param ST The suffix tree for the module.
872 /// \param TII TargetInstrInfo for the module.
873 ///
874 /// \returns The length of the longest candidate found. 0 if there are none.
Jessica Paquette9df7fde2017-10-23 23:36:46 +0000875 unsigned
876 buildCandidateList(std::vector<std::shared_ptr<Candidate>> &CandidateList,
877 std::vector<OutlinedFunction> &FunctionList,
878 SuffixTree &ST, InstructionMapper &Mapper,
879 const TargetInstrInfo &TII);
Jessica Paquette596f4832017-03-06 21:31:18 +0000880
Jessica Paquette60d31fc2017-10-17 21:11:58 +0000881 /// Helper function for pruneOverlaps.
882 /// Removes \p C from the candidate list, and updates its \p OutlinedFunction.
883 void prune(Candidate &C, std::vector<OutlinedFunction> &FunctionList);
884
Jessica Paquette596f4832017-03-06 21:31:18 +0000885 /// \brief Remove any overlapping candidates that weren't handled by the
886 /// suffix tree's pruning method.
887 ///
888 /// Pruning from the suffix tree doesn't necessarily remove all overlaps.
889 /// If a short candidate is chosen for outlining, then a longer candidate
890 /// which has that short candidate as a suffix is chosen, the tree's pruning
891 /// method will not find it. Thus, we need to prune before outlining as well.
892 ///
893 /// \param[in,out] CandidateList A list of outlining candidates.
894 /// \param[in,out] FunctionList A list of functions to be outlined.
Jessica Paquette809d7082017-07-28 03:21:58 +0000895 /// \param Mapper Contains instruction mapping info for outlining.
Jessica Paquette596f4832017-03-06 21:31:18 +0000896 /// \param MaxCandidateLen The length of the longest candidate.
897 /// \param TII TargetInstrInfo for the module.
Jessica Paquette9df7fde2017-10-23 23:36:46 +0000898 void pruneOverlaps(std::vector<std::shared_ptr<Candidate>> &CandidateList,
Jessica Paquette596f4832017-03-06 21:31:18 +0000899 std::vector<OutlinedFunction> &FunctionList,
Jessica Paquette809d7082017-07-28 03:21:58 +0000900 InstructionMapper &Mapper, unsigned MaxCandidateLen,
901 const TargetInstrInfo &TII);
Jessica Paquette596f4832017-03-06 21:31:18 +0000902
903 /// Construct a suffix tree on the instructions in \p M and outline repeated
904 /// strings from that tree.
905 bool runOnModule(Module &M) override;
906};
907
908} // Anonymous namespace.
909
910char MachineOutliner::ID = 0;
911
912namespace llvm {
Jessica Paquette13593842017-10-07 00:16:34 +0000913ModulePass *createMachineOutlinerPass(bool OutlineFromLinkOnceODRs) {
914 return new MachineOutliner(OutlineFromLinkOnceODRs);
915}
916
Jessica Paquette78681be2017-07-27 23:24:43 +0000917} // namespace llvm
Jessica Paquette596f4832017-03-06 21:31:18 +0000918
Jessica Paquette78681be2017-07-27 23:24:43 +0000919INITIALIZE_PASS(MachineOutliner, DEBUG_TYPE, "Machine Function Outliner", false,
920 false)
921
Jessica Paquette9df7fde2017-10-23 23:36:46 +0000922unsigned MachineOutliner::findCandidates(
923 SuffixTree &ST, const TargetInstrInfo &TII, InstructionMapper &Mapper,
924 std::vector<std::shared_ptr<Candidate>> &CandidateList,
925 std::vector<OutlinedFunction> &FunctionList) {
Jessica Paquette78681be2017-07-27 23:24:43 +0000926 CandidateList.clear();
927 FunctionList.clear();
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000928 unsigned MaxLen = 0;
Jessica Paquette78681be2017-07-27 23:24:43 +0000929
930 // FIXME: Visit internal nodes instead of leaves.
931 for (SuffixTreeNode *Leaf : ST.LeafVector) {
932 assert(Leaf && "Leaves in LeafVector cannot be null!");
933 if (!Leaf->IsInTree)
934 continue;
935
936 assert(Leaf->Parent && "All leaves must have parents!");
937 SuffixTreeNode &Parent = *(Leaf->Parent);
938
939 // If it doesn't appear enough, or we already outlined from it, skip it.
940 if (Parent.OccurrenceCount < 2 || Parent.isRoot() || !Parent.IsInTree)
941 continue;
942
Jessica Paquette809d7082017-07-28 03:21:58 +0000943 // Figure out if this candidate is beneficial.
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000944 unsigned StringLen = Leaf->ConcatLen - (unsigned)Leaf->size();
Jessica Paquette95c11072017-08-14 22:57:41 +0000945
946 // Too short to be beneficial; skip it.
947 // FIXME: This isn't necessarily true for, say, X86. If we factor in
948 // instruction lengths we need more information than this.
949 if (StringLen < 2)
950 continue;
951
Jessica Paquetted87f5442017-07-29 02:55:46 +0000952 // If this is a beneficial class of candidate, then every one is stored in
953 // this vector.
954 std::vector<Candidate> CandidatesForRepeatedSeq;
955
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000956 // Describes the start and end point of each candidate. This allows the
957 // target to infer some information about each occurrence of each repeated
958 // sequence.
Jessica Paquetted87f5442017-07-29 02:55:46 +0000959 // FIXME: CandidatesForRepeatedSeq and this should be combined.
960 std::vector<
961 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
Jessica Paquette4cf187b2017-09-27 20:47:39 +0000962 RepeatedSequenceLocs;
Jessica Paquetted87f5442017-07-29 02:55:46 +0000963
Jessica Paquette809d7082017-07-28 03:21:58 +0000964 // Figure out the call overhead for each instance of the sequence.
965 for (auto &ChildPair : Parent.Children) {
966 SuffixTreeNode *M = ChildPair.second;
Jessica Paquette78681be2017-07-27 23:24:43 +0000967
Jessica Paquette809d7082017-07-28 03:21:58 +0000968 if (M && M->IsInTree && M->isLeaf()) {
Jessica Paquetted87f5442017-07-29 02:55:46 +0000969 // Never visit this leaf again.
970 M->IsInTree = false;
Jessica Paquette52df8012017-12-01 21:56:56 +0000971 unsigned StartIdx = M->SuffixIdx;
972 unsigned EndIdx = StartIdx + StringLen - 1;
973
974 // Trick: Discard some candidates that would be incompatible with the
975 // ones we've already found for this sequence. This will save us some
976 // work in candidate selection.
977 //
978 // If two candidates overlap, then we can't outline them both. This
979 // happens when we have candidates that look like, say
980 //
981 // AA (where each "A" is an instruction).
982 //
983 // We might have some portion of the module that looks like this:
984 // AAAAAA (6 A's)
985 //
986 // In this case, there are 5 different copies of "AA" in this range, but
987 // at most 3 can be outlined. If only outlining 3 of these is going to
988 // be unbeneficial, then we ought to not bother.
989 //
990 // Note that two things DON'T overlap when they look like this:
991 // start1...end1 .... start2...end2
992 // That is, one must either
993 // * End before the other starts
994 // * Start after the other ends
995 if (std::all_of(CandidatesForRepeatedSeq.begin(),
996 CandidatesForRepeatedSeq.end(),
997 [&StartIdx, &EndIdx](const Candidate &C) {
998 return (EndIdx < C.getStartIdx() ||
999 StartIdx > C.getEndIdx());
1000 })) {
1001 // It doesn't overlap with anything, so we can outline it.
1002 // Each sequence is over [StartIt, EndIt].
1003 MachineBasicBlock::iterator StartIt = Mapper.InstrList[StartIdx];
1004 MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
1005
Jessica Paquettea499c3c2018-01-19 21:21:49 +00001006 // Save the MachineFunction containing the Candidate.
1007 MachineFunction *MF = StartIt->getParent()->getParent();
1008 assert(MF && "Candidate doesn't have a MF?");
1009
Jessica Paquette52df8012017-12-01 21:56:56 +00001010 // Save the candidate and its location.
1011 CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen,
Jessica Paquettea499c3c2018-01-19 21:21:49 +00001012 FunctionList.size(), MF);
Jessica Paquette52df8012017-12-01 21:56:56 +00001013 RepeatedSequenceLocs.emplace_back(std::make_pair(StartIt, EndIt));
1014 }
Jessica Paquette809d7082017-07-28 03:21:58 +00001015 }
1016 }
1017
Jessica Paquetteacc15e12017-10-03 20:32:55 +00001018 // We've found something we might want to outline.
1019 // Create an OutlinedFunction to store it and check if it'd be beneficial
1020 // to outline.
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001021 TargetInstrInfo::MachineOutlinerInfo MInfo =
1022 TII.getOutlininingCandidateInfo(RepeatedSequenceLocs);
Jessica Paquetteacc15e12017-10-03 20:32:55 +00001023 std::vector<unsigned> Seq;
1024 for (unsigned i = Leaf->SuffixIdx; i < Leaf->SuffixIdx + StringLen; i++)
1025 Seq.push_back(ST.Str[i]);
Jessica Paquette52df8012017-12-01 21:56:56 +00001026 OutlinedFunction OF(FunctionList.size(), CandidatesForRepeatedSeq.size(),
1027 Seq, MInfo);
Jessica Paquetteacc15e12017-10-03 20:32:55 +00001028 unsigned Benefit = OF.getBenefit();
Jessica Paquette809d7082017-07-28 03:21:58 +00001029
Jessica Paquetteffe4abc2017-08-31 21:02:45 +00001030 // Is it better to outline this candidate than not?
Jessica Paquetteacc15e12017-10-03 20:32:55 +00001031 if (Benefit < 1) {
Jessica Paquetteffe4abc2017-08-31 21:02:45 +00001032 // Outlining this candidate would take more instructions than not
1033 // outlining.
1034 // Emit a remark explaining why we didn't outline this candidate.
1035 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator> C =
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001036 RepeatedSequenceLocs[0];
Vivek Pandya95906582017-10-11 17:12:59 +00001037 MachineOptimizationRemarkEmitter MORE(
1038 *(C.first->getParent()->getParent()), nullptr);
1039 MORE.emit([&]() {
1040 MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper",
1041 C.first->getDebugLoc(),
1042 C.first->getParent());
1043 R << "Did not outline " << NV("Length", StringLen) << " instructions"
1044 << " from " << NV("NumOccurrences", RepeatedSequenceLocs.size())
1045 << " locations."
1046 << " Instructions from outlining all occurrences ("
1047 << NV("OutliningCost", OF.getOutliningCost()) << ")"
1048 << " >= Unoutlined instruction count ("
Jessica Paquette85af63d2017-10-17 19:03:23 +00001049 << NV("NotOutliningCost", StringLen * OF.getOccurrenceCount()) << ")"
Vivek Pandya95906582017-10-11 17:12:59 +00001050 << " (Also found at: ";
Jessica Paquetteffe4abc2017-08-31 21:02:45 +00001051
Vivek Pandya95906582017-10-11 17:12:59 +00001052 // Tell the user the other places the candidate was found.
1053 for (unsigned i = 1, e = RepeatedSequenceLocs.size(); i < e; i++) {
1054 R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
1055 RepeatedSequenceLocs[i].first->getDebugLoc());
1056 if (i != e - 1)
1057 R << ", ";
1058 }
Jessica Paquetteffe4abc2017-08-31 21:02:45 +00001059
Vivek Pandya95906582017-10-11 17:12:59 +00001060 R << ")";
1061 return R;
1062 });
Jessica Paquetteffe4abc2017-08-31 21:02:45 +00001063
1064 // Move to the next candidate.
Jessica Paquette78681be2017-07-27 23:24:43 +00001065 continue;
Jessica Paquetteffe4abc2017-08-31 21:02:45 +00001066 }
Jessica Paquette78681be2017-07-27 23:24:43 +00001067
1068 if (StringLen > MaxLen)
1069 MaxLen = StringLen;
1070
Jessica Paquetted87f5442017-07-29 02:55:46 +00001071 // At this point, the candidate class is seen as beneficial. Set their
1072 // benefit values and save them in the candidate list.
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001073 std::vector<std::shared_ptr<Candidate>> CandidatesForFn;
Jessica Paquetted87f5442017-07-29 02:55:46 +00001074 for (Candidate &C : CandidatesForRepeatedSeq) {
1075 C.Benefit = Benefit;
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001076 C.MInfo = MInfo;
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001077 std::shared_ptr<Candidate> Cptr = std::make_shared<Candidate>(C);
1078 CandidateList.push_back(Cptr);
1079 CandidatesForFn.push_back(Cptr);
Jessica Paquette78681be2017-07-27 23:24:43 +00001080 }
1081
Jessica Paquetteacc15e12017-10-03 20:32:55 +00001082 FunctionList.push_back(OF);
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001083 FunctionList.back().Candidates = CandidatesForFn;
Jessica Paquette78681be2017-07-27 23:24:43 +00001084
1085 // Move to the next function.
Jessica Paquette78681be2017-07-27 23:24:43 +00001086 Parent.IsInTree = false;
1087 }
1088
1089 return MaxLen;
1090}
Jessica Paquette596f4832017-03-06 21:31:18 +00001091
Jessica Paquette60d31fc2017-10-17 21:11:58 +00001092// Remove C from the candidate space, and update its OutlinedFunction.
1093void MachineOutliner::prune(Candidate &C,
1094 std::vector<OutlinedFunction> &FunctionList) {
1095 // Get the OutlinedFunction associated with this Candidate.
1096 OutlinedFunction &F = FunctionList[C.FunctionIdx];
1097
1098 // Update C's associated function's occurrence count.
1099 F.decrement();
1100
1101 // Remove C from the CandidateList.
1102 C.InCandidateList = false;
1103
1104 DEBUG(dbgs() << "- Removed a Candidate \n";
1105 dbgs() << "--- Num fns left for candidate: " << F.getOccurrenceCount()
1106 << "\n";
1107 dbgs() << "--- Candidate's functions's benefit: " << F.getBenefit()
1108 << "\n";);
1109}
1110
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001111void MachineOutliner::pruneOverlaps(
1112 std::vector<std::shared_ptr<Candidate>> &CandidateList,
1113 std::vector<OutlinedFunction> &FunctionList, InstructionMapper &Mapper,
1114 unsigned MaxCandidateLen, const TargetInstrInfo &TII) {
Jessica Paquette91999162017-09-28 23:39:36 +00001115
1116 // Return true if this candidate became unbeneficial for outlining in a
1117 // previous step.
Jessica Paquette60d31fc2017-10-17 21:11:58 +00001118 auto ShouldSkipCandidate = [&FunctionList, this](Candidate &C) {
Jessica Paquette91999162017-09-28 23:39:36 +00001119
1120 // Check if the candidate was removed in a previous step.
1121 if (!C.InCandidateList)
1122 return true;
1123
Jessica Paquette85af63d2017-10-17 19:03:23 +00001124 // C must be alive. Check if we should remove it.
Jessica Paquette60d31fc2017-10-17 21:11:58 +00001125 if (FunctionList[C.FunctionIdx].getBenefit() < 1) {
1126 prune(C, FunctionList);
Jessica Paquette91999162017-09-28 23:39:36 +00001127 return true;
1128 }
1129
1130 // C is in the list, and F is still beneficial.
1131 return false;
1132 };
1133
Jessica Paquetteacffa282017-03-23 21:27:38 +00001134 // TODO: Experiment with interval trees or other interval-checking structures
1135 // to lower the time complexity of this function.
1136 // TODO: Can we do better than the simple greedy choice?
1137 // Check for overlaps in the range.
1138 // This is O(MaxCandidateLen * CandidateList.size()).
Jessica Paquette596f4832017-03-06 21:31:18 +00001139 for (auto It = CandidateList.begin(), Et = CandidateList.end(); It != Et;
1140 It++) {
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001141 Candidate &C1 = **It;
Jessica Paquette596f4832017-03-06 21:31:18 +00001142
Jessica Paquette91999162017-09-28 23:39:36 +00001143 // If C1 was already pruned, or its function is no longer beneficial for
1144 // outlining, move to the next candidate.
1145 if (ShouldSkipCandidate(C1))
Jessica Paquette596f4832017-03-06 21:31:18 +00001146 continue;
1147
Jessica Paquette596f4832017-03-06 21:31:18 +00001148 // The minimum start index of any candidate that could overlap with this
1149 // one.
1150 unsigned FarthestPossibleIdx = 0;
1151
1152 // Either the index is 0, or it's at most MaxCandidateLen indices away.
Jessica Paquette1934fd22017-10-23 16:25:53 +00001153 if (C1.getStartIdx() > MaxCandidateLen)
1154 FarthestPossibleIdx = C1.getStartIdx() - MaxCandidateLen;
Jessica Paquette596f4832017-03-06 21:31:18 +00001155
Hiroshi Inoue0909ca12018-01-26 08:15:29 +00001156 // Compare against the candidates in the list that start at most
Jessica Paquetteacffa282017-03-23 21:27:38 +00001157 // FarthestPossibleIdx indices away from C1. There are at most
1158 // MaxCandidateLen of these.
Jessica Paquette596f4832017-03-06 21:31:18 +00001159 for (auto Sit = It + 1; Sit != Et; Sit++) {
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001160 Candidate &C2 = **Sit;
Jessica Paquette596f4832017-03-06 21:31:18 +00001161
1162 // Is this candidate too far away to overlap?
Jessica Paquette1934fd22017-10-23 16:25:53 +00001163 if (C2.getStartIdx() < FarthestPossibleIdx)
Jessica Paquette596f4832017-03-06 21:31:18 +00001164 break;
1165
Jessica Paquette91999162017-09-28 23:39:36 +00001166 // If C2 was already pruned, or its function is no longer beneficial for
1167 // outlining, move to the next candidate.
1168 if (ShouldSkipCandidate(C2))
Jessica Paquette596f4832017-03-06 21:31:18 +00001169 continue;
1170
Jessica Paquette596f4832017-03-06 21:31:18 +00001171 // Do C1 and C2 overlap?
1172 //
1173 // Not overlapping:
1174 // High indices... [C1End ... C1Start][C2End ... C2Start] ...Low indices
1175 //
1176 // We sorted our candidate list so C2Start <= C1Start. We know that
1177 // C2End > C2Start since each candidate has length >= 2. Therefore, all we
1178 // have to check is C2End < C2Start to see if we overlap.
Jessica Paquette1934fd22017-10-23 16:25:53 +00001179 if (C2.getEndIdx() < C1.getStartIdx())
Jessica Paquette596f4832017-03-06 21:31:18 +00001180 continue;
1181
Jessica Paquetteacffa282017-03-23 21:27:38 +00001182 // C1 and C2 overlap.
1183 // We need to choose the better of the two.
1184 //
1185 // Approximate this by picking the one which would have saved us the
1186 // most instructions before any pruning.
Jessica Paquette60d31fc2017-10-17 21:11:58 +00001187
1188 // Is C2 a better candidate?
1189 if (C2.Benefit > C1.Benefit) {
1190 // Yes, so prune C1. Since C1 is dead, we don't have to compare it
1191 // against anything anymore, so break.
1192 prune(C1, FunctionList);
Jessica Paquetteacffa282017-03-23 21:27:38 +00001193 break;
1194 }
Jessica Paquette60d31fc2017-10-17 21:11:58 +00001195
1196 // Prune C2 and move on to the next candidate.
1197 prune(C2, FunctionList);
Jessica Paquette596f4832017-03-06 21:31:18 +00001198 }
1199 }
1200}
1201
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001202unsigned MachineOutliner::buildCandidateList(
1203 std::vector<std::shared_ptr<Candidate>> &CandidateList,
1204 std::vector<OutlinedFunction> &FunctionList, SuffixTree &ST,
1205 InstructionMapper &Mapper, const TargetInstrInfo &TII) {
Jessica Paquette596f4832017-03-06 21:31:18 +00001206
1207 std::vector<unsigned> CandidateSequence; // Current outlining candidate.
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001208 unsigned MaxCandidateLen = 0; // Length of the longest candidate.
Jessica Paquette596f4832017-03-06 21:31:18 +00001209
Jessica Paquette78681be2017-07-27 23:24:43 +00001210 MaxCandidateLen =
1211 findCandidates(ST, TII, Mapper, CandidateList, FunctionList);
Jessica Paquette596f4832017-03-06 21:31:18 +00001212
Jessica Paquette596f4832017-03-06 21:31:18 +00001213 // Sort the candidates in decending order. This will simplify the outlining
1214 // process when we have to remove the candidates from the mapping by
1215 // allowing us to cut them out without keeping track of an offset.
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001216 std::stable_sort(
1217 CandidateList.begin(), CandidateList.end(),
1218 [](const std::shared_ptr<Candidate> &LHS,
1219 const std::shared_ptr<Candidate> &RHS) { return *LHS < *RHS; });
Jessica Paquette596f4832017-03-06 21:31:18 +00001220
1221 return MaxCandidateLen;
1222}
1223
1224MachineFunction *
1225MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
Jessica Paquette78681be2017-07-27 23:24:43 +00001226 InstructionMapper &Mapper) {
Jessica Paquette596f4832017-03-06 21:31:18 +00001227
1228 // Create the function name. This should be unique. For now, just hash the
1229 // module name and include it in the function name plus the number of this
1230 // function.
1231 std::ostringstream NameStream;
Jessica Paquette78681be2017-07-27 23:24:43 +00001232 NameStream << "OUTLINED_FUNCTION_" << OF.Name;
Jessica Paquette596f4832017-03-06 21:31:18 +00001233
1234 // Create the function using an IR-level function.
1235 LLVMContext &C = M.getContext();
1236 Function *F = dyn_cast<Function>(
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001237 M.getOrInsertFunction(NameStream.str(), Type::getVoidTy(C)));
Jessica Paquette596f4832017-03-06 21:31:18 +00001238 assert(F && "Function was null!");
1239
1240 // NOTE: If this is linkonceodr, then we can take advantage of linker deduping
1241 // which gives us better results when we outline from linkonceodr functions.
1242 F->setLinkage(GlobalValue::PrivateLinkage);
1243 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
1244
Jessica Paquette729e6862018-01-18 00:00:58 +00001245 // Save F so that we can add debug info later if we need to.
1246 CreatedIRFunctions.push_back(F);
1247
Jessica Paquette596f4832017-03-06 21:31:18 +00001248 BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
1249 IRBuilder<> Builder(EntryBB);
1250 Builder.CreateRetVoid();
1251
1252 MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
Matthias Braun7bda1952017-06-06 00:44:35 +00001253 MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
Jessica Paquette596f4832017-03-06 21:31:18 +00001254 MachineBasicBlock &MBB = *MF.CreateMachineBasicBlock();
1255 const TargetSubtargetInfo &STI = MF.getSubtarget();
1256 const TargetInstrInfo &TII = *STI.getInstrInfo();
1257
1258 // Insert the new function into the module.
1259 MF.insert(MF.begin(), &MBB);
1260
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001261 TII.insertOutlinerPrologue(MBB, MF, OF.MInfo);
Jessica Paquette596f4832017-03-06 21:31:18 +00001262
1263 // Copy over the instructions for the function using the integer mappings in
1264 // its sequence.
1265 for (unsigned Str : OF.Sequence) {
1266 MachineInstr *NewMI =
1267 MF.CloneMachineInstr(Mapper.IntegerInstructionMap.find(Str)->second);
1268 NewMI->dropMemRefs();
1269
1270 // Don't keep debug information for outlined instructions.
Jessica Paquette596f4832017-03-06 21:31:18 +00001271 NewMI->setDebugLoc(DebugLoc());
1272 MBB.insert(MBB.end(), NewMI);
1273 }
1274
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001275 TII.insertOutlinerEpilogue(MBB, MF, OF.MInfo);
Jessica Paquette729e6862018-01-18 00:00:58 +00001276
Jessica Paquettea499c3c2018-01-19 21:21:49 +00001277 // If there's a DISubprogram associated with this outlined function, then
1278 // emit debug info for the outlined function.
1279 if (DISubprogram *SP = OF.getSubprogramOrNull()) {
1280 // We have a DISubprogram. Get its DICompileUnit.
1281 DICompileUnit *CU = SP->getUnit();
1282 DIBuilder DB(M, true, CU);
1283 DIFile *Unit = SP->getFile();
1284 Mangler Mg;
1285
1286 // Walk over each IR function we created in the outliner and create
1287 // DISubprograms for each function.
1288 for (Function *F : CreatedIRFunctions) {
1289 // Get the mangled name of the function for the linkage name.
1290 std::string Dummy;
1291 llvm::raw_string_ostream MangledNameStream(Dummy);
1292 Mg.getNameWithPrefix(MangledNameStream, F, false);
1293
1294 DISubprogram *SP = DB.createFunction(
1295 Unit /* Context */, F->getName(), StringRef(MangledNameStream.str()),
1296 Unit /* File */,
1297 0 /* Line 0 is reserved for compiler-generated code. */,
1298 DB.createSubroutineType(
1299 DB.getOrCreateTypeArray(None)), /* void type */
1300 false, true, 0, /* Line 0 is reserved for compiler-generated code. */
1301 DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
1302 true /* Outlined code is optimized code by definition. */);
1303
1304 // Don't add any new variables to the subprogram.
1305 DB.finalizeSubprogram(SP);
1306
1307 // Attach subprogram to the function.
1308 F->setSubprogram(SP);
1309 }
1310
1311 // We're done with the DIBuilder.
1312 DB.finalize();
1313 }
1314
Geoff Berry82203c42018-01-31 20:15:16 +00001315 MF.getRegInfo().freezeReservedRegs(MF);
Jessica Paquette596f4832017-03-06 21:31:18 +00001316 return &MF;
1317}
1318
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001319bool MachineOutliner::outline(
1320 Module &M, const ArrayRef<std::shared_ptr<Candidate>> &CandidateList,
1321 std::vector<OutlinedFunction> &FunctionList, InstructionMapper &Mapper) {
Jessica Paquette596f4832017-03-06 21:31:18 +00001322
1323 bool OutlinedSomething = false;
Jessica Paquette596f4832017-03-06 21:31:18 +00001324 // Replace the candidates with calls to their respective outlined functions.
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001325 for (const std::shared_ptr<Candidate> &Cptr : CandidateList) {
1326 Candidate &C = *Cptr;
Jessica Paquette596f4832017-03-06 21:31:18 +00001327 // Was the candidate removed during pruneOverlaps?
1328 if (!C.InCandidateList)
1329 continue;
1330
1331 // If not, then look at its OutlinedFunction.
1332 OutlinedFunction &OF = FunctionList[C.FunctionIdx];
1333
1334 // Was its OutlinedFunction made unbeneficial during pruneOverlaps?
Jessica Paquette85af63d2017-10-17 19:03:23 +00001335 if (OF.getBenefit() < 1)
Jessica Paquette596f4832017-03-06 21:31:18 +00001336 continue;
1337
1338 // If not, then outline it.
Jessica Paquette1934fd22017-10-23 16:25:53 +00001339 assert(C.getStartIdx() < Mapper.InstrList.size() &&
Jessica Paquettec9ab4c22017-10-17 18:43:15 +00001340 "Candidate out of bounds!");
Jessica Paquette1934fd22017-10-23 16:25:53 +00001341 MachineBasicBlock *MBB = (*Mapper.InstrList[C.getStartIdx()]).getParent();
1342 MachineBasicBlock::iterator StartIt = Mapper.InstrList[C.getStartIdx()];
1343 unsigned EndIdx = C.getEndIdx();
Jessica Paquette596f4832017-03-06 21:31:18 +00001344
1345 assert(EndIdx < Mapper.InstrList.size() && "Candidate out of bounds!");
1346 MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
1347 assert(EndIt != MBB->end() && "EndIt out of bounds!");
1348
1349 EndIt++; // Erase needs one past the end index.
1350
1351 // Does this candidate have a function yet?
Jessica Paquetteacffa282017-03-23 21:27:38 +00001352 if (!OF.MF) {
Jessica Paquette596f4832017-03-06 21:31:18 +00001353 OF.MF = createOutlinedFunction(M, OF, Mapper);
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001354 MachineBasicBlock *MBB = &*OF.MF->begin();
1355
1356 // Output a remark telling the user that an outlined function was created,
1357 // and explaining where it came from.
1358 MachineOptimizationRemarkEmitter MORE(*OF.MF, nullptr);
1359 MachineOptimizationRemark R(DEBUG_TYPE, "OutlinedFunction",
1360 MBB->findDebugLoc(MBB->begin()), MBB);
1361 R << "Saved " << NV("OutliningBenefit", OF.getBenefit())
1362 << " instructions by "
1363 << "outlining " << NV("Length", OF.Sequence.size()) << " instructions "
1364 << "from " << NV("NumOccurrences", OF.getOccurrenceCount())
1365 << " locations. "
1366 << "(Found at: ";
1367
1368 // Tell the user the other places the candidate was found.
1369 for (size_t i = 0, e = OF.Candidates.size(); i < e; i++) {
1370
1371 // Skip over things that were pruned.
1372 if (!OF.Candidates[i]->InCandidateList)
1373 continue;
1374
1375 R << NV(
1376 (Twine("StartLoc") + Twine(i)).str(),
1377 Mapper.InstrList[OF.Candidates[i]->getStartIdx()]->getDebugLoc());
1378 if (i != e - 1)
1379 R << ", ";
1380 }
1381
1382 R << ")";
1383
1384 MORE.emit(R);
Jessica Paquetteacffa282017-03-23 21:27:38 +00001385 FunctionsCreated++;
1386 }
Jessica Paquette596f4832017-03-06 21:31:18 +00001387
1388 MachineFunction *MF = OF.MF;
1389 const TargetSubtargetInfo &STI = MF->getSubtarget();
1390 const TargetInstrInfo &TII = *STI.getInstrInfo();
1391
1392 // Insert a call to the new function and erase the old sequence.
Jessica Paquette4cf187b2017-09-27 20:47:39 +00001393 TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.MInfo);
Jessica Paquette1934fd22017-10-23 16:25:53 +00001394 StartIt = Mapper.InstrList[C.getStartIdx()];
Jessica Paquette596f4832017-03-06 21:31:18 +00001395 MBB->erase(StartIt, EndIt);
1396
1397 OutlinedSomething = true;
1398
1399 // Statistics.
1400 NumOutlined++;
1401 }
1402
Jessica Paquette78681be2017-07-27 23:24:43 +00001403 DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n";);
Jessica Paquette596f4832017-03-06 21:31:18 +00001404
1405 return OutlinedSomething;
1406}
1407
1408bool MachineOutliner::runOnModule(Module &M) {
1409
1410 // Is there anything in the module at all?
1411 if (M.empty())
1412 return false;
1413
1414 MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
Jessica Paquette78681be2017-07-27 23:24:43 +00001415 const TargetSubtargetInfo &STI =
1416 MMI.getOrCreateMachineFunction(*M.begin()).getSubtarget();
Jessica Paquette596f4832017-03-06 21:31:18 +00001417 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
1418 const TargetInstrInfo *TII = STI.getInstrInfo();
Jessica Paquette3291e732018-01-09 00:26:18 +00001419
Jessica Paquette596f4832017-03-06 21:31:18 +00001420 InstructionMapper Mapper;
1421
1422 // Build instruction mappings for each function in the module.
1423 for (Function &F : M) {
Matthias Braun7bda1952017-06-06 00:44:35 +00001424 MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
Jessica Paquette596f4832017-03-06 21:31:18 +00001425
1426 // Is the function empty? Safe to outline from?
Jessica Paquette13593842017-10-07 00:16:34 +00001427 if (F.empty() ||
1428 !TII->isFunctionSafeToOutlineFrom(MF, OutlineFromLinkOnceODRs))
Jessica Paquette596f4832017-03-06 21:31:18 +00001429 continue;
1430
1431 // If it is, look at each MachineBasicBlock in the function.
1432 for (MachineBasicBlock &MBB : MF) {
1433
Jessica Paquette757e1202018-01-13 00:42:28 +00001434 // Is there anything in MBB? And is it the target of an indirect branch?
1435 if (MBB.empty() || MBB.hasAddressTaken())
Jessica Paquette596f4832017-03-06 21:31:18 +00001436 continue;
1437
1438 // If yes, map it.
1439 Mapper.convertToUnsignedVec(MBB, *TRI, *TII);
1440 }
1441 }
1442
1443 // Construct a suffix tree, use it to find candidates, and then outline them.
1444 SuffixTree ST(Mapper.UnsignedVec);
Jessica Paquette9df7fde2017-10-23 23:36:46 +00001445 std::vector<std::shared_ptr<Candidate>> CandidateList;
Jessica Paquette596f4832017-03-06 21:31:18 +00001446 std::vector<OutlinedFunction> FunctionList;
1447
Jessica Paquetteacffa282017-03-23 21:27:38 +00001448 // Find all of the outlining candidates.
Jessica Paquette596f4832017-03-06 21:31:18 +00001449 unsigned MaxCandidateLen =
Jessica Paquettec984e212017-03-13 18:39:33 +00001450 buildCandidateList(CandidateList, FunctionList, ST, Mapper, *TII);
Jessica Paquette596f4832017-03-06 21:31:18 +00001451
Jessica Paquetteacffa282017-03-23 21:27:38 +00001452 // Remove candidates that overlap with other candidates.
Jessica Paquette809d7082017-07-28 03:21:58 +00001453 pruneOverlaps(CandidateList, FunctionList, Mapper, MaxCandidateLen, *TII);
Jessica Paquetteacffa282017-03-23 21:27:38 +00001454
1455 // Outline each of the candidates and return true if something was outlined.
Jessica Paquette729e6862018-01-18 00:00:58 +00001456 bool OutlinedSomething = outline(M, CandidateList, FunctionList, Mapper);
1457
Jessica Paquette729e6862018-01-18 00:00:58 +00001458 return OutlinedSomething;
Jessica Paquette596f4832017-03-06 21:31:18 +00001459}