llvm.org GIT mirror llvm / d43adee
[Outliner] Fixed Asan bot failure in r296418 Fixed the asan bot failure which led to the last commit of the outliner being reverted. The change is in lib/CodeGen/MachineOutliner.cpp in the SuffixTree's constructor. LeafVector is no longer initialized using reserve but just a standard constructor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297081 91177308-0d34-0410-b5e6-96231b3b80d8 Jessica Paquette 3 years ago
11 changed file(s) with 1754 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
404404
405405 /// This pass combine basic blocks guarded by the same branch.
406406 extern char &BranchCoalescingID;
407
408 /// This pass performs outlining on machine instructions directly before
409 /// printing assembly.
410 ModulePass *createMachineOutlinerPass();
411
407412 } // End llvm namespace
408413
409414 /// Target machine pass initializer for passes with dependencies. Use with
236236 void initializeMachineLoopInfoPass(PassRegistry&);
237237 void initializeMachineModuleInfoPass(PassRegistry&);
238238 void initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry&);
239 void initializeMachineOutlinerPass(PassRegistry&);
239240 void initializeMachinePipelinerPass(PassRegistry&);
240241 void initializeMachinePostDominatorTreePass(PassRegistry&);
241242 void initializeMachineRegionInfoPassPass(PassRegistry&);
15071507 return false;
15081508 }
15091509
1510 /// \brief Return how many instructions would be saved by outlining a
1511 /// sequence containing \p SequenceSize instructions that appears
1512 /// \p Occurrences times in a module.
1513 virtual unsigned getOutliningBenefit(size_t SequenceSize, size_t Occurrences)
1514 const {
1515 llvm_unreachable(
1516 "Target didn't implement TargetInstrInfo::getOutliningBenefit!");
1517 }
1518
1519 /// Represents how an instruction should be mapped by the outliner.
1520 /// \p Legal instructions are those which are safe to outline.
1521 /// \p Illegal instructions are those which cannot be outlined.
1522 /// \p Invisible instructions are instructions which can be outlined, but
1523 /// shouldn't actually impact the outlining result.
1524 enum MachineOutlinerInstrType {Legal, Illegal, Invisible};
1525
1526 /// Return true if the instruction is legal to outline.
1527 virtual MachineOutlinerInstrType getOutliningType(MachineInstr &MI) const {
1528 llvm_unreachable(
1529 "Target didn't implement TargetInstrInfo::getOutliningType!");
1530 }
1531
1532 /// Insert a custom epilogue for outlined functions.
1533 /// This may be empty, in which case no epilogue or return statement will be
1534 /// emitted.
1535 virtual void insertOutlinerEpilogue(MachineBasicBlock &MBB,
1536 MachineFunction &MF) const {
1537 llvm_unreachable(
1538 "Target didn't implement TargetInstrInfo::insertOutlinerEpilogue!");
1539 }
1540
1541 /// Insert a call to an outlined function into the program.
1542 /// Returns an iterator to the spot where we inserted the call. This must be
1543 /// implemented by the target.
1544 virtual MachineBasicBlock::iterator
1545 insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
1546 MachineBasicBlock::iterator &It, MachineFunction &MF)
1547 const {
1548 llvm_unreachable(
1549 "Target didn't implement TargetInstrInfo::insertOutlinedCall!");
1550 }
1551
1552 /// Insert a custom prologue for outlined functions.
1553 /// This may be empty, in which case no prologue will be emitted.
1554 virtual void insertOutlinerPrologue(MachineBasicBlock &MBB,
1555 MachineFunction &MF) const {
1556 llvm_unreachable(
1557 "Target didn't implement TargetInstrInfo::insertOutlinerPrologue!");
1558 }
1559
1560 /// Return true if the function can safely be outlined from.
1561 /// By default, this means that the function has no red zone.
1562 virtual bool isFunctionSafeToOutlineFrom(MachineFunction &F) const {
1563 llvm_unreachable("Target didn't implement "
1564 "TargetInstrInfo::isFunctionSafeToOutlineFrom!");
1565 }
1566
15101567 private:
15111568 unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
15121569 unsigned CatchRetOpcode;
7474 MachineModuleInfo.cpp
7575 MachineModuleInfoImpls.cpp
7676 MachineOptimizationRemarkEmitter.cpp
77 MachineOutliner.cpp
7778 MachinePassRegistry.cpp
7879 MachinePipeliner.cpp
7980 MachinePostDominators.cpp
5757 initializeMachineLoopInfoPass(Registry);
5858 initializeMachineModuleInfoPass(Registry);
5959 initializeMachineOptimizationRemarkEmitterPassPass(Registry);
60 initializeMachineOutlinerPass(Registry);
6061 initializeMachinePipelinerPass(Registry);
6162 initializeMachinePostDominatorTreePass(Registry);
6263 initializeMachineRegionInfoPassPass(Registry);
0 //===---- MachineOutliner.cpp - Outline instructions -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Replaces repeated sequences of instructions with function calls.
11 ///
12 /// This works by placing every instruction from every basic block in a
13 /// suffix tree, and repeatedly querying that tree for repeated sequences of
14 /// instructions. If a sequence of instructions appears often, then it ought
15 /// to be beneficial to pull out into a function.
16 ///
17 /// This was originally presented at the 2016 LLVM Developers' Meeting in the
18 /// talk "Reducing Code Size Using Outlining". For a high-level overview of
19 /// how this pass works, the talk is available on YouTube at
20 ///
21 /// https://www.youtube.com/watch?v=yorld-WSOeU
22 ///
23 /// The slides for the talk are available at
24 ///
25 /// http://www.llvm.org/devmtg/2016-11/Slides/Paquette-Outliner.pdf
26 ///
27 /// The talk provides an overview of how the outliner finds candidates and
28 /// ultimately outlines them. It describes how the main data structure for this
29 /// pass, the suffix tree, is queried and purged for candidates. It also gives
30 /// a simplified suffix tree construction algorithm for suffix trees based off
31 /// of the algorithm actually used here, Ukkonen's algorithm.
32 ///
33 /// For the original RFC for this pass, please see
34 ///
35 /// http://lists.llvm.org/pipermail/llvm-dev/2016-August/104170.html
36 ///
37 /// For more information on the suffix tree data structure, please see
38 /// https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
39 ///
40 //===----------------------------------------------------------------------===//
41 #include "llvm/ADT/DenseMap.h"
42 #include "llvm/ADT/Statistic.h"
43 #include "llvm/ADT/Twine.h"
44 #include "llvm/CodeGen/MachineFrameInfo.h"
45 #include "llvm/CodeGen/MachineFunction.h"
46 #include "llvm/CodeGen/MachineInstrBuilder.h"
47 #include "llvm/CodeGen/MachineModuleInfo.h"
48 #include "llvm/CodeGen/Passes.h"
49 #include "llvm/IR/IRBuilder.h"
50 #include "llvm/Support/Allocator.h"
51 #include "llvm/Support/Debug.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include "llvm/Target/TargetInstrInfo.h"
54 #include "llvm/Target/TargetMachine.h"
55 #include "llvm/Target/TargetRegisterInfo.h"
56 #include "llvm/Target/TargetSubtargetInfo.h"
57 #include
58 #include
59 #include
60 #include
61 #include
62
63 #define DEBUG_TYPE "machine-outliner"
64
65 using namespace llvm;
66
67 STATISTIC(NumOutlined, "Number of candidates outlined");
68 STATISTIC(FunctionsCreated, "Number of functions created");
69
70 namespace {
71
72 /// Represents an undefined index in the suffix tree.
73 const size_t EmptyIdx = -1;
74
75 /// A node in a suffix tree which represents a substring or suffix.
76 ///
77 /// Each node has either no children or at least two children, with the root
78 /// being a exception in the empty tree.
79 ///
80 /// Children are represented as a map between unsigned integers and nodes. If
81 /// a node N has a child M on unsigned integer k, then the mapping represented
82 /// by N is a proper prefix of the mapping represented by M. Note that this,
83 /// although similar to a trie is somewhat different: each node stores a full
84 /// substring of the full mapping rather than a single character state.
85 ///
86 /// Each internal node contains a pointer to the internal node representing
87 /// the same string, but with the first character chopped off. This is stored
88 /// in \p Link. Each leaf node stores the start index of its respective
89 /// suffix in \p SuffixIdx.
90 struct SuffixTreeNode {
91
92 /// The children of this node.
93 ///
94 /// A child existing on an unsigned integer implies that from the mapping
95 /// represented by the current node, there is a way to reach another
96 /// mapping by tacking that character on the end of the current string.
97 DenseMap Children;
98
99 /// A flag set to false if the node has been pruned from the tree.
100 bool IsInTree = true;
101
102 /// The start index of this node's substring in the main string.
103 size_t StartIdx = EmptyIdx;
104
105 /// The end index of this node's substring in the main string.
106 ///
107 /// Every leaf node must have its \p EndIdx incremented at the end of every
108 /// step in the construction algorithm. To avoid having to update O(N)
109 /// nodes individually at the end of every step, the end index is stored
110 /// as a pointer.
111 size_t *EndIdx = nullptr;
112
113 /// For leaves, the start index of the suffix represented by this node.
114 ///
115 /// For all other nodes, this is ignored.
116 size_t SuffixIdx = EmptyIdx;
117
118 /// \brief For internal nodes, a pointer to the internal node representing
119 /// the same sequence with the first character chopped off.
120 ///
121 /// This has two major purposes in the suffix tree. The first is as a
122 /// shortcut in Ukkonen's construction algorithm. One of the things that
123 /// Ukkonen's algorithm does to achieve linear-time construction is
124 /// keep track of which node the next insert should be at. This makes each
125 /// insert O(1), and there are a total of O(N) inserts. The suffix link
126 /// helps with inserting children of internal nodes.
127 ///
128 /// Say we add a child to an internal node with associated mapping S. The
129 /// next insertion must be at the node representing S - its first character.
130 /// This is given by the way that we iteratively build the tree in Ukkonen's
131 /// algorithm. The main idea is to look at the suffixes of each prefix in the
132 /// string, starting with the longest suffix of the prefix, and ending with
133 /// the shortest. Therefore, if we keep pointers between such nodes, we can
134 /// move to the next insertion point in O(1) time. If we don't, then we'd
135 /// have to query from the root, which takes O(N) time. This would make the
136 /// construction algorithm O(N^2) rather than O(N).
137 ///
138 /// The suffix link is also used during the tree pruning process to let us
139 /// quickly throw out a bunch of potential overlaps. Say we have a sequence
140 /// S we want to outline. Then each of its suffixes contribute to at least
141 /// one overlapping case. Therefore, we can follow the suffix links
142 /// starting at the node associated with S to the root and "delete" those
143 /// nodes, save for the root. For each candidate, this removes
144 /// O(|candidate|) overlaps from the search space. We don't actually
145 /// completely invalidate these nodes though; doing that is far too
146 /// aggressive. Consider the following pathological string:
147 ///
148 /// 1 2 3 1 2 3 2 3 2 3 2 3 2 3 2 3 2 3
149 ///
150 /// If we, for the sake of example, outlined 1 2 3, then we would throw
151 /// out all instances of 2 3. This isn't desirable. To get around this,
152 /// when we visit a link node, we decrement its occurrence count by the
153 /// number of sequences we outlined in the current step. In the pathological
154 /// example, the 2 3 node would have an occurrence count of 8, while the
155 /// 1 2 3 node would have an occurrence count of 2. Thus, the 2 3 node
156 /// would survive to the next round allowing us to outline the extra
157 /// instances of 2 3.
158 SuffixTreeNode *Link = nullptr;
159
160 /// The parent of this node. Every node except for the root has a parent.
161 SuffixTreeNode *Parent = nullptr;
162
163 /// The number of times this node's string appears in the tree.
164 ///
165 /// This is equal to the number of leaf children of the string. It represents
166 /// the number of suffixes that the node's string is a prefix of.
167 size_t OccurrenceCount = 0;
168
169 /// Returns true if this node is a leaf.
170 bool isLeaf() const { return SuffixIdx != EmptyIdx; }
171
172 /// Returns true if this node is the root of its owning \p SuffixTree.
173 bool isRoot() const { return StartIdx == EmptyIdx; }
174
175 /// Return the number of elements in the substring associated with this node.
176 size_t size() const {
177
178 // Is it the root? If so, it's the empty string so return 0.
179 if (isRoot())
180 return 0;
181
182 assert(*EndIdx != EmptyIdx && "EndIdx is undefined!");
183
184 // Size = the number of elements in the string.
185 // For example, [0 1 2 3] has length 4, not 3. 3-0 = 3, so we have 3-0+1.
186 return *EndIdx - StartIdx + 1;
187 }
188
189 SuffixTreeNode(size_t StartIdx, size_t *EndIdx, SuffixTreeNode *Link,
190 SuffixTreeNode *Parent)
191 : StartIdx(StartIdx), EndIdx(EndIdx), Link(Link), Parent(Parent) {}
192
193 SuffixTreeNode() {}
194 };
195
196 /// A data structure for fast substring queries.
197 ///
198 /// Suffix trees represent the suffixes of their input strings in their leaves.
199 /// A suffix tree is a type of compressed trie structure where each node
200 /// represents an entire substring rather than a single character. Each leaf
201 /// of the tree is a suffix.
202 ///
203 /// A suffix tree can be seen as a type of state machine where each state is a
204 /// substring of the full string. The tree is structured so that, for a string
205 /// of length N, there are exactly N leaves in the tree. This structure allows
206 /// us to quickly find repeated substrings of the input string.
207 ///
208 /// In this implementation, a "string" is a vector of unsigned integers.
209 /// These integers may result from hashing some data type. A suffix tree can
210 /// contain 1 or many strings, which can then be queried as one large string.
211 ///
212 /// The suffix tree is implemented using Ukkonen's algorithm for linear-time
213 /// suffix tree construction. Ukkonen's algorithm is explained in more detail
214 /// in the paper by Esko Ukkonen "On-line construction of suffix trees. The
215 /// paper is available at
216 ///
217 /// https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
218 class SuffixTree {
219 private:
220 /// Each element is an integer representing an instruction in the module.
221 ArrayRef Str;
222
223 /// Maintains each node in the tree.
224 BumpPtrAllocator NodeAllocator;
225
226 /// The root of the suffix tree.
227 ///
228 /// The root represents the empty string. It is maintained by the
229 /// \p NodeAllocator like every other node in the tree.
230 SuffixTreeNode *Root = nullptr;
231
232 /// Stores each leaf in the tree for better pruning.
233 std::vector LeafVector;
234
235 /// Maintains the end indices of the internal nodes in the tree.
236 ///
237 /// Each internal node is guaranteed to never have its end index change
238 /// during the construction algorithm; however, leaves must be updated at
239 /// every step. Therefore, we need to store leaf end indices by reference
240 /// to avoid updating O(N) leaves at every step of construction. Thus,
241 /// every internal node must be allocated its own end index.
242 BumpPtrAllocator InternalEndIdxAllocator;
243
244 /// The end index of each leaf in the tree.
245 size_t LeafEndIdx = -1;
246
247 /// \brief Helper struct which keeps track of the next insertion point in
248 /// Ukkonen's algorithm.
249 struct ActiveState {
250 /// The next node to insert at.
251 SuffixTreeNode *Node;
252
253 /// The index of the first character in the substring currently being added.
254 size_t Idx = EmptyIdx;
255
256 /// The length of the substring we have to add at the current step.
257 size_t Len = 0;
258 };
259
260 /// \brief The point the next insertion will take place at in the
261 /// construction algorithm.
262 ActiveState Active;
263
264 /// Allocate a leaf node and add it to the tree.
265 ///
266 /// \param Parent The parent of this node.
267 /// \param StartIdx The start index of this node's associated string.
268 /// \param Edge The label on the edge leaving \p Parent to this node.
269 ///
270 /// \returns A pointer to the allocated leaf node.
271 SuffixTreeNode *insertLeaf(SuffixTreeNode &Parent, size_t StartIdx,
272 unsigned Edge) {
273
274 assert(StartIdx <= LeafEndIdx && "String can't start after it ends!");
275
276 SuffixTreeNode *N = new (NodeAllocator) SuffixTreeNode(StartIdx,
277 &LeafEndIdx,
278 nullptr,
279 &Parent);
280 Parent.Children[Edge] = N;
281
282 return N;
283 }
284
285 /// Allocate an internal node and add it to the tree.
286 ///
287 /// \param Parent The parent of this node. Only null when allocating the root.
288 /// \param StartIdx The start index of this node's associated string.
289 /// \param EndIdx The end index of this node's associated string.
290 /// \param Edge The label on the edge leaving \p Parent to this node.
291 ///
292 /// \returns A pointer to the allocated internal node.
293 SuffixTreeNode *insertInternalNode(SuffixTreeNode *Parent, size_t StartIdx,
294 size_t EndIdx, unsigned Edge) {
295
296 assert(StartIdx <= EndIdx && "String can't start after it ends!");
297 assert(!(!Parent && StartIdx != EmptyIdx) &&
298 "Non-root internal nodes must have parents!");
299
300 size_t *E = new (InternalEndIdxAllocator) size_t(EndIdx);
301 SuffixTreeNode *N = new (NodeAllocator) SuffixTreeNode(StartIdx,
302 E,
303 Root,
304 Parent);
305 if (Parent)
306 Parent->Children[Edge] = N;
307
308 return N;
309 }
310
311 /// \brief Set the suffix indices of the leaves to the start indices of their
312 /// respective suffixes. Also stores each leaf in \p LeafVector at its
313 /// respective suffix index.
314 ///
315 /// \param[in] CurrNode The node currently being visited.
316 /// \param CurrIdx The current index of the string being visited.
317 void setSuffixIndices(SuffixTreeNode &CurrNode, size_t CurrIdx) {
318
319 bool IsLeaf = CurrNode.Children.size() == 0 && !CurrNode.isRoot();
320
321 // Traverse the tree depth-first.
322 for (auto &ChildPair : CurrNode.Children) {
323 assert(ChildPair.second && "Node had a null child!");
324 setSuffixIndices(*ChildPair.second,
325 CurrIdx + ChildPair.second->size());
326 }
327
328 // Is this node a leaf?
329 if (IsLeaf) {
330 // If yes, give it a suffix index and bump its parent's occurrence count.
331 CurrNode.SuffixIdx = Str.size() - CurrIdx;
332 assert(CurrNode.Parent && "CurrNode had no parent!");
333 CurrNode.Parent->OccurrenceCount++;
334
335 // Store the leaf in the leaf vector for pruning later.
336 LeafVector[CurrNode.SuffixIdx] = &CurrNode;
337 }
338 }
339
340 /// \brief Construct the suffix tree for the prefix of the input ending at
341 /// \p EndIdx.
342 ///
343 /// Used to construct the full suffix tree iteratively. At the end of each
344 /// step, the constructed suffix tree is either a valid suffix tree, or a
345 /// suffix tree with implicit suffixes. At the end of the final step, the
346 /// suffix tree is a valid tree.
347 ///
348 /// \param EndIdx The end index of the current prefix in the main string.
349 /// \param SuffixesToAdd The number of suffixes that must be added
350 /// to complete the suffix tree at the current phase.
351 ///
352 /// \returns The number of suffixes that have not been added at the end of
353 /// this step.
354 unsigned extend(size_t EndIdx, size_t SuffixesToAdd) {
355 SuffixTreeNode *NeedsLink = nullptr;
356
357 while (SuffixesToAdd > 0) {
358
359 // Are we waiting to add anything other than just the last character?
360 if (Active.Len == 0) {
361 // If not, then say the active index is the end index.
362 Active.Idx = EndIdx;
363 }
364
365 assert(Active.Idx <= EndIdx && "Start index can't be after end index!");
366
367 // The first character in the current substring we're looking at.
368 unsigned FirstChar = Str[Active.Idx];
369
370 // Have we inserted anything starting with FirstChar at the current node?
371 if (Active.Node->Children.count(FirstChar) == 0) {
372 // If not, then we can just insert a leaf and move too the next step.
373 insertLeaf(*Active.Node, EndIdx, FirstChar);
374
375 // The active node is an internal node, and we visited it, so it must
376 // need a link if it doesn't have one.
377 if (NeedsLink) {
378 NeedsLink->Link = Active.Node;
379 NeedsLink = nullptr;
380 }
381 } else {
382 // There's a match with FirstChar, so look for the point in the tree to
383 // insert a new node.
384 SuffixTreeNode *NextNode = Active.Node->Children[FirstChar];
385
386 size_t SubstringLen = NextNode->size();
387
388 // Is the current suffix we're trying to insert longer than the size of
389 // the child we want to move to?
390 if (Active.Len >= SubstringLen) {
391 // If yes, then consume the characters we've seen and move to the next
392 // node.
393 Active.Idx += SubstringLen;
394 Active.Len -= SubstringLen;
395 Active.Node = NextNode;
396 continue;
397 }
398
399 // Otherwise, the suffix we're trying to insert must be contained in the
400 // next node we want to move to.
401 unsigned LastChar = Str[EndIdx];
402
403 // Is the string we're trying to insert a substring of the next node?
404 if (Str[NextNode->StartIdx + Active.Len] == LastChar) {
405 // If yes, then we're done for this step. Remember our insertion point
406 // and move to the next end index. At this point, we have an implicit
407 // suffix tree.
408 if (NeedsLink && !Active.Node->isRoot()) {
409 NeedsLink->Link = Active.Node;
410 NeedsLink = nullptr;
411 }
412
413 Active.Len++;
414 break;
415 }
416
417 // The string we're trying to insert isn't a substring of the next node,
418 // but matches up to a point. Split the node.
419 //
420 // For example, say we ended our search at a node n and we're trying to
421 // insert ABD. Then we'll create a new node s for AB, reduce n to just
422 // representing C, and insert a new leaf node l to represent d. This
423 // allows us to ensure that if n was a leaf, it remains a leaf.
424 //
425 // | ABC ---split---> | AB
426 // n s
427 // C / \ D
428 // n l
429
430 // The node s from the diagram
431 SuffixTreeNode *SplitNode =
432 insertInternalNode(Active.Node,
433 NextNode->StartIdx,
434 NextNode->StartIdx + Active.Len - 1,
435 FirstChar);
436
437 // Insert the new node representing the new substring into the tree as
438 // a child of the split node. This is the node l from the diagram.
439 insertLeaf(*SplitNode, EndIdx, LastChar);
440
441 // Make the old node a child of the split node and update its start
442 // index. This is the node n from the diagram.
443 NextNode->StartIdx += Active.Len;
444 NextNode->Parent = SplitNode;
445 SplitNode->Children[Str[NextNode->StartIdx]] = NextNode;
446
447 // SplitNode is an internal node, update the suffix link.
448 if (NeedsLink)
449 NeedsLink->Link = SplitNode;
450
451 NeedsLink = SplitNode;
452 }
453
454 // We've added something new to the tree, so there's one less suffix to
455 // add.
456 SuffixesToAdd--;
457
458 if (Active.Node->isRoot()) {
459 if (Active.Len > 0) {
460 Active.Len--;
461 Active.Idx = EndIdx - SuffixesToAdd + 1;
462 }
463 } else {
464 // Start the next phase at the next smallest suffix.
465 Active.Node = Active.Node->Link;
466 }
467 }
468
469 return SuffixesToAdd;
470 }
471
472 /// \brief Return the start index and length of a string which maximizes a
473 /// benefit function by traversing the tree depth-first.
474 ///
475 /// Helper function for \p bestRepeatedSubstring.
476 ///
477 /// \param CurrNode The node currently being visited.
478 /// \param CurrLen Length of the current string.
479 /// \param[out] BestLen Length of the most beneficial substring.
480 /// \param[out] MaxBenefit Benefit of the most beneficial substring.
481 /// \param[out] BestStartIdx Start index of the most beneficial substring.
482 /// \param BenefitFn The function the query should return a maximum string
483 /// for.
484 void findBest(SuffixTreeNode &CurrNode, size_t CurrLen, size_t &BestLen,
485 size_t &MaxBenefit, size_t &BestStartIdx,
486 const std::function
487 &BenefitFn) {
488
489 if (!CurrNode.IsInTree)
490 return;
491
492 // Can we traverse further down the tree?
493 if (!CurrNode.isLeaf()) {
494 // If yes, continue the traversal.
495 for (auto &ChildPair : CurrNode.Children) {
496 if (ChildPair.second && ChildPair.second->IsInTree)
497 findBest(*ChildPair.second, CurrLen + ChildPair.second->size(),
498 BestLen, MaxBenefit, BestStartIdx, BenefitFn);
499 }
500 } else {
501 // We hit a leaf.
502 size_t StringLen = CurrLen - CurrNode.size();
503 unsigned Benefit = BenefitFn(CurrNode, StringLen);
504
505 // Did we do better than in the last step?
506 if (Benefit <= MaxBenefit)
507 return;
508
509 // We did better, so update the best string.
510 MaxBenefit = Benefit;
511 BestStartIdx = CurrNode.SuffixIdx;
512 BestLen = StringLen;
513 }
514 }
515
516 public:
517
518 /// \brief Return a substring of the tree with maximum benefit if such a
519 /// substring exists.
520 ///
521 /// Clears the input vector and fills it with a maximum substring or empty.
522 ///
523 /// \param[in,out] Best The most beneficial substring in the tree. Empty
524 /// if it does not exist.
525 /// \param BenefitFn The function the query should return a maximum string
526 /// for.
527 void bestRepeatedSubstring(std::vector &Best,
528 const std::function
529 &BenefitFn) {
530 Best.clear();
531 size_t Length = 0; // Becomes the length of the best substring.
532 size_t Benefit = 0; // Becomes the benefit of the best substring.
533 size_t StartIdx = 0; // Becomes the start index of the best substring.
534 findBest(*Root, 0, Length, Benefit, StartIdx, BenefitFn);
535
536 for (size_t Idx = 0; Idx < Length; Idx++)
537 Best.push_back(Str[Idx + StartIdx]);
538 }
539
540 /// Perform a depth-first search for \p QueryString on the suffix tree.
541 ///
542 /// \param QueryString The string to search for.
543 /// \param CurrIdx The current index in \p QueryString that is being matched
544 /// against.
545 /// \param CurrNode The suffix tree node being searched in.
546 ///
547 /// \returns A \p SuffixTreeNode that \p QueryString appears in if such a
548 /// node exists, and \p nullptr otherwise.
549 SuffixTreeNode *findString(const std::vector &QueryString,
550 size_t &CurrIdx, SuffixTreeNode *CurrNode) {
551
552 // The search ended at a nonexistent or pruned node. Quit.
553 if (!CurrNode || !CurrNode->IsInTree)
554 return nullptr;
555
556 unsigned Edge = QueryString[CurrIdx]; // The edge we want to move on.
557 SuffixTreeNode *NextNode = CurrNode->Children[Edge]; // Next node in query.
558
559 if (CurrNode->isRoot()) {
560 // If we're at the root we have to check if there's a child, and move to
561 // that child. Don't consume the character since \p Root represents the
562 // empty string.
563 if (NextNode && NextNode->IsInTree)
564 return findString(QueryString, CurrIdx, NextNode);
565 return nullptr;
566 }
567
568 size_t StrIdx = CurrNode->StartIdx;
569 size_t MaxIdx = QueryString.size();
570 bool ContinueSearching = false;
571
572 // Match as far as possible into the string. If there's a mismatch, quit.
573 for (; CurrIdx < MaxIdx; CurrIdx++, StrIdx++) {
574 Edge = QueryString[CurrIdx];
575
576 // We matched perfectly, but still have a remainder to search.
577 if (StrIdx > *(CurrNode->EndIdx)) {
578 ContinueSearching = true;
579 break;
580 }
581
582 if (Edge != Str[StrIdx])
583 return nullptr;
584 }
585
586 NextNode = CurrNode->Children[Edge];
587
588 // Move to the node which matches what we're looking for and continue
589 // searching.
590 if (ContinueSearching)
591 return findString(QueryString, CurrIdx, NextNode);
592
593 // We matched perfectly so we're done.
594 return CurrNode;
595 }
596
597 /// \brief Remove a node from a tree and all nodes representing proper
598 /// suffixes of that node's string.
599 ///
600 /// This is used in the outlining algorithm to reduce the number of
601 /// overlapping candidates
602 ///
603 /// \param N The suffix tree node to start pruning from.
604 /// \param Len The length of the string to be pruned.
605 ///
606 /// \returns True if this candidate didn't overlap with a previously chosen
607 /// candidate.
608 bool prune(SuffixTreeNode *N, size_t Len) {
609
610 bool NoOverlap = true;
611 std::vector IndicesToPrune;
612
613 // Look at each of N's children.
614 for (auto &ChildPair : N->Children) {
615 SuffixTreeNode *M = ChildPair.second;
616
617 // Is this a leaf child?
618 if (M && M->IsInTree && M->isLeaf()) {
619 // Save each leaf child's suffix indices and remove them from the tree.
620 IndicesToPrune.push_back(M->SuffixIdx);
621 M->IsInTree = false;
622 }
623 }
624
625 // Remove each suffix we have to prune from the tree. Each of these will be
626 // I + some offset for I in IndicesToPrune and some offset < Len.
627 unsigned Offset = 1;
628 for (unsigned CurrentSuffix = 1; CurrentSuffix < Len; CurrentSuffix++) {
629 for (unsigned I : IndicesToPrune) {
630
631 unsigned PruneIdx = I + Offset;
632
633 // Is this index actually in the string?
634 if (PruneIdx < LeafVector.size()) {
635 // If yes, we have to try and prune it.
636 // Was the current leaf already pruned by another candidate?
637 if (LeafVector[PruneIdx]->IsInTree) {
638 // If not, prune it.
639 LeafVector[PruneIdx]->IsInTree = false;
640 } else {
641 // If yes, signify that we've found an overlap, but keep pruning.
642 NoOverlap = false;
643 }
644
645 // Update the parent of the current leaf's occurrence count.
646 SuffixTreeNode *Parent = LeafVector[PruneIdx]->Parent;
647
648 // Is the parent still in the tree?
649 if (Parent->OccurrenceCount > 0) {
650 Parent->OccurrenceCount--;
651 Parent->IsInTree = (Parent->OccurrenceCount > 1);
652 }
653 }
654 }
655
656 // Move to the next character in the string.
657 Offset++;
658 }
659
660 // We know we can never outline anything which starts one index back from
661 // the indices we want to outline. This is because our minimum outlining
662 // length is always 2.
663 for (unsigned I : IndicesToPrune) {
664 if (I > 0) {
665
666 unsigned PruneIdx = I-1;
667 SuffixTreeNode *Parent = LeafVector[PruneIdx]->Parent;
668
669 // Was the leaf one index back from I already pruned?
670 if (LeafVector[PruneIdx]->IsInTree) {
671 // If not, prune it.
672 LeafVector[PruneIdx]->IsInTree = false;
673 } else {
674 // If yes, signify that we've found an overlap, but keep pruning.
675 NoOverlap = false;
676 }
677
678 // Update the parent of the current leaf's occurrence count.
679 if (Parent->OccurrenceCount > 0) {
680 Parent->OccurrenceCount--;
681 Parent->IsInTree = (Parent->OccurrenceCount > 1);
682 }
683 }
684 }
685
686 // Finally, remove N from the tree and set its occurrence count to 0.
687 N->IsInTree = false;
688 N->OccurrenceCount = 0;
689
690 return NoOverlap;
691 }
692
693 /// \brief Find each occurrence of of a string in \p QueryString and prune
694 /// their nodes.
695 ///
696 /// \param QueryString The string to search for.
697 /// \param[out] Occurrences The start indices of each occurrence.
698 ///
699 /// \returns Whether or not the occurrence overlaps with a previous candidate.
700 bool findOccurrencesAndPrune(const std::vector &QueryString,
701 std::vector &Occurrences) {
702 size_t Dummy = 0;
703 SuffixTreeNode *N = findString(QueryString, Dummy, Root);
704
705 if (!N || !N->IsInTree)
706 return false;
707
708 // If this is an internal node, occurrences are the number of leaf children
709 // of the node.
710 for (auto &ChildPair : N->Children) {
711 SuffixTreeNode *M = ChildPair.second;
712
713 // Is it a leaf? If so, we have an occurrence.
714 if (M && M->IsInTree && M->isLeaf())
715 Occurrences.push_back(M->SuffixIdx);
716 }
717
718 // If we're in a leaf, then this node is the only occurrence.
719 if (N->isLeaf())
720 Occurrences.push_back(N->SuffixIdx);
721
722 return prune(N, QueryString.size());
723 }
724
725 /// Construct a suffix tree from a sequence of unsigned integers.
726 ///
727 /// \param Str The string to construct the suffix tree for.
728 SuffixTree(const std::vector &Str) : Str(Str) {
729 Root = insertInternalNode(nullptr, EmptyIdx, EmptyIdx, 0);
730 Root->IsInTree = true;
731 Active.Node = Root;
732 LeafVector = std::vector(Str.size());
733
734 // Keep track of the number of suffixes we have to add of the current
735 // prefix.
736 size_t SuffixesToAdd = 0;
737 Active.Node = Root;
738
739 // Construct the suffix tree iteratively on each prefix of the string.
740 // PfxEndIdx is the end index of the current prefix.
741 // End is one past the last element in the string.
742 for (size_t PfxEndIdx = 0, End = Str.size(); PfxEndIdx < End; PfxEndIdx++) {
743 SuffixesToAdd++;
744 LeafEndIdx = PfxEndIdx; // Extend each of the leaves.
745 SuffixesToAdd = extend(PfxEndIdx, SuffixesToAdd);
746 }
747
748 // Set the suffix indices of each leaf.
749 assert(Root && "Root node can't be nullptr!");
750 setSuffixIndices(*Root, 0);
751 }
752 };
753
754 /// \brief An individual sequence of instructions to be replaced with a call to
755 /// an outlined function.
756 struct Candidate {
757
758 /// Set to false if the candidate overlapped with another candidate.
759 bool InCandidateList = true;
760
761 /// The start index of this \p Candidate.
762 size_t StartIdx;
763
764 /// The number of instructions in this \p Candidate.
765 size_t Len;
766
767 /// The index of this \p Candidate's \p OutlinedFunction in the list of
768 /// \p OutlinedFunctions.
769 size_t FunctionIdx;
770
771 Candidate(size_t StartIdx, size_t Len, size_t FunctionIdx)
772 : StartIdx(StartIdx), Len(Len), FunctionIdx(FunctionIdx) {}
773
774 Candidate() {}
775
776 /// \brief Used to ensure that \p Candidates are outlined in an order that
777 /// preserves the start and end indices of other \p Candidates.
778 bool operator<(const Candidate &RHS) const { return StartIdx > RHS.StartIdx; }
779 };
780
781 /// \brief The information necessary to create an outlined function for some
782 /// class of candidate.
783 struct OutlinedFunction {
784
785 /// The actual outlined function created.
786 /// This is initialized after we go through and create the actual function.
787 MachineFunction *MF = nullptr;
788
789 /// A number assigned to this function which appears at the end of its name.
790 size_t Name;
791
792 /// The number of times that this function has appeared.
793 size_t OccurrenceCount = 0;
794
795 /// \brief The sequence of integers corresponding to the instructions in this
796 /// function.
797 std::vector Sequence;
798
799 /// The number of instructions this function would save.
800 unsigned Benefit = 0;
801
802 OutlinedFunction(size_t Name, size_t OccurrenceCount,
803 const std::vector &Sequence,
804 unsigned Benefit)
805 : Name(Name), OccurrenceCount(OccurrenceCount), Sequence(Sequence),
806 Benefit(Benefit)
807 {}
808 };
809
810 /// \brief Maps \p MachineInstrs to unsigned integers and stores the mappings.
811 struct InstructionMapper {
812
813 /// \brief The next available integer to assign to a \p MachineInstr that
814 /// cannot be outlined.
815 ///
816 /// Set to -3 for compatability with \p DenseMapInfo.
817 unsigned IllegalInstrNumber = -3;
818
819 /// \brief The next available integer to assign to a \p MachineInstr that can
820 /// be outlined.
821 unsigned LegalInstrNumber = 0;
822
823 /// Correspondence from \p MachineInstrs to unsigned integers.
824 DenseMap
825 InstructionIntegerMap;
826
827 /// Corresponcence from unsigned integers to \p MachineInstrs.
828 /// Inverse of \p InstructionIntegerMap.
829 DenseMap IntegerInstructionMap;
830
831 /// The vector of unsigned integers that the module is mapped to.
832 std::vector UnsignedVec;
833
834 /// \brief Stores the location of the instruction associated with the integer
835 /// at index i in \p UnsignedVec for each index i.
836 std::vector InstrList;
837
838 /// \brief Maps \p *It to a legal integer.
839 ///
840 /// Updates \p InstrList, \p UnsignedVec, \p InstructionIntegerMap,
841 /// \p IntegerInstructionMap, and \p LegalInstrNumber.
842 ///
843 /// \returns The integer that \p *It was mapped to.
844 unsigned mapToLegalUnsigned(MachineBasicBlock::iterator &It) {
845
846 // Get the integer for this instruction or give it the current
847 // LegalInstrNumber.
848 InstrList.push_back(It);
849 MachineInstr &MI = *It;
850 bool WasInserted;
851 DenseMap::iterator
852 ResultIt;
853 std::tie(ResultIt, WasInserted) =
854 InstructionIntegerMap.insert(std::make_pair(&MI, LegalInstrNumber));
855 unsigned MINumber = ResultIt->second;
856
857 // There was an insertion.
858 if (WasInserted) {
859 LegalInstrNumber++;
860 IntegerInstructionMap.insert(std::make_pair(MINumber, &MI));
861 }
862
863 UnsignedVec.push_back(MINumber);
864
865 // Make sure we don't overflow or use any integers reserved by the DenseMap.
866 if (LegalInstrNumber >= IllegalInstrNumber)
867 report_fatal_error("Instruction mapping overflow!");
868
869 assert(LegalInstrNumber != DenseMapInfo::getEmptyKey()
870 && "Tried to assign DenseMap tombstone or empty key to instruction.");
871 assert(LegalInstrNumber != DenseMapInfo::getTombstoneKey()
872 && "Tried to assign DenseMap tombstone or empty key to instruction.");
873
874 return MINumber;
875 }
876
877 /// Maps \p *It to an illegal integer.
878 ///
879 /// Updates \p InstrList, \p UnsignedVec, and \p IllegalInstrNumber.
880 ///
881 /// \returns The integer that \p *It was mapped to.
882 unsigned mapToIllegalUnsigned(MachineBasicBlock::iterator &It) {
883 unsigned MINumber = IllegalInstrNumber;
884
885 InstrList.push_back(It);
886 UnsignedVec.push_back(IllegalInstrNumber);
887 IllegalInstrNumber--;
888
889 assert(LegalInstrNumber < IllegalInstrNumber &&
890 "Instruction mapping overflow!");
891
892 assert(IllegalInstrNumber !=
893 DenseMapInfo::getEmptyKey() &&
894 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
895
896 assert(IllegalInstrNumber !=
897 DenseMapInfo::getTombstoneKey() &&
898 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
899
900 return MINumber;
901 }
902
903 /// \brief Transforms a \p MachineBasicBlock into a \p vector of \p unsigneds
904 /// and appends it to \p UnsignedVec and \p InstrList.
905 ///
906 /// Two instructions are assigned the same integer if they are identical.
907 /// If an instruction is deemed unsafe to outline, then it will be assigned an
908 /// unique integer. The resulting mapping is placed into a suffix tree and
909 /// queried for candidates.
910 ///
911 /// \param MBB The \p MachineBasicBlock to be translated into integers.
912 /// \param TRI \p TargetRegisterInfo for the module.
913 /// \param TII \p TargetInstrInfo for the module.
914 void convertToUnsignedVec(MachineBasicBlock &MBB,
915 const TargetRegisterInfo &TRI,
916 const TargetInstrInfo &TII) {
917 for (MachineBasicBlock::iterator It = MBB.begin(), Et = MBB.end(); It != Et;
918 It++) {
919
920 // Keep track of where this instruction is in the module.
921 switch(TII.getOutliningType(*It)) {
922 case TargetInstrInfo::MachineOutlinerInstrType::Illegal:
923 mapToIllegalUnsigned(It);
924 break;
925
926 case TargetInstrInfo::MachineOutlinerInstrType::Legal:
927 mapToLegalUnsigned(It);
928 break;
929
930 case TargetInstrInfo::MachineOutlinerInstrType::Invisible:
931 break;
932 }
933 }
934
935 // After we're done every insertion, uniquely terminate this part of the
936 // "string". This makes sure we won't match across basic block or function
937 // boundaries since the "end" is encoded uniquely and thus appears in no
938 // repeated substring.
939 InstrList.push_back(MBB.end());
940 UnsignedVec.push_back(IllegalInstrNumber);
941 IllegalInstrNumber--;
942 }
943
944 InstructionMapper() {
945 // Make sure that the implementation of DenseMapInfo hasn't
946 // changed.
947 assert(DenseMapInfo::getEmptyKey() == (unsigned)-1 &&
948 "DenseMapInfo's empty key isn't -1!");
949 assert(DenseMapInfo::getTombstoneKey() == (unsigned)-2 &&
950 "DenseMapInfo's tombstone key isn't -2!");
951 }
952 };
953
954 /// \brief An interprocedural pass which finds repeated sequences of
955 /// instructions and replaces them with calls to functions.
956 ///
957 /// Each instruction is mapped to an unsigned integer and placed in a string.
958 /// The resulting mapping is then placed in a \p SuffixTree. The \p SuffixTree
959 /// is then repeatedly queried for repeated sequences of instructions. Each
960 /// non-overlapping repeated sequence is then placed in its own
961 /// \p MachineFunction and each instance is then replaced with a call to that
962 /// function.
963 struct MachineOutliner : public ModulePass {
964
965 static char ID;
966
967 StringRef getPassName() const override { return "Machine Outliner"; }
968
969 void getAnalysisUsage(AnalysisUsage &AU) const override {
970 AU.addRequired();
971 AU.addPreserved();
972 AU.setPreservesAll();
973 ModulePass::getAnalysisUsage(AU);
974 }
975
976 MachineOutliner() : ModulePass(ID) {
977 initializeMachineOutlinerPass(*PassRegistry::getPassRegistry());
978 }
979
980 /// \brief Replace the sequences of instructions represented by the
981 /// \p Candidates in \p CandidateList with calls to \p MachineFunctions
982 /// described in \p FunctionList.
983 ///
984 /// \param M The module we are outlining from.
985 /// \param CandidateList A list of candidates to be outlined.
986 /// \param FunctionList A list of functions to be inserted into the module.
987 /// \param Mapper Contains the instruction mappings for the module.
988 bool outline(Module &M, const ArrayRef &CandidateList,
989 std::vector &FunctionList,
990 InstructionMapper &Mapper);
991
992 /// Creates a function for \p OF and inserts it into the module.
993 MachineFunction *createOutlinedFunction(Module &M, const OutlinedFunction &OF,
994 InstructionMapper &Mapper);
995
996 /// Find potential outlining candidates and store them in \p CandidateList.
997 ///
998 /// For each type of potential candidate, also build an \p OutlinedFunction
999 /// struct containing the information to build the function for that
1000 /// candidate.
1001 ///
1002 /// \param[out] CandidateList Filled with outlining candidates for the module.
1003 /// \param[out] FunctionList Filled with functions corresponding to each type
1004 /// of \p Candidate.
1005 /// \param ST The suffix tree for the module.
1006 /// \param TII TargetInstrInfo for the module.
1007 ///
1008 /// \returns The length of the longest candidate found. 0 if there are none.
1009 unsigned buildCandidateList(std::vector &CandidateList,
1010 std::vector &FunctionList,
1011 SuffixTree &ST, const TargetInstrInfo &TII);
1012
1013 /// \brief Remove any overlapping candidates that weren't handled by the
1014 /// suffix tree's pruning method.
1015 ///
1016 /// Pruning from the suffix tree doesn't necessarily remove all overlaps.
1017 /// If a short candidate is chosen for outlining, then a longer candidate
1018 /// which has that short candidate as a suffix is chosen, the tree's pruning
1019 /// method will not find it. Thus, we need to prune before outlining as well.
1020 ///
1021 /// \param[in,out] CandidateList A list of outlining candidates.
1022 /// \param[in,out] FunctionList A list of functions to be outlined.
1023 /// \param MaxCandidateLen The length of the longest candidate.
1024 /// \param TII TargetInstrInfo for the module.
1025 void pruneOverlaps(std::vector &CandidateList,
1026 std::vector &FunctionList,
1027 unsigned MaxCandidateLen,
1028 const TargetInstrInfo &TII);
1029
1030 /// Construct a suffix tree on the instructions in \p M and outline repeated
1031 /// strings from that tree.
1032 bool runOnModule(Module &M) override;
1033 };
1034
1035 } // Anonymous namespace.
1036
1037 char MachineOutliner::ID = 0;
1038
1039 namespace llvm {
1040 ModulePass *createMachineOutlinerPass() { return new MachineOutliner(); }
1041 }
1042
1043 INITIALIZE_PASS(MachineOutliner, "machine-outliner",
1044 "Machine Function Outliner", false, false)
1045
1046 void MachineOutliner::pruneOverlaps(std::vector &CandidateList,
1047 std::vector &FunctionList,
1048 unsigned MaxCandidateLen,
1049 const TargetInstrInfo &TII) {
1050
1051 // Check for overlaps in the range. This is O(n^2) worst case, but we can
1052 // alleviate that somewhat by bounding our search space using the start
1053 // index of our first candidate and the maximum distance an overlapping
1054 // candidate could have from the first candidate.
1055 for (auto It = CandidateList.begin(), Et = CandidateList.end(); It != Et;
1056 It++) {
1057 Candidate &C1 = *It;
1058 OutlinedFunction &F1 = FunctionList[C1.FunctionIdx];
1059
1060 // If we removed this candidate, skip it.
1061 if (!C1.InCandidateList)
1062 continue;
1063
1064 // If the candidate's function isn't good to outline anymore, then
1065 // remove the candidate and skip it.
1066 if (F1.OccurrenceCount < 2 || F1.Benefit < 1) {
1067 C1.InCandidateList = false;
1068 continue;
1069 }
1070
1071 // The minimum start index of any candidate that could overlap with this
1072 // one.
1073 unsigned FarthestPossibleIdx = 0;
1074
1075 // Either the index is 0, or it's at most MaxCandidateLen indices away.
1076 if (C1.StartIdx > MaxCandidateLen)
1077 FarthestPossibleIdx = C1.StartIdx - MaxCandidateLen;
1078
1079 // Compare against the other candidates in the list.
1080 // This is at most MaxCandidateLen/2 other candidates.
1081 // This is because each candidate has to be at least 2 indices away.
1082 // = O(n * MaxCandidateLen/2) comparisons
1083 //
1084 // On average, the maximum length of a candidate is quite small; a fraction
1085 // of the total module length in terms of instructions. If the maximum
1086 // candidate length is large, then there are fewer possible candidates to
1087 // compare against in the first place.
1088 for (auto Sit = It + 1; Sit != Et; Sit++) {
1089 Candidate &C2 = *Sit;
1090 OutlinedFunction &F2 = FunctionList[C2.FunctionIdx];
1091
1092 // Is this candidate too far away to overlap?
1093 // NOTE: This will be true in
1094 // O(max(FarthestPossibleIdx/2, #Candidates remaining)) steps
1095 // for every candidate.
1096 if (C2.StartIdx < FarthestPossibleIdx)
1097 break;
1098
1099 // Did we already remove this candidate in a previous step?
1100 if (!C2.InCandidateList)
1101 continue;
1102
1103 // Is the function beneficial to outline?
1104 if (F2.OccurrenceCount < 2 || F2.Benefit < 1) {
1105 // If not, remove this candidate and move to the next one.
1106 C2.InCandidateList = false;
1107 continue;
1108 }
1109
1110 size_t C2End = C2.StartIdx + C2.Len - 1;
1111
1112 // Do C1 and C2 overlap?
1113 //
1114 // Not overlapping:
1115 // High indices... [C1End ... C1Start][C2End ... C2Start] ...Low indices
1116 //
1117 // We sorted our candidate list so C2Start <= C1Start. We know that
1118 // C2End > C2Start since each candidate has length >= 2. Therefore, all we
1119 // have to check is C2End < C2Start to see if we overlap.
1120 if (C2End < C1.StartIdx)
1121 continue;
1122
1123 // C2 overlaps with C1. Because we pruned the tree already, the only way
1124 // this can happen is if C1 is a proper suffix of C2. Thus, we must have
1125 // found C1 first during our query, so it must have benefit greater or
1126 // equal to C2. Greedily pick C1 as the candidate to keep and toss out C2.
1127 DEBUG (
1128 size_t C1End = C1.StartIdx + C1.Len - 1;
1129 dbgs() << "- Found an overlap to purge.\n";
1130 dbgs() << "--- C1 :[" << C1.StartIdx << ", " << C1End << "]\n";
1131 dbgs() << "--- C2 :[" << C2.StartIdx << ", " << C2End << "]\n";
1132 );
1133
1134 // Update the function's occurrence count and benefit to reflec that C2
1135 // is being removed.
1136 F2.OccurrenceCount--;
1137 F2.Benefit = TII.getOutliningBenefit(F2.Sequence.size(),
1138 F2.OccurrenceCount
1139 );
1140
1141 // Mark C2 as not in the list.
1142 C2.InCandidateList = false;
1143
1144 DEBUG (
1145 dbgs() << "- Removed C2. \n";
1146 dbgs() << "--- Num fns left for C2: " << F2.OccurrenceCount << "\n";
1147 dbgs() << "--- C2's benefit: " << F2.Benefit << "\n";
1148 );
1149 }
1150 }
1151 }
1152
1153 unsigned
1154 MachineOutliner::buildCandidateList(std::vector &CandidateList,
1155 std::vector &FunctionList,
1156 SuffixTree &ST,
1157 const TargetInstrInfo &TII) {
1158
1159 std::vector CandidateSequence; // Current outlining candidate.
1160 unsigned MaxCandidateLen = 0; // Length of the longest candidate.
1161
1162 // Function for maximizing query in the suffix tree.
1163 // This allows us to define more fine-grained types of things to outline in
1164 // the target without putting target-specific info in the suffix tree.
1165 auto BenefitFn = [&TII](const SuffixTreeNode &Curr, size_t StringLen) {
1166
1167 // Any leaf whose parent is the root only has one occurrence.
1168 if (Curr.Parent->isRoot())
1169 return 0u;
1170
1171 // Anything with length < 2 will never be beneficial on any target.
1172 if (StringLen < 2)
1173 return 0u;
1174
1175 size_t Occurrences = Curr.Parent->OccurrenceCount;
1176
1177 // Anything with fewer than 2 occurrences will never be beneficial on any
1178 // target.
1179 if (Occurrences < 2)
1180 return 0u;
1181
1182 return TII.getOutliningBenefit(StringLen, Occurrences);
1183 };
1184
1185 // Repeatedly query the suffix tree for the substring that maximizes
1186 // BenefitFn. Find the occurrences of that string, prune the tree, and store
1187 // each occurrence as a candidate.
1188 for (ST.bestRepeatedSubstring(CandidateSequence, BenefitFn);
1189 CandidateSequence.size() > 1;
1190 ST.bestRepeatedSubstring(CandidateSequence, BenefitFn)) {
1191
1192 std::vector Occurrences;
1193
1194 bool GotNonOverlappingCandidate =
1195 ST.findOccurrencesAndPrune(CandidateSequence, Occurrences);
1196
1197 // Is the candidate we found known to overlap with something we already
1198 // outlined?
1199 if (!GotNonOverlappingCandidate)
1200 continue;
1201
1202 // Is this candidate the longest so far?
1203 if (CandidateSequence.size() > MaxCandidateLen)
1204 MaxCandidateLen = CandidateSequence.size();
1205
1206 // Keep track of the benefit of outlining this candidate in its
1207 // OutlinedFunction.
1208 unsigned FnBenefit = TII.getOutliningBenefit(CandidateSequence.size(),
1209 Occurrences.size()
1210 );
1211
1212 assert(FnBenefit > 0 && "Function cannot be unbeneficial!");
1213
1214 // Save an OutlinedFunction for this candidate.
1215 FunctionList.emplace_back(
1216 FunctionList.size(), // Number of this function.
1217 Occurrences.size(), // Number of occurrences.
1218 CandidateSequence, // Sequence to outline.
1219 FnBenefit // Instructions saved by outlining this function.
1220 );
1221
1222 // Save each of the occurrences of the candidate so we can outline them.
1223 for (size_t &Occ : Occurrences)
1224 CandidateList.emplace_back(
1225 Occ, // Starting idx in that MBB.
1226 CandidateSequence.size(), // Candidate length.
1227 FunctionList.size() - 1 // Idx of the corresponding function.
1228 );
1229
1230 FunctionsCreated++;
1231 }
1232
1233 // Sort the candidates in decending order. This will simplify the outlining
1234 // process when we have to remove the candidates from the mapping by
1235 // allowing us to cut them out without keeping track of an offset.
1236 std::stable_sort(CandidateList.begin(), CandidateList.end());
1237
1238 return MaxCandidateLen;
1239 }
1240
1241 MachineFunction *
1242 MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
1243 InstructionMapper &Mapper) {
1244
1245 // Create the function name. This should be unique. For now, just hash the
1246 // module name and include it in the function name plus the number of this
1247 // function.
1248 std::ostringstream NameStream;
1249 NameStream << "OUTLINED_FUNCTION" << "_" << OF.Name;
1250
1251 // Create the function using an IR-level function.
1252 LLVMContext &C = M.getContext();
1253 Function *F = dyn_cast(
1254 M.getOrInsertFunction(NameStream.str(), Type::getVoidTy(C), NULL));
1255 assert(F && "Function was null!");
1256
1257 // NOTE: If this is linkonceodr, then we can take advantage of linker deduping
1258 // which gives us better results when we outline from linkonceodr functions.
1259 F->setLinkage(GlobalValue::PrivateLinkage);
1260 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
1261
1262 BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
1263 IRBuilder<> Builder(EntryBB);
1264 Builder.CreateRetVoid();
1265
1266 MachineModuleInfo &MMI = getAnalysis();
1267 MachineFunction &MF = MMI.getMachineFunction(*F);
1268 MachineBasicBlock &MBB = *MF.CreateMachineBasicBlock();
1269 const TargetSubtargetInfo &STI = MF.getSubtarget();
1270 const TargetInstrInfo &TII = *STI.getInstrInfo();
1271
1272 // Insert the new function into the module.
1273 MF.insert(MF.begin(), &MBB);
1274
1275 TII.insertOutlinerPrologue(MBB, MF);
1276
1277 // Copy over the instructions for the function using the integer mappings in
1278 // its sequence.
1279 for (unsigned Str : OF.Sequence) {
1280 MachineInstr *NewMI =
1281 MF.CloneMachineInstr(Mapper.IntegerInstructionMap.find(Str)->second);
1282 NewMI->dropMemRefs();
1283
1284 // Don't keep debug information for outlined instructions.
1285 // FIXME: This means outlined functions are currently undebuggable.
1286 NewMI->setDebugLoc(DebugLoc());
1287 MBB.insert(MBB.end(), NewMI);
1288 }
1289
1290 TII.insertOutlinerEpilogue(MBB, MF);
1291
1292 return &MF;
1293 }
1294
1295 bool MachineOutliner::outline(Module &M,
1296 const ArrayRef &CandidateList,
1297 std::vector &FunctionList,
1298 InstructionMapper &Mapper) {
1299
1300 bool OutlinedSomething = false;
1301
1302 // Replace the candidates with calls to their respective outlined functions.
1303 for (const Candidate &C : CandidateList) {
1304
1305 // Was the candidate removed during pruneOverlaps?
1306 if (!C.InCandidateList)
1307 continue;
1308
1309 // If not, then look at its OutlinedFunction.
1310 OutlinedFunction &OF = FunctionList[C.FunctionIdx];
1311
1312 // Was its OutlinedFunction made unbeneficial during pruneOverlaps?
1313 if (OF.OccurrenceCount < 2 || OF.Benefit < 1)
1314 continue;
1315
1316 // If not, then outline it.
1317 assert(C.StartIdx < Mapper.InstrList.size() && "Candidate out of bounds!");
1318 MachineBasicBlock *MBB = (*Mapper.InstrList[C.StartIdx]).getParent();
1319 MachineBasicBlock::iterator StartIt = Mapper.InstrList[C.StartIdx];
1320 unsigned EndIdx = C.StartIdx + C.Len - 1;
1321
1322 assert(EndIdx < Mapper.InstrList.size() && "Candidate out of bounds!");
1323 MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
1324 assert(EndIt != MBB->end() && "EndIt out of bounds!");
1325
1326 EndIt++; // Erase needs one past the end index.
1327
1328 // Does this candidate have a function yet?
1329 if (!OF.MF)
1330 OF.MF = createOutlinedFunction(M, OF, Mapper);
1331
1332 MachineFunction *MF = OF.MF;
1333 const TargetSubtargetInfo &STI = MF->getSubtarget();
1334 const TargetInstrInfo &TII = *STI.getInstrInfo();
1335
1336 // Insert a call to the new function and erase the old sequence.
1337 TII.insertOutlinedCall(M, *MBB, StartIt, *MF);
1338 StartIt = Mapper.InstrList[C.StartIdx];
1339 MBB->erase(StartIt, EndIt);
1340
1341 OutlinedSomething = true;
1342
1343 // Statistics.
1344 NumOutlined++;
1345 }
1346
1347 DEBUG (
1348 dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n";
1349 );
1350
1351 return OutlinedSomething;
1352 }
1353
1354 bool MachineOutliner::runOnModule(Module &M) {
1355
1356 // Is there anything in the module at all?
1357 if (M.empty())
1358 return false;
1359
1360 MachineModuleInfo &MMI = getAnalysis();
1361 const TargetSubtargetInfo &STI = MMI.getMachineFunction(*M.begin())
1362 .getSubtarget();
1363 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
1364 const TargetInstrInfo *TII = STI.getInstrInfo();
1365
1366 InstructionMapper Mapper;
1367
1368 // Build instruction mappings for each function in the module.
1369 for (Function &F : M) {
1370 MachineFunction &MF = MMI.getMachineFunction(F);
1371
1372 // Is the function empty? Safe to outline from?
1373 if (F.empty() || !TII->isFunctionSafeToOutlineFrom(MF))
1374 continue;
1375
1376 // If it is, look at each MachineBasicBlock in the function.
1377 for (MachineBasicBlock &MBB : MF) {
1378
1379 // Is there anything in MBB?
1380 if (MBB.empty())
1381 continue;
1382
1383 // If yes, map it.
1384 Mapper.convertToUnsignedVec(MBB, *TRI, *TII);
1385 }
1386 }
1387
1388 // Construct a suffix tree, use it to find candidates, and then outline them.
1389 SuffixTree ST(Mapper.UnsignedVec);
1390 std::vector CandidateList;
1391 std::vector FunctionList;
1392
1393 unsigned MaxCandidateLen =
1394 buildCandidateList(CandidateList, FunctionList, ST, *TII);
1395
1396 pruneOverlaps(CandidateList, FunctionList, MaxCandidateLen, *TII);
1397 return outline(M, CandidateList, FunctionList, Mapper);
1398 }
9191 cl::desc("Verify generated machine code"),
9292 cl::init(false),
9393 cl::ZeroOrMore);
94 static cl::opt EnableMachineOutliner("enable-machine-outliner",
95 cl::Hidden,
96 cl::desc("Enable machine outliner"));
9497
9598 static cl::opt
9699 PrintMachineInstrs("print-machineinstrs", cl::ValueOptional,
673676 addPass(&XRayInstrumentationID, false);
674677 addPass(&PatchableFunctionID, false);
675678
679 if (EnableMachineOutliner)
680 PM->add(createMachineOutlinerPass());
681
676682 AddingMachinePasses = false;
677683 }
678684
1038210382 char LDTLSCleanup::ID = 0;
1038310383 FunctionPass*
1038410384 llvm::createCleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); }
10385
10386 unsigned X86InstrInfo::getOutliningBenefit(size_t SequenceSize,
10387 size_t Occurrences) const {
10388 unsigned NotOutlinedSize = SequenceSize * Occurrences;
10389
10390 // Sequence appears once in outlined function (Sequence.size())
10391 // One return instruction (+1)
10392 // One call per occurrence (Occurrences)
10393 unsigned OutlinedSize = (SequenceSize + 1) + Occurrences;
10394
10395 // Return the number of instructions saved by outlining this sequence.
10396 return NotOutlinedSize > OutlinedSize ? NotOutlinedSize - OutlinedSize : 0;
10397 }
10398
10399 bool X86InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF) const {
10400 return MF.getFunction()->hasFnAttribute(Attribute::NoRedZone);
10401 }
10402
10403 X86GenInstrInfo::MachineOutlinerInstrType
10404 X86InstrInfo::getOutliningType(MachineInstr &MI) const {
10405
10406 // Don't outline returns or basic block terminators.
10407 if (MI.isReturn() || MI.isTerminator())
10408 return MachineOutlinerInstrType::Illegal;
10409
10410 // Don't outline anything that modifies or reads from the stack pointer.
10411 //
10412 // FIXME: There are instructions which are being manually built without
10413 // explicit uses/defs so we also have to check the MCInstrDesc. We should be
10414 // able to remove the extra checks once those are fixed up. For example,
10415 // sometimes we might get something like %RAX = POP64r 1. This won't be
10416 // caught by modifiesRegister or readsRegister even though the instruction
10417 // really ought to be formed so that modifiesRegister/readsRegister would
10418 // catch it.
10419 if (MI.modifiesRegister(X86::RSP, &RI) || MI.readsRegister(X86::RSP, &RI) ||
10420 MI.getDesc().hasImplicitUseOfPhysReg(X86::RSP) ||
10421 MI.getDesc().hasImplicitDefOfPhysReg(X86::RSP))
10422 return MachineOutlinerInstrType::Illegal;
10423
10424 if (MI.readsRegister(X86::RIP, &RI) ||
10425 MI.getDesc().hasImplicitUseOfPhysReg(X86::RIP) ||
10426 MI.getDesc().hasImplicitDefOfPhysReg(X86::RIP))
10427 return MachineOutlinerInstrType::Illegal;
10428
10429 if (MI.isPosition())
10430 return MachineOutlinerInstrType::Illegal;
10431
10432 for (const MachineOperand &MOP : MI.operands())
10433 if (MOP.isCPI() || MOP.isJTI() || MOP.isCFIIndex() || MOP.isFI() ||
10434 MOP.isTargetIndex())
10435 return MachineOutlinerInstrType::Illegal;
10436
10437 // Don't allow debug values to impact outlining type.
10438 if (MI.isDebugValue() || MI.isIndirectDebugValue())
10439 return MachineOutlinerInstrType::Invisible;
10440
10441 return MachineOutlinerInstrType::Legal;
10442 }
10443
10444 void X86InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB,
10445 MachineFunction &MF) const {
10446
10447 MachineInstr *retq = BuildMI(MF, DebugLoc(), get(X86::RETQ));
10448 MBB.insert(MBB.end(), retq);
10449 }
10450
10451 void X86InstrInfo::insertOutlinerPrologue(MachineBasicBlock &MBB,
10452 MachineFunction &MF) const {
10453 return;
10454 }
10455
10456 MachineBasicBlock::iterator
10457 X86InstrInfo::insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
10458 MachineBasicBlock::iterator &It,
10459 MachineFunction &MF) const {
10460 It = MBB.insert(It,
10461 BuildMI(MF, DebugLoc(), get(X86::CALL64pcrel32))
10462 .addGlobalAddress(M.getNamedValue(MF.getName())));
10463 return It;
10464 }
544544
545545 bool isTailCall(const MachineInstr &Inst) const override;
546546
547 unsigned getOutliningBenefit(size_t SequenceSize,
548 size_t Occurrences) const override;
549
550 bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override;
551
552 llvm::X86GenInstrInfo::MachineOutlinerInstrType
553 getOutliningType(MachineInstr &MI) const override;
554
555 void insertOutlinerEpilogue(MachineBasicBlock &MBB,
556 MachineFunction &MF) const override;
557
558 void insertOutlinerPrologue(MachineBasicBlock &MBB,
559 MachineFunction &MF) const override;
560
561 MachineBasicBlock::iterator
562 insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
563 MachineBasicBlock::iterator &It,
564 MachineFunction &MF) const override;
565
547566 protected:
548567 /// Commutes the operands in the given instruction by changing the operands
549568 /// order and/or changing the instruction's opcode and/or the immediate value
0 ; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
1
2 @x = global i32 0, align 4, !dbg !0
3
4 define i32 @main() #0 !dbg !11 {
5 ; CHECK-LABEL: _main:
6 %1 = alloca i32, align 4
7 %2 = alloca i32, align 4
8 %3 = alloca i32, align 4
9 %4 = alloca i32, align 4
10 %5 = alloca i32, align 4
11 ; There is a debug value in the middle of this section, make sure debug values are ignored.
12 ; CHECK: callq l_OUTLINED_FUNCTION_0
13 store i32 1, i32* %2, align 4
14 store i32 2, i32* %3, align 4
15 store i32 3, i32* %4, align 4
16 call void @llvm.dbg.value(metadata i32 10, i64 0, metadata !15, metadata !16), !dbg !17
17 store i32 4, i32* %5, align 4
18 store i32 0, i32* @x, align 4, !dbg !24
19 ; This is the same sequence of instructions without a debug value. It should be outlined
20 ; in the same way.
21 ; CHECK: callq l_OUTLINED_FUNCTION_0
22 store i32 1, i32* %2, align 4
23 store i32 2, i32* %3, align 4
24 store i32 3, i32* %4, align 4
25 store i32 4, i32* %5, align 4
26 store i32 1, i32* @x, align 4, !dbg !14
27 ret i32 0, !dbg !25
28 }
29
30 ; CHECK-LABEL: l_OUTLINED_FUNCTION_0:
31 ; CHECK-NOT: .loc {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{^(is_stmt)}}
32 ; CHECK-NOT: ##DEBUG_VALUE: main:{{[a-z]}} <- {{[0-9]+}}
33 ; CHECK: movl $1, -{{[0-9]+}}(%rbp)
34 ; CHECK-NEXT: movl $2, -{{[0-9]+}}(%rbp)
35 ; CHECK-NEXT: movl $3, -{{[0-9]+}}(%rbp)
36 ; CHECK-NEXT: movl $4, -{{[0-9]+}}(%rbp)
37 ; CHECK-NEXT: retq
38
39 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
40
41 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
42
43 attributes #0 = { noredzone nounwind ssp uwtable "no-frame-pointer-elim"="true" }
44
45 !llvm.dbg.cu = !{!2}
46 !llvm.module.flags = !{!7, !8, !9}
47 !llvm.ident = !{!10}
48
49 !0 = !DIGlobalVariableExpression(var: !1)
50 !1 = distinct !DIGlobalVariable(name: "x", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true)
51 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 5.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
52 !3 = !DIFile(filename: "debug-test.c", directory: "dir")
53 !4 = !{}
54 !5 = !{!0}
55 !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
56 !7 = !{i32 2, !"Dwarf Version", i32 4}
57 !8 = !{i32 2, !"Debug Info Version", i32 3}
58 !9 = !{i32 1, !"PIC Level", i32 2}
59 !10 = !{!"clang version 5.0.0"}
60 !11 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 4, type: !12, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4)
61 !12 = !DISubroutineType(types: !13)
62 !13 = !{!6}
63 !14 = !DILocation(line: 7, column: 4, scope: !11)
64 !15 = !DILocalVariable(name: "a", scope: !11, file: !3, line: 5, type: !6)
65 !16 = !DIExpression()
66 !17 = !DILocation(line: 5, column: 6, scope: !11)
67 !18 = !DILocalVariable(name: "b", scope: !11, file: !3, line: 5, type: !6)
68 !19 = !DILocation(line: 5, column: 9, scope: !11)
69 !20 = !DILocalVariable(name: "c", scope: !11, file: !3, line: 5, type: !6)
70 !21 = !DILocation(line: 5, column: 12, scope: !11)
71 !22 = !DILocalVariable(name: "d", scope: !11, file: !3, line: 5, type: !6)
72 !23 = !DILocation(line: 5, column: 15, scope: !11)
73 !24 = !DILocation(line: 14, column: 4, scope: !11)
74 !25 = !DILocation(line: 21, column: 2, scope: !11)
0 ; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
1
2 @x = global i32 0, align 4
3
4 define i32 @check_boundaries() #0 {
5 ; CHECK-LABEL: _check_boundaries:
6 %1 = alloca i32, align 4
7 %2 = alloca i32, align 4
8 %3 = alloca i32, align 4
9 %4 = alloca i32, align 4
10 %5 = alloca i32, align 4
11 store i32 0, i32* %1, align 4
12 store i32 0, i32* %2, align 4
13 %6 = load i32, i32* %2, align 4
14 %7 = icmp ne i32 %6, 0
15 br i1 %7, label %9, label %8
16
17 ; CHECK: callq l_OUTLINED_FUNCTION_1
18 ; CHECK: cmpl $0, -{{[0-9]+}}(%rbp)
19 store i32 1, i32* %2, align 4
20 store i32 2, i32* %3, align 4
21 store i32 3, i32* %4, align 4
22 store i32 4, i32* %5, align 4
23 br label %10
24
25 store i32 1, i32* %4, align 4
26 br label %10
27
28 %11 = load i32, i32* %2, align 4
29 %12 = icmp ne i32 %11, 0
30 br i1 %12, label %14, label %13
31
32 ; CHECK: callq l_OUTLINED_FUNCTION_1
33 store i32 1, i32* %2, align 4
34 store i32 2, i32* %3, align 4
35 store i32 3, i32* %4, align 4
36 store i32 4, i32* %5, align 4
37 br label %15
38
39 store i32 1, i32* %4, align 4
40 br label %15
41
42 ret i32 0
43 }
44
45 define i32 @empty_1() #0 {
46 ; CHECK-LABEL: _empty_1:
47 ; CHECK-NOT: callq l_OUTLINED_FUNCTION_{{[0-9]+}}
48 ret i32 1
49 }
50
51 define i32 @empty_2() #0 {
52 ; CHECK-LABEL: _empty_2
53 ; CHECK-NOT: callq l_OUTLINED_FUNCTION_{{[0-9]+}}
54 ret i32 1
55 }
56
57 define i32 @no_empty_outlining() #0 {
58 ; CHECK-LABEL: _no_empty_outlining:
59 %1 = alloca i32, align 4
60 store i32 0, i32* %1, align 4
61 ; CHECK-NOT: callq l_OUTLINED_FUNCTION_{{[0-9]+}}
62 %2 = call i32 @empty_1() #1
63 %3 = call i32 @empty_2() #1
64 %4 = call i32 @empty_1() #1
65 %5 = call i32 @empty_2() #1
66 %6 = call i32 @empty_1() #1
67 %7 = call i32 @empty_2() #1
68 ret i32 0
69 }
70
71 define i32 @main() #0 {
72 ; CHECK-LABEL: _main:
73 %1 = alloca i32, align 4
74 %2 = alloca i32, align 4
75 %3 = alloca i32, align 4
76 %4 = alloca i32, align 4
77 %5 = alloca i32, align 4
78
79 store i32 0, i32* %1, align 4
80 store i32 0, i32* @x, align 4
81 ; CHECK: callq l_OUTLINED_FUNCTION_0
82 store i32 1, i32* %2, align 4
83 store i32 2, i32* %3, align 4
84 store i32 3, i32* %4, align 4
85 store i32 4, i32* %5, align 4
86 store i32 1, i32* @x, align 4
87 ; CHECK: callq l_OUTLINED_FUNCTION_0
88 store i32 1, i32* %2, align 4
89 store i32 2, i32* %3, align 4
90 store i32 3, i32* %4, align 4
91 store i32 4, i32* %5, align 4
92 ret i32 0
93 }
94
95 attributes #0 = { noredzone nounwind ssp uwtable "no-frame-pointer-elim"="true" }
96
97 ; CHECK-LABEL: l_OUTLINED_FUNCTION_0:
98 ; CHECK: movl $1, -{{[0-9]+}}(%rbp)
99 ; CHECK-NEXT: movl $2, -{{[0-9]+}}(%rbp)
100 ; CHECK-NEXT: movl $3, -{{[0-9]+}}(%rbp)
101 ; CHECK-NEXT: movl $4, -{{[0-9]+}}(%rbp)
102 ; CHECK-NEXT: retq
103
104 ; CHECK-LABEL: l_OUTLINED_FUNCTION_1:
105 ; CHECK: movl $1, -{{[0-9]+}}(%rbp)
106 ; CHECK-NEXT: movl $2, -{{[0-9]+}}(%rbp)
107 ; CHECK-NEXT: movl $3, -{{[0-9]+}}(%rbp)
108 ; CHECK-NEXT: movl $4, -{{[0-9]+}}(%rbp)
109 ; CHECK-NEXT: retq