LLVM 20.0.0git
MachineOutliner.cpp
Go to the documentation of this file.
1//===---- MachineOutliner.cpp - Outline instructions -----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// 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/// The MachineOutliner communicates with a given target using hooks defined in
18/// TargetInstrInfo.h. The target supplies the outliner with information on how
19/// a specific sequence of instructions should be outlined. This information
20/// is used to deduce the number of instructions necessary to
21///
22/// * Create an outlined function
23/// * Call that outlined function
24///
25/// Targets must implement
26/// * getOutliningCandidateInfo
27/// * buildOutlinedFrame
28/// * insertOutlinedCall
29/// * isFunctionSafeToOutlineFrom
30///
31/// in order to make use of the MachineOutliner.
32///
33/// This was originally presented at the 2016 LLVM Developers' Meeting in the
34/// talk "Reducing Code Size Using Outlining". For a high-level overview of
35/// how this pass works, the talk is available on YouTube at
36///
37/// https://www.youtube.com/watch?v=yorld-WSOeU
38///
39/// The slides for the talk are available at
40///
41/// http://www.llvm.org/devmtg/2016-11/Slides/Paquette-Outliner.pdf
42///
43/// The talk provides an overview of how the outliner finds candidates and
44/// ultimately outlines them. It describes how the main data structure for this
45/// pass, the suffix tree, is queried and purged for candidates. It also gives
46/// a simplified suffix tree construction algorithm for suffix trees based off
47/// of the algorithm actually used here, Ukkonen's algorithm.
48///
49/// For the original RFC for this pass, please see
50///
51/// http://lists.llvm.org/pipermail/llvm-dev/2016-August/104170.html
52///
53/// For more information on the suffix tree data structure, please see
54/// https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
55///
56//===----------------------------------------------------------------------===//
58#include "llvm/ADT/DenseMap.h"
59#include "llvm/ADT/SmallSet.h"
60#include "llvm/ADT/Statistic.h"
61#include "llvm/ADT/Twine.h"
66#include "llvm/CodeGen/Passes.h"
69#include "llvm/IR/DIBuilder.h"
70#include "llvm/IR/IRBuilder.h"
71#include "llvm/IR/Mangler.h"
72#include "llvm/IR/Module.h"
75#include "llvm/Support/Debug.h"
78#include <functional>
79#include <tuple>
80#include <vector>
81
82#define DEBUG_TYPE "machine-outliner"
83
84using namespace llvm;
85using namespace ore;
86using namespace outliner;
87
88// Statistics for outlined functions.
89STATISTIC(NumOutlined, "Number of candidates outlined");
90STATISTIC(FunctionsCreated, "Number of functions created");
91
92// Statistics for instruction mapping.
93STATISTIC(NumLegalInUnsignedVec, "Outlinable instructions mapped");
94STATISTIC(NumIllegalInUnsignedVec,
95 "Unoutlinable instructions mapped + number of sentinel values");
96STATISTIC(NumSentinels, "Sentinel values inserted during mapping");
97STATISTIC(NumInvisible,
98 "Invisible instructions skipped during mapping");
99STATISTIC(UnsignedVecSize,
100 "Total number of instructions mapped and saved to mapping vector");
101
102// Set to true if the user wants the outliner to run on linkonceodr linkage
103// functions. This is false by default because the linker can dedupe linkonceodr
104// functions. Since the outliner is confined to a single module (modulo LTO),
105// this is off by default. It should, however, be the default behaviour in
106// LTO.
108 "enable-linkonceodr-outlining", cl::Hidden,
109 cl::desc("Enable the machine outliner on linkonceodr functions"),
110 cl::init(false));
111
112/// Number of times to re-run the outliner. This is not the total number of runs
113/// as the outliner will run at least one time. The default value is set to 0,
114/// meaning the outliner will run one time and rerun zero times after that.
116 "machine-outliner-reruns", cl::init(0), cl::Hidden,
117 cl::desc(
118 "Number of times to rerun the outliner after the initial outline"));
119
121 "outliner-benefit-threshold", cl::init(1), cl::Hidden,
122 cl::desc(
123 "The minimum size in bytes before an outlining candidate is accepted"));
124
126 "outliner-leaf-descendants", cl::init(true), cl::Hidden,
127 cl::desc("Consider all leaf descendants of internal nodes of the suffix "
128 "tree as candidates for outlining (if false, only leaf children "
129 "are considered)"));
130
131namespace {
132
133/// Maps \p MachineInstrs to unsigned integers and stores the mappings.
134struct InstructionMapper {
135 const MachineModuleInfo &MMI;
136
137 /// The next available integer to assign to a \p MachineInstr that
138 /// cannot be outlined.
139 ///
140 /// Set to -3 for compatability with \p DenseMapInfo<unsigned>.
141 unsigned IllegalInstrNumber = -3;
142
143 /// The next available integer to assign to a \p MachineInstr that can
144 /// be outlined.
145 unsigned LegalInstrNumber = 0;
146
147 /// Correspondence from \p MachineInstrs to unsigned integers.
149 InstructionIntegerMap;
150
151 /// Correspondence between \p MachineBasicBlocks and target-defined flags.
153
154 /// The vector of unsigned integers that the module is mapped to.
155 SmallVector<unsigned> UnsignedVec;
156
157 /// Stores the location of the instruction associated with the integer
158 /// at index i in \p UnsignedVec for each index i.
160
161 // Set if we added an illegal number in the previous step.
162 // Since each illegal number is unique, we only need one of them between
163 // each range of legal numbers. This lets us make sure we don't add more
164 // than one illegal number per range.
165 bool AddedIllegalLastTime = false;
166
167 /// Maps \p *It to a legal integer.
168 ///
169 /// Updates \p CanOutlineWithPrevInstr, \p HaveLegalRange, \p InstrListForMBB,
170 /// \p UnsignedVecForMBB, \p InstructionIntegerMap, and \p LegalInstrNumber.
171 ///
172 /// \returns The integer that \p *It was mapped to.
173 unsigned mapToLegalUnsigned(
174 MachineBasicBlock::iterator &It, bool &CanOutlineWithPrevInstr,
175 bool &HaveLegalRange, unsigned &NumLegalInBlock,
176 SmallVector<unsigned> &UnsignedVecForMBB,
178 // We added something legal, so we should unset the AddedLegalLastTime
179 // flag.
180 AddedIllegalLastTime = false;
181
182 // If we have at least two adjacent legal instructions (which may have
183 // invisible instructions in between), remember that.
184 if (CanOutlineWithPrevInstr)
185 HaveLegalRange = true;
186 CanOutlineWithPrevInstr = true;
187
188 // Keep track of the number of legal instructions we insert.
189 NumLegalInBlock++;
190
191 // Get the integer for this instruction or give it the current
192 // LegalInstrNumber.
193 InstrListForMBB.push_back(It);
194 MachineInstr &MI = *It;
195 bool WasInserted;
197 ResultIt;
198 std::tie(ResultIt, WasInserted) =
199 InstructionIntegerMap.insert(std::make_pair(&MI, LegalInstrNumber));
200 unsigned MINumber = ResultIt->second;
201
202 // There was an insertion.
203 if (WasInserted)
204 LegalInstrNumber++;
205
206 UnsignedVecForMBB.push_back(MINumber);
207
208 // Make sure we don't overflow or use any integers reserved by the DenseMap.
209 if (LegalInstrNumber >= IllegalInstrNumber)
210 report_fatal_error("Instruction mapping overflow!");
211
212 assert(LegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
213 "Tried to assign DenseMap tombstone or empty key to instruction.");
214 assert(LegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
215 "Tried to assign DenseMap tombstone or empty key to instruction.");
216
217 // Statistics.
218 ++NumLegalInUnsignedVec;
219 return MINumber;
220 }
221
222 /// Maps \p *It to an illegal integer.
223 ///
224 /// Updates \p InstrListForMBB, \p UnsignedVecForMBB, and \p
225 /// IllegalInstrNumber.
226 ///
227 /// \returns The integer that \p *It was mapped to.
228 unsigned mapToIllegalUnsigned(
229 MachineBasicBlock::iterator &It, bool &CanOutlineWithPrevInstr,
230 SmallVector<unsigned> &UnsignedVecForMBB,
232 // Can't outline an illegal instruction. Set the flag.
233 CanOutlineWithPrevInstr = false;
234
235 // Only add one illegal number per range of legal numbers.
236 if (AddedIllegalLastTime)
237 return IllegalInstrNumber;
238
239 // Remember that we added an illegal number last time.
240 AddedIllegalLastTime = true;
241 unsigned MINumber = IllegalInstrNumber;
242
243 InstrListForMBB.push_back(It);
244 UnsignedVecForMBB.push_back(IllegalInstrNumber);
245 IllegalInstrNumber--;
246 // Statistics.
247 ++NumIllegalInUnsignedVec;
248
249 assert(LegalInstrNumber < IllegalInstrNumber &&
250 "Instruction mapping overflow!");
251
252 assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
253 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
254
255 assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
256 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
257
258 return MINumber;
259 }
260
261 /// Transforms a \p MachineBasicBlock into a \p vector of \p unsigneds
262 /// and appends it to \p UnsignedVec and \p InstrList.
263 ///
264 /// Two instructions are assigned the same integer if they are identical.
265 /// If an instruction is deemed unsafe to outline, then it will be assigned an
266 /// unique integer. The resulting mapping is placed into a suffix tree and
267 /// queried for candidates.
268 ///
269 /// \param MBB The \p MachineBasicBlock to be translated into integers.
270 /// \param TII \p TargetInstrInfo for the function.
271 void convertToUnsignedVec(MachineBasicBlock &MBB,
272 const TargetInstrInfo &TII) {
273 LLVM_DEBUG(dbgs() << "*** Converting MBB '" << MBB.getName()
274 << "' to unsigned vector ***\n");
275 unsigned Flags = 0;
276
277 // Don't even map in this case.
278 if (!TII.isMBBSafeToOutlineFrom(MBB, Flags))
279 return;
280
281 auto OutlinableRanges = TII.getOutlinableRanges(MBB, Flags);
282 LLVM_DEBUG(dbgs() << MBB.getName() << ": " << OutlinableRanges.size()
283 << " outlinable range(s)\n");
284 if (OutlinableRanges.empty())
285 return;
286
287 // Store info for the MBB for later outlining.
288 MBBFlagsMap[&MBB] = Flags;
289
291
292 // The number of instructions in this block that will be considered for
293 // outlining.
294 unsigned NumLegalInBlock = 0;
295
296 // True if we have at least two legal instructions which aren't separated
297 // by an illegal instruction.
298 bool HaveLegalRange = false;
299
300 // True if we can perform outlining given the last mapped (non-invisible)
301 // instruction. This lets us know if we have a legal range.
302 bool CanOutlineWithPrevInstr = false;
303
304 // FIXME: Should this all just be handled in the target, rather than using
305 // repeated calls to getOutliningType?
306 SmallVector<unsigned> UnsignedVecForMBB;
308
309 LLVM_DEBUG(dbgs() << "*** Mapping outlinable ranges ***\n");
310 for (auto &OutlinableRange : OutlinableRanges) {
311 auto OutlinableRangeBegin = OutlinableRange.first;
312 auto OutlinableRangeEnd = OutlinableRange.second;
313#ifndef NDEBUG
315 dbgs() << "Mapping "
316 << std::distance(OutlinableRangeBegin, OutlinableRangeEnd)
317 << " instruction range\n");
318 // Everything outside of an outlinable range is illegal.
319 unsigned NumSkippedInRange = 0;
320#endif
321 for (; It != OutlinableRangeBegin; ++It) {
322#ifndef NDEBUG
323 ++NumSkippedInRange;
324#endif
325 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
326 InstrListForMBB);
327 }
328#ifndef NDEBUG
329 LLVM_DEBUG(dbgs() << "Skipped " << NumSkippedInRange
330 << " instructions outside outlinable range\n");
331#endif
332 assert(It != MBB.end() && "Should still have instructions?");
333 // `It` is now positioned at the beginning of a range of instructions
334 // which may be outlinable. Check if each instruction is known to be safe.
335 for (; It != OutlinableRangeEnd; ++It) {
336 // Keep track of where this instruction is in the module.
337 switch (TII.getOutliningType(MMI, It, Flags)) {
338 case InstrType::Illegal:
339 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
340 InstrListForMBB);
341 break;
342
343 case InstrType::Legal:
344 mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
345 NumLegalInBlock, UnsignedVecForMBB,
346 InstrListForMBB);
347 break;
348
349 case InstrType::LegalTerminator:
350 mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
351 NumLegalInBlock, UnsignedVecForMBB,
352 InstrListForMBB);
353 // The instruction also acts as a terminator, so we have to record
354 // that in the string.
355 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
356 InstrListForMBB);
357 break;
358
359 case InstrType::Invisible:
360 // Normally this is set by mapTo(Blah)Unsigned, but we just want to
361 // skip this instruction. So, unset the flag here.
362 ++NumInvisible;
363 AddedIllegalLastTime = false;
364 break;
365 }
366 }
367 }
368
369 LLVM_DEBUG(dbgs() << "HaveLegalRange = " << HaveLegalRange << "\n");
370
371 // Are there enough legal instructions in the block for outlining to be
372 // possible?
373 if (HaveLegalRange) {
374 // After we're done every insertion, uniquely terminate this part of the
375 // "string". This makes sure we won't match across basic block or function
376 // boundaries since the "end" is encoded uniquely and thus appears in no
377 // repeated substring.
378 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
379 InstrListForMBB);
380 ++NumSentinels;
381 append_range(InstrList, InstrListForMBB);
382 append_range(UnsignedVec, UnsignedVecForMBB);
383 }
384 }
385
386 InstructionMapper(const MachineModuleInfo &MMI_) : MMI(MMI_) {
387 // Make sure that the implementation of DenseMapInfo<unsigned> hasn't
388 // changed.
390 "DenseMapInfo<unsigned>'s empty key isn't -1!");
392 "DenseMapInfo<unsigned>'s tombstone key isn't -2!");
393 }
394};
395
396/// An interprocedural pass which finds repeated sequences of
397/// instructions and replaces them with calls to functions.
398///
399/// Each instruction is mapped to an unsigned integer and placed in a string.
400/// The resulting mapping is then placed in a \p SuffixTree. The \p SuffixTree
401/// is then repeatedly queried for repeated sequences of instructions. Each
402/// non-overlapping repeated sequence is then placed in its own
403/// \p MachineFunction and each instance is then replaced with a call to that
404/// function.
405struct MachineOutliner : public ModulePass {
406
407 static char ID;
408
409 MachineModuleInfo *MMI = nullptr;
410
411 /// Set to true if the outliner should consider functions with
412 /// linkonceodr linkage.
413 bool OutlineFromLinkOnceODRs = false;
414
415 /// The current repeat number of machine outlining.
416 unsigned OutlineRepeatedNum = 0;
417
418 /// Set to true if the outliner should run on all functions in the module
419 /// considered safe for outlining.
420 /// Set to true by default for compatibility with llc's -run-pass option.
421 /// Set when the pass is constructed in TargetPassConfig.
422 bool RunOnAllFunctions = true;
423
424 StringRef getPassName() const override { return "Machine Outliner"; }
425
426 void getAnalysisUsage(AnalysisUsage &AU) const override {
429 AU.setPreservesAll();
431 }
432
433 MachineOutliner() : ModulePass(ID) {
435 }
436
437 /// Remark output explaining that not outlining a set of candidates would be
438 /// better than outlining that set.
439 void emitNotOutliningCheaperRemark(
440 unsigned StringLen, std::vector<Candidate> &CandidatesForRepeatedSeq,
441 OutlinedFunction &OF);
442
443 /// Remark output explaining that a function was outlined.
444 void emitOutlinedFunctionRemark(OutlinedFunction &OF);
445
446 /// Find all repeated substrings that satisfy the outlining cost model by
447 /// constructing a suffix tree.
448 ///
449 /// If a substring appears at least twice, then it must be represented by
450 /// an internal node which appears in at least two suffixes. Each suffix
451 /// is represented by a leaf node. To do this, we visit each internal node
452 /// in the tree, using the leaf children of each internal node. If an
453 /// internal node represents a beneficial substring, then we use each of
454 /// its leaf children to find the locations of its substring.
455 ///
456 /// \param Mapper Contains outlining mapping information.
457 /// \param[out] FunctionList Filled with a list of \p OutlinedFunctions
458 /// each type of candidate.
459 void findCandidates(InstructionMapper &Mapper,
460 std::vector<OutlinedFunction> &FunctionList);
461
462 /// Replace the sequences of instructions represented by \p OutlinedFunctions
463 /// with calls to functions.
464 ///
465 /// \param M The module we are outlining from.
466 /// \param FunctionList A list of functions to be inserted into the module.
467 /// \param Mapper Contains the instruction mappings for the module.
468 bool outline(Module &M, std::vector<OutlinedFunction> &FunctionList,
469 InstructionMapper &Mapper, unsigned &OutlinedFunctionNum);
470
471 /// Creates a function for \p OF and inserts it into the module.
473 InstructionMapper &Mapper,
474 unsigned Name);
475
476 /// Calls 'doOutline()' 1 + OutlinerReruns times.
477 bool runOnModule(Module &M) override;
478
479 /// Construct a suffix tree on the instructions in \p M and outline repeated
480 /// strings from that tree.
481 bool doOutline(Module &M, unsigned &OutlinedFunctionNum);
482
483 /// Return a DISubprogram for OF if one exists, and null otherwise. Helper
484 /// function for remark emission.
486 for (const Candidate &C : OF.Candidates)
487 if (MachineFunction *MF = C.getMF())
488 if (DISubprogram *SP = MF->getFunction().getSubprogram())
489 return SP;
490 return nullptr;
491 }
492
493 /// Populate and \p InstructionMapper with instruction-to-integer mappings.
494 /// These are used to construct a suffix tree.
495 void populateMapper(InstructionMapper &Mapper, Module &M);
496
497 /// Initialize information necessary to output a size remark.
498 /// FIXME: This should be handled by the pass manager, not the outliner.
499 /// FIXME: This is nearly identical to the initSizeRemarkInfo in the legacy
500 /// pass manager.
501 void initSizeRemarkInfo(const Module &M,
502 StringMap<unsigned> &FunctionToInstrCount);
503
504 /// Emit the remark.
505 // FIXME: This should be handled by the pass manager, not the outliner.
506 void
507 emitInstrCountChangedRemark(const Module &M,
508 const StringMap<unsigned> &FunctionToInstrCount);
509};
510} // Anonymous namespace.
511
512char MachineOutliner::ID = 0;
513
514namespace llvm {
515ModulePass *createMachineOutlinerPass(bool RunOnAllFunctions) {
516 MachineOutliner *OL = new MachineOutliner();
517 OL->RunOnAllFunctions = RunOnAllFunctions;
518 return OL;
519}
520
521} // namespace llvm
522
523INITIALIZE_PASS(MachineOutliner, DEBUG_TYPE, "Machine Function Outliner", false,
524 false)
525
526void MachineOutliner::emitNotOutliningCheaperRemark(
527 unsigned StringLen, std::vector<Candidate> &CandidatesForRepeatedSeq,
528 OutlinedFunction &OF) {
529 // FIXME: Right now, we arbitrarily choose some Candidate from the
530 // OutlinedFunction. This isn't necessarily fixed, nor does it have to be.
531 // We should probably sort these by function name or something to make sure
532 // the remarks are stable.
533 Candidate &C = CandidatesForRepeatedSeq.front();
534 MachineOptimizationRemarkEmitter MORE(*(C.getMF()), nullptr);
535 MORE.emit([&]() {
536 MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper",
537 C.front().getDebugLoc(), C.getMBB());
538 R << "Did not outline " << NV("Length", StringLen) << " instructions"
539 << " from " << NV("NumOccurrences", CandidatesForRepeatedSeq.size())
540 << " locations."
541 << " Bytes from outlining all occurrences ("
542 << NV("OutliningCost", OF.getOutliningCost()) << ")"
543 << " >= Unoutlined instruction bytes ("
544 << NV("NotOutliningCost", OF.getNotOutlinedCost()) << ")"
545 << " (Also found at: ";
546
547 // Tell the user the other places the candidate was found.
548 for (unsigned i = 1, e = CandidatesForRepeatedSeq.size(); i < e; i++) {
549 R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
550 CandidatesForRepeatedSeq[i].front().getDebugLoc());
551 if (i != e - 1)
552 R << ", ";
553 }
554
555 R << ")";
556 return R;
557 });
558}
559
560void MachineOutliner::emitOutlinedFunctionRemark(OutlinedFunction &OF) {
561 MachineBasicBlock *MBB = &*OF.MF->begin();
563 MachineOptimizationRemark R(DEBUG_TYPE, "OutlinedFunction",
565 R << "Saved " << NV("OutliningBenefit", OF.getBenefit()) << " bytes by "
566 << "outlining " << NV("Length", OF.getNumInstrs()) << " instructions "
567 << "from " << NV("NumOccurrences", OF.getOccurrenceCount())
568 << " locations. "
569 << "(Found at: ";
570
571 // Tell the user the other places the candidate was found.
572 for (size_t i = 0, e = OF.Candidates.size(); i < e; i++) {
573
574 R << NV((Twine("StartLoc") + Twine(i)).str(),
575 OF.Candidates[i].front().getDebugLoc());
576 if (i != e - 1)
577 R << ", ";
578 }
579
580 R << ")";
581
582 MORE.emit(R);
583}
584
585void MachineOutliner::findCandidates(
586 InstructionMapper &Mapper, std::vector<OutlinedFunction> &FunctionList) {
587 FunctionList.clear();
588 SuffixTree ST(Mapper.UnsignedVec, OutlinerLeafDescendants);
589
590 // First, find all of the repeated substrings in the tree of minimum length
591 // 2.
592 std::vector<Candidate> CandidatesForRepeatedSeq;
593 LLVM_DEBUG(dbgs() << "*** Discarding overlapping candidates *** \n");
595 dbgs() << "Searching for overlaps in all repeated sequences...\n");
596 for (SuffixTree::RepeatedSubstring &RS : ST) {
597 CandidatesForRepeatedSeq.clear();
598 unsigned StringLen = RS.Length;
599 LLVM_DEBUG(dbgs() << " Sequence length: " << StringLen << "\n");
600 // Debug code to keep track of how many candidates we removed.
601#ifndef NDEBUG
602 unsigned NumDiscarded = 0;
603 unsigned NumKept = 0;
604#endif
605 // Sort the start indices so that we can efficiently check if candidates
606 // overlap with the ones we've already found for this sequence.
607 llvm::sort(RS.StartIndices);
608 for (const unsigned &StartIdx : RS.StartIndices) {
609 // Trick: Discard some candidates that would be incompatible with the
610 // ones we've already found for this sequence. This will save us some
611 // work in candidate selection.
612 //
613 // If two candidates overlap, then we can't outline them both. This
614 // happens when we have candidates that look like, say
615 //
616 // AA (where each "A" is an instruction).
617 //
618 // We might have some portion of the module that looks like this:
619 // AAAAAA (6 A's)
620 //
621 // In this case, there are 5 different copies of "AA" in this range, but
622 // at most 3 can be outlined. If only outlining 3 of these is going to
623 // be unbeneficial, then we ought to not bother.
624 //
625 // Note that two things DON'T overlap when they look like this:
626 // start1...end1 .... start2...end2
627 // That is, one must either
628 // * End before the other starts
629 // * Start after the other ends
630 unsigned EndIdx = StartIdx + StringLen - 1;
631 if (!CandidatesForRepeatedSeq.empty() &&
632 StartIdx <= CandidatesForRepeatedSeq.back().getEndIdx()) {
633#ifndef NDEBUG
634 ++NumDiscarded;
635 LLVM_DEBUG(dbgs() << " .. DISCARD candidate @ [" << StartIdx << ", "
636 << EndIdx << "]; overlaps with candidate @ ["
637 << CandidatesForRepeatedSeq.back().getStartIdx()
638 << ", " << CandidatesForRepeatedSeq.back().getEndIdx()
639 << "]\n");
640#endif
641 continue;
642 }
643 // It doesn't overlap with anything, so we can outline it.
644 // Each sequence is over [StartIt, EndIt].
645 // Save the candidate and its location.
646#ifndef NDEBUG
647 ++NumKept;
648#endif
649 MachineBasicBlock::iterator StartIt = Mapper.InstrList[StartIdx];
650 MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
651 MachineBasicBlock *MBB = StartIt->getParent();
652 CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen, StartIt, EndIt,
653 MBB, FunctionList.size(),
654 Mapper.MBBFlagsMap[MBB]);
655 }
656#ifndef NDEBUG
657 LLVM_DEBUG(dbgs() << " Candidates discarded: " << NumDiscarded
658 << "\n");
659 LLVM_DEBUG(dbgs() << " Candidates kept: " << NumKept << "\n\n");
660#endif
661
662 // We've found something we might want to outline.
663 // Create an OutlinedFunction to store it and check if it'd be beneficial
664 // to outline.
665 if (CandidatesForRepeatedSeq.size() < 2)
666 continue;
667
668 // Arbitrarily choose a TII from the first candidate.
669 // FIXME: Should getOutliningCandidateInfo move to TargetMachine?
670 const TargetInstrInfo *TII =
671 CandidatesForRepeatedSeq[0].getMF()->getSubtarget().getInstrInfo();
672
673 std::optional<OutlinedFunction> OF =
674 TII->getOutliningCandidateInfo(*MMI, CandidatesForRepeatedSeq);
675
676 // If we deleted too many candidates, then there's nothing worth outlining.
677 // FIXME: This should take target-specified instruction sizes into account.
678 if (!OF || OF->Candidates.size() < 2)
679 continue;
680
681 // Is it better to outline this candidate than not?
682 if (OF->getBenefit() < OutlinerBenefitThreshold) {
683 emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq, *OF);
684 continue;
685 }
686
687 FunctionList.push_back(*OF);
688 }
689}
690
691MachineFunction *MachineOutliner::createOutlinedFunction(
692 Module &M, OutlinedFunction &OF, InstructionMapper &Mapper, unsigned Name) {
693
694 // Create the function name. This should be unique.
695 // FIXME: We should have a better naming scheme. This should be stable,
696 // regardless of changes to the outliner's cost model/traversal order.
697 std::string FunctionName = "OUTLINED_FUNCTION_";
698 if (OutlineRepeatedNum > 0)
699 FunctionName += std::to_string(OutlineRepeatedNum + 1) + "_";
700 FunctionName += std::to_string(Name);
701 LLVM_DEBUG(dbgs() << "NEW FUNCTION: " << FunctionName << "\n");
702
703 // Create the function using an IR-level function.
704 LLVMContext &C = M.getContext();
705 Function *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
706 Function::ExternalLinkage, FunctionName, M);
707
708 // NOTE: If this is linkonceodr, then we can take advantage of linker deduping
709 // which gives us better results when we outline from linkonceodr functions.
710 F->setLinkage(GlobalValue::InternalLinkage);
711 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
712
713 // Set optsize/minsize, so we don't insert padding between outlined
714 // functions.
715 F->addFnAttr(Attribute::OptimizeForSize);
716 F->addFnAttr(Attribute::MinSize);
717
718 Candidate &FirstCand = OF.Candidates.front();
719 const TargetInstrInfo &TII =
720 *FirstCand.getMF()->getSubtarget().getInstrInfo();
721
722 TII.mergeOutliningCandidateAttributes(*F, OF.Candidates);
723
724 // Set uwtable, so we generate eh_frame.
725 UWTableKind UW = std::accumulate(
726 OF.Candidates.cbegin(), OF.Candidates.cend(), UWTableKind::None,
727 [](UWTableKind K, const outliner::Candidate &C) {
728 return std::max(K, C.getMF()->getFunction().getUWTableKind());
729 });
730 F->setUWTableKind(UW);
731
732 BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
733 IRBuilder<> Builder(EntryBB);
734 Builder.CreateRetVoid();
735
736 MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
738 MF.setIsOutlined(true);
740
741 // Insert the new function into the module.
742 MF.insert(MF.begin(), &MBB);
743
744 MachineFunction *OriginalMF = FirstCand.front().getMF();
745 const std::vector<MCCFIInstruction> &Instrs =
746 OriginalMF->getFrameInstructions();
747 for (auto &MI : FirstCand) {
748 if (MI.isDebugInstr())
749 continue;
750
751 // Don't keep debug information for outlined instructions.
752 auto DL = DebugLoc();
753 if (MI.isCFIInstruction()) {
754 unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
755 MCCFIInstruction CFI = Instrs[CFIIndex];
756 BuildMI(MBB, MBB.end(), DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
757 .addCFIIndex(MF.addFrameInst(CFI));
758 } else {
759 MachineInstr *NewMI = MF.CloneMachineInstr(&MI);
760 NewMI->dropMemRefs(MF);
761 NewMI->setDebugLoc(DL);
762 MBB.insert(MBB.end(), NewMI);
763 }
764 }
765
766 // Set normal properties for a late MachineFunction.
767 MF.getProperties().reset(MachineFunctionProperties::Property::IsSSA);
768 MF.getProperties().set(MachineFunctionProperties::Property::NoPHIs);
769 MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
770 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness);
772
773 // Compute live-in set for outlined fn
774 const MachineRegisterInfo &MRI = MF.getRegInfo();
775 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
776 LivePhysRegs LiveIns(TRI);
777 for (auto &Cand : OF.Candidates) {
778 // Figure out live-ins at the first instruction.
779 MachineBasicBlock &OutlineBB = *Cand.front().getParent();
780 LivePhysRegs CandLiveIns(TRI);
781 CandLiveIns.addLiveOuts(OutlineBB);
782 for (const MachineInstr &MI :
783 reverse(make_range(Cand.begin(), OutlineBB.end())))
784 CandLiveIns.stepBackward(MI);
785
786 // The live-in set for the outlined function is the union of the live-ins
787 // from all the outlining points.
788 for (MCPhysReg Reg : CandLiveIns)
789 LiveIns.addReg(Reg);
790 }
791 addLiveIns(MBB, LiveIns);
792
793 TII.buildOutlinedFrame(MBB, MF, OF);
794
795 // If there's a DISubprogram associated with this outlined function, then
796 // emit debug info for the outlined function.
797 if (DISubprogram *SP = getSubprogramOrNull(OF)) {
798 // We have a DISubprogram. Get its DICompileUnit.
799 DICompileUnit *CU = SP->getUnit();
800 DIBuilder DB(M, true, CU);
801 DIFile *Unit = SP->getFile();
802 Mangler Mg;
803 // Get the mangled name of the function for the linkage name.
804 std::string Dummy;
805 raw_string_ostream MangledNameStream(Dummy);
806 Mg.getNameWithPrefix(MangledNameStream, F, false);
807
808 DISubprogram *OutlinedSP = DB.createFunction(
809 Unit /* Context */, F->getName(), StringRef(Dummy), Unit /* File */,
810 0 /* Line 0 is reserved for compiler-generated code. */,
811 DB.createSubroutineType(
812 DB.getOrCreateTypeArray(std::nullopt)), /* void type */
813 0, /* Line 0 is reserved for compiler-generated code. */
814 DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
815 /* Outlined code is optimized code by definition. */
816 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
817
818 // Don't add any new variables to the subprogram.
819 DB.finalizeSubprogram(OutlinedSP);
820
821 // Attach subprogram to the function.
822 F->setSubprogram(OutlinedSP);
823 // We're done with the DIBuilder.
824 DB.finalize();
825 }
826
827 return &MF;
828}
829
830bool MachineOutliner::outline(Module &M,
831 std::vector<OutlinedFunction> &FunctionList,
832 InstructionMapper &Mapper,
833 unsigned &OutlinedFunctionNum) {
834 LLVM_DEBUG(dbgs() << "*** Outlining ***\n");
835 LLVM_DEBUG(dbgs() << "NUMBER OF POTENTIAL FUNCTIONS: " << FunctionList.size()
836 << "\n");
837 bool OutlinedSomething = false;
838
839 // Sort by priority where priority := getNotOutlinedCost / getOutliningCost.
840 // The function with highest priority should be outlined first.
841 stable_sort(FunctionList,
842 [](const OutlinedFunction &LHS, const OutlinedFunction &RHS) {
843 return LHS.getNotOutlinedCost() * RHS.getOutliningCost() >
844 RHS.getNotOutlinedCost() * LHS.getOutliningCost();
845 });
846
847 // Walk over each function, outlining them as we go along. Functions are
848 // outlined greedily, based off the sort above.
849 auto *UnsignedVecBegin = Mapper.UnsignedVec.begin();
850 LLVM_DEBUG(dbgs() << "WALKING FUNCTION LIST\n");
851 for (OutlinedFunction &OF : FunctionList) {
852#ifndef NDEBUG
853 auto NumCandidatesBefore = OF.Candidates.size();
854#endif
855 // If we outlined something that overlapped with a candidate in a previous
856 // step, then we can't outline from it.
857 erase_if(OF.Candidates, [&UnsignedVecBegin](Candidate &C) {
858 return std::any_of(UnsignedVecBegin + C.getStartIdx(),
859 UnsignedVecBegin + C.getEndIdx() + 1, [](unsigned I) {
860 return I == static_cast<unsigned>(-1);
861 });
862 });
863
864#ifndef NDEBUG
865 auto NumCandidatesAfter = OF.Candidates.size();
866 LLVM_DEBUG(dbgs() << "PRUNED: " << NumCandidatesBefore - NumCandidatesAfter
867 << "/" << NumCandidatesBefore << " candidates\n");
868#endif
869
870 // If we made it unbeneficial to outline this function, skip it.
872 LLVM_DEBUG(dbgs() << "SKIP: Expected benefit (" << OF.getBenefit()
873 << " B) < threshold (" << OutlinerBenefitThreshold
874 << " B)\n");
875 continue;
876 }
877
878 LLVM_DEBUG(dbgs() << "OUTLINE: Expected benefit (" << OF.getBenefit()
879 << " B) > threshold (" << OutlinerBenefitThreshold
880 << " B)\n");
881
882 // It's beneficial. Create the function and outline its sequence's
883 // occurrences.
884 OF.MF = createOutlinedFunction(M, OF, Mapper, OutlinedFunctionNum);
885 emitOutlinedFunctionRemark(OF);
886 FunctionsCreated++;
887 OutlinedFunctionNum++; // Created a function, move to the next name.
888 MachineFunction *MF = OF.MF;
889 const TargetSubtargetInfo &STI = MF->getSubtarget();
890 const TargetInstrInfo &TII = *STI.getInstrInfo();
891
892 // Replace occurrences of the sequence with calls to the new function.
893 LLVM_DEBUG(dbgs() << "CREATE OUTLINED CALLS\n");
894 for (Candidate &C : OF.Candidates) {
895 MachineBasicBlock &MBB = *C.getMBB();
896 MachineBasicBlock::iterator StartIt = C.begin();
897 MachineBasicBlock::iterator EndIt = std::prev(C.end());
898
899 // Insert the call.
900 auto CallInst = TII.insertOutlinedCall(M, MBB, StartIt, *MF, C);
901// Insert the call.
902#ifndef NDEBUG
903 auto MBBBeingOutlinedFromName =
904 MBB.getName().empty() ? "<unknown>" : MBB.getName().str();
905 auto MFBeingOutlinedFromName = MBB.getParent()->getName().empty()
906 ? "<unknown>"
907 : MBB.getParent()->getName().str();
908 LLVM_DEBUG(dbgs() << " CALL: " << MF->getName() << " in "
909 << MFBeingOutlinedFromName << ":"
910 << MBBBeingOutlinedFromName << "\n");
911 LLVM_DEBUG(dbgs() << " .. " << *CallInst);
912#endif
913
914 // If the caller tracks liveness, then we need to make sure that
915 // anything we outline doesn't break liveness assumptions. The outlined
916 // functions themselves currently don't track liveness, but we should
917 // make sure that the ranges we yank things out of aren't wrong.
919 MachineFunctionProperties::Property::TracksLiveness)) {
920 // The following code is to add implicit def operands to the call
921 // instruction. It also updates call site information for moved
922 // code.
923 SmallSet<Register, 2> UseRegs, DefRegs;
924 // Copy over the defs in the outlined range.
925 // First inst in outlined range <-- Anything that's defined in this
926 // ... .. range has to be added as an
927 // implicit Last inst in outlined range <-- def to the call
928 // instruction. Also remove call site information for outlined block
929 // of code. The exposed uses need to be copied in the outlined range.
931 Iter = EndIt.getReverse(),
932 Last = std::next(CallInst.getReverse());
933 Iter != Last; Iter++) {
934 MachineInstr *MI = &*Iter;
935 SmallSet<Register, 2> InstrUseRegs;
936 for (MachineOperand &MOP : MI->operands()) {
937 // Skip over anything that isn't a register.
938 if (!MOP.isReg())
939 continue;
940
941 if (MOP.isDef()) {
942 // Introduce DefRegs set to skip the redundant register.
943 DefRegs.insert(MOP.getReg());
944 if (UseRegs.count(MOP.getReg()) &&
945 !InstrUseRegs.count(MOP.getReg()))
946 // Since the regiester is modeled as defined,
947 // it is not necessary to be put in use register set.
948 UseRegs.erase(MOP.getReg());
949 } else if (!MOP.isUndef()) {
950 // Any register which is not undefined should
951 // be put in the use register set.
952 UseRegs.insert(MOP.getReg());
953 InstrUseRegs.insert(MOP.getReg());
954 }
955 }
956 if (MI->isCandidateForCallSiteEntry())
957 MI->getMF()->eraseCallSiteInfo(MI);
958 }
959
960 for (const Register &I : DefRegs)
961 // If it's a def, add it to the call instruction.
962 CallInst->addOperand(
963 MachineOperand::CreateReg(I, true, /* isDef = true */
964 true /* isImp = true */));
965
966 for (const Register &I : UseRegs)
967 // If it's a exposed use, add it to the call instruction.
968 CallInst->addOperand(
969 MachineOperand::CreateReg(I, false, /* isDef = false */
970 true /* isImp = true */));
971 }
972
973 // Erase from the point after where the call was inserted up to, and
974 // including, the final instruction in the sequence.
975 // Erase needs one past the end, so we need std::next there too.
976 MBB.erase(std::next(StartIt), std::next(EndIt));
977
978 // Keep track of what we removed by marking them all as -1.
979 for (unsigned &I : make_range(UnsignedVecBegin + C.getStartIdx(),
980 UnsignedVecBegin + C.getEndIdx() + 1))
981 I = static_cast<unsigned>(-1);
982 OutlinedSomething = true;
983
984 // Statistics.
985 NumOutlined++;
986 }
987 }
988
989 LLVM_DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n";);
990 return OutlinedSomething;
991}
992
993void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
994 // Build instruction mappings for each function in the module. Start by
995 // iterating over each Function in M.
996 LLVM_DEBUG(dbgs() << "*** Populating mapper ***\n");
997 for (Function &F : M) {
998 LLVM_DEBUG(dbgs() << "MAPPING FUNCTION: " << F.getName() << "\n");
999
1000 if (F.hasFnAttribute("nooutline")) {
1001 LLVM_DEBUG(dbgs() << "SKIP: Function has nooutline attribute\n");
1002 continue;
1003 }
1004
1005 // There's something in F. Check if it has a MachineFunction associated with
1006 // it.
1008
1009 // If it doesn't, then there's nothing to outline from. Move to the next
1010 // Function.
1011 if (!MF) {
1012 LLVM_DEBUG(dbgs() << "SKIP: Function does not have a MachineFunction\n");
1013 continue;
1014 }
1015
1017 if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault(*MF)) {
1018 LLVM_DEBUG(dbgs() << "SKIP: Target does not want to outline from "
1019 "function by default\n");
1020 continue;
1021 }
1022
1023 // We have a MachineFunction. Ask the target if it's suitable for outlining.
1024 // If it isn't, then move on to the next Function in the module.
1025 if (!TII->isFunctionSafeToOutlineFrom(*MF, OutlineFromLinkOnceODRs)) {
1026 LLVM_DEBUG(dbgs() << "SKIP: " << MF->getName()
1027 << ": unsafe to outline from\n");
1028 continue;
1029 }
1030
1031 // We have a function suitable for outlining. Iterate over every
1032 // MachineBasicBlock in MF and try to map its instructions to a list of
1033 // unsigned integers.
1034 const unsigned MinMBBSize = 2;
1035
1036 for (MachineBasicBlock &MBB : *MF) {
1037 LLVM_DEBUG(dbgs() << " MAPPING MBB: '" << MBB.getName() << "'\n");
1038 // If there isn't anything in MBB, then there's no point in outlining from
1039 // it.
1040 // If there are fewer than 2 instructions in the MBB, then it can't ever
1041 // contain something worth outlining.
1042 // FIXME: This should be based off of the maximum size in B of an outlined
1043 // call versus the size in B of the MBB.
1044 if (MBB.size() < MinMBBSize) {
1045 LLVM_DEBUG(dbgs() << " SKIP: MBB size less than minimum size of "
1046 << MinMBBSize << "\n");
1047 continue;
1048 }
1049
1050 // Check if MBB could be the target of an indirect branch. If it is, then
1051 // we don't want to outline from it.
1052 if (MBB.hasAddressTaken()) {
1053 LLVM_DEBUG(dbgs() << " SKIP: MBB's address is taken\n");
1054 continue;
1055 }
1056
1057 // MBB is suitable for outlining. Map it to a list of unsigneds.
1058 Mapper.convertToUnsignedVec(MBB, *TII);
1059 }
1060 }
1061 // Statistics.
1062 UnsignedVecSize = Mapper.UnsignedVec.size();
1063}
1064
1065void MachineOutliner::initSizeRemarkInfo(
1066 const Module &M, StringMap<unsigned> &FunctionToInstrCount) {
1067 // Collect instruction counts for every function. We'll use this to emit
1068 // per-function size remarks later.
1069 for (const Function &F : M) {
1071
1072 // We only care about MI counts here. If there's no MachineFunction at this
1073 // point, then there won't be after the outliner runs, so let's move on.
1074 if (!MF)
1075 continue;
1076 FunctionToInstrCount[F.getName().str()] = MF->getInstructionCount();
1077 }
1078}
1079
1080void MachineOutliner::emitInstrCountChangedRemark(
1081 const Module &M, const StringMap<unsigned> &FunctionToInstrCount) {
1082 // Iterate over each function in the module and emit remarks.
1083 // Note that we won't miss anything by doing this, because the outliner never
1084 // deletes functions.
1085 for (const Function &F : M) {
1087
1088 // The outliner never deletes functions. If we don't have a MF here, then we
1089 // didn't have one prior to outlining either.
1090 if (!MF)
1091 continue;
1092
1093 std::string Fname = std::string(F.getName());
1094 unsigned FnCountAfter = MF->getInstructionCount();
1095 unsigned FnCountBefore = 0;
1096
1097 // Check if the function was recorded before.
1098 auto It = FunctionToInstrCount.find(Fname);
1099
1100 // Did we have a previously-recorded size? If yes, then set FnCountBefore
1101 // to that.
1102 if (It != FunctionToInstrCount.end())
1103 FnCountBefore = It->second;
1104
1105 // Compute the delta and emit a remark if there was a change.
1106 int64_t FnDelta = static_cast<int64_t>(FnCountAfter) -
1107 static_cast<int64_t>(FnCountBefore);
1108 if (FnDelta == 0)
1109 continue;
1110
1112 MORE.emit([&]() {
1113 MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
1114 DiagnosticLocation(), &MF->front());
1115 R << DiagnosticInfoOptimizationBase::Argument("Pass", "Machine Outliner")
1116 << ": Function: "
1117 << DiagnosticInfoOptimizationBase::Argument("Function", F.getName())
1118 << ": MI instruction count changed from "
1119 << DiagnosticInfoOptimizationBase::Argument("MIInstrsBefore",
1120 FnCountBefore)
1121 << " to "
1123 FnCountAfter)
1124 << "; Delta: "
1125 << DiagnosticInfoOptimizationBase::Argument("Delta", FnDelta);
1126 return R;
1127 });
1128 }
1129}
1130
1131bool MachineOutliner::runOnModule(Module &M) {
1132 // Check if there's anything in the module. If it's empty, then there's
1133 // nothing to outline.
1134 if (M.empty())
1135 return false;
1136
1137 MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
1138
1139 // Number to append to the current outlined function.
1140 unsigned OutlinedFunctionNum = 0;
1141
1142 OutlineRepeatedNum = 0;
1143 if (!doOutline(M, OutlinedFunctionNum))
1144 return false;
1145
1146 for (unsigned I = 0; I < OutlinerReruns; ++I) {
1147 OutlinedFunctionNum = 0;
1148 OutlineRepeatedNum++;
1149 if (!doOutline(M, OutlinedFunctionNum)) {
1150 LLVM_DEBUG({
1151 dbgs() << "Did not outline on iteration " << I + 2 << " out of "
1152 << OutlinerReruns + 1 << "\n";
1153 });
1154 break;
1155 }
1156 }
1157
1158 return true;
1159}
1160
1161bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) {
1162 // If the user passed -enable-machine-outliner=always or
1163 // -enable-machine-outliner, the pass will run on all functions in the module.
1164 // Otherwise, if the target supports default outlining, it will run on all
1165 // functions deemed by the target to be worth outlining from by default. Tell
1166 // the user how the outliner is running.
1167 LLVM_DEBUG({
1168 dbgs() << "Machine Outliner: Running on ";
1169 if (RunOnAllFunctions)
1170 dbgs() << "all functions";
1171 else
1172 dbgs() << "target-default functions";
1173 dbgs() << "\n";
1174 });
1175
1176 // If the user specifies that they want to outline from linkonceodrs, set
1177 // it here.
1178 OutlineFromLinkOnceODRs = EnableLinkOnceODROutlining;
1179 InstructionMapper Mapper(*MMI);
1180
1181 // Prepare instruction mappings for the suffix tree.
1182 populateMapper(Mapper, M);
1183 std::vector<OutlinedFunction> FunctionList;
1184
1185 // Find all of the outlining candidates.
1186 findCandidates(Mapper, FunctionList);
1187
1188 // If we've requested size remarks, then collect the MI counts of every
1189 // function before outlining, and the MI counts after outlining.
1190 // FIXME: This shouldn't be in the outliner at all; it should ultimately be
1191 // the pass manager's responsibility.
1192 // This could pretty easily be placed in outline instead, but because we
1193 // really ultimately *don't* want this here, it's done like this for now
1194 // instead.
1195
1196 // Check if we want size remarks.
1197 bool ShouldEmitSizeRemarks = M.shouldEmitInstrCountChangedRemark();
1198 StringMap<unsigned> FunctionToInstrCount;
1199 if (ShouldEmitSizeRemarks)
1200 initSizeRemarkInfo(M, FunctionToInstrCount);
1201
1202 // Outline each of the candidates and return true if something was outlined.
1203 bool OutlinedSomething =
1204 outline(M, FunctionList, Mapper, OutlinedFunctionNum);
1205
1206 // If we outlined something, we definitely changed the MI count of the
1207 // module. If we've asked for size remarks, then output them.
1208 // FIXME: This should be in the pass manager.
1209 if (ShouldEmitSizeRemarks && OutlinedSomething)
1210 emitInstrCountChangedRemark(M, FunctionToInstrCount);
1211
1212 LLVM_DEBUG({
1213 if (!OutlinedSomething)
1214 dbgs() << "Stopped outlining at iteration " << OutlineRepeatedNum
1215 << " because no changes were found.\n";
1216 });
1217
1218 return OutlinedSomething;
1219}
unsigned const MachineRegisterInfo * MRI
AMDGPU promote alloca to vector or false DEBUG_TYPE to vector
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
std::string Name
const HexagonInstrInfo * TII
static DISubprogram * getSubprogramOrNull(OutlinableGroup &Group)
Get the subprogram if it exists for one of the outlined regions.
Definition: IROutliner.cpp:620
IRTranslator LLVM IR MI
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
static cl::opt< unsigned > OutlinerBenefitThreshold("outliner-benefit-threshold", cl::init(1), cl::Hidden, cl::desc("The minimum size in bytes before an outlining candidate is accepted"))
static cl::opt< bool > OutlinerLeafDescendants("outliner-leaf-descendants", cl::init(true), cl::Hidden, cl::desc("Consider all leaf descendants of internal nodes of the suffix " "tree as candidates for outlining (if false, only leaf children " "are considered)"))
static cl::opt< unsigned > OutlinerReruns("machine-outliner-reruns", cl::init(0), cl::Hidden, cl::desc("Number of times to rerun the outliner after the initial outline"))
Number of times to re-run the outliner.
#define DEBUG_TYPE
static cl::opt< bool > EnableLinkOnceODROutlining("enable-linkonceodr-outlining", cl::Hidden, cl::desc("Enable the machine outliner on linkonceodr functions"), cl::init(false))
Contains all data structures shared between the outliner implemented in MachineOutliner....
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
static Function * createOutlinedFunction(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder, StringRef FuncName, SmallVectorImpl< Value * > &Inputs, OpenMPIRBuilder::TargetBodyGenCallbackTy &CBFunc, OpenMPIRBuilder::TargetGenArgAccessorsCallbackTy &ArgAccessorFuncCB)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
Value * RHS
Value * LHS
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:202
This class represents a function call, abstracting a target machine's calling convention.
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Subprogram description.
A debug info location.
Definition: DebugLoc.h:33
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:165
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:59
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2671
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:52
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineFunctionProperties & set(Property P)
bool hasProperty(Property P) const
MachineFunctionProperties & reset(Property P)
unsigned getInstructionCount() const
Return the number of MachineInstrs in this MachineFunction.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const std::vector< MCCFIInstruction > & getFrameInstructions() const
Returns a reference to a list of cfi instructions in the function's prologue.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
Definition: MachineInstr.h:69
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:346
void dropMemRefs(MachineFunction &MF)
Clear this MachineInstr's memory reference descriptor list.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
This class contains meta information specific to a module.
MachineFunction & getOrCreateMachineFunction(Function &F)
Returns the MachineFunction constructed for the IR function F.
MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
Diagnostic information for optimization analysis remarks.
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void freezeReservedRegs()
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition: Mangler.cpp:120
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:166
bool erase(const T &V)
Definition: SmallSet.h:207
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
iterator end()
Definition: StringMap.h:220
iterator find(StringRef Key)
Definition: StringMap.h:233
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Type * getVoidTy(LLVMContext &C)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void stable_sort(R &&Range)
Definition: STLExtras.h:1995
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2067
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
UWTableKind
Definition: CodeGen.h:120
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1647
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
void initializeMachineOutlinerPass(PassRegistry &)
ModulePass * createMachineOutlinerPass(bool RunOnAllFunctions=true)
This pass performs outlining on machine instructions directly before printing assembly.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2051
void addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs)
Adds registers contained in LiveRegs to the block live-in list of MBB.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define MORE()
Definition: regcomp.c:252
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52
Used in the streaming interface as the general argument type.
A repeated substring in the tree.
Definition: SuffixTree.h:49
An individual sequence of instructions to be replaced with a call to an outlined function.
MachineFunction * getMF() const
The information necessary to create an outlined function for some class of candidate.
unsigned getBenefit() const
Return the number of instructions that would be saved by outlining this function.
MachineFunction * MF
The actual outlined function created.
unsigned getNumInstrs() const
Return the number of instructions in this sequence.
unsigned getOccurrenceCount() const
Return the number of candidates for this OutlinedFunction.
std::vector< Candidate > Candidates