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"
68#include "llvm/CodeGen/Passes.h"
71#include "llvm/IR/DIBuilder.h"
72#include "llvm/IR/IRBuilder.h"
73#include "llvm/IR/Mangler.h"
74#include "llvm/IR/Module.h"
77#include "llvm/Support/Debug.h"
81#include <tuple>
82#include <vector>
83
84#define DEBUG_TYPE "machine-outliner"
85
86using namespace llvm;
87using namespace ore;
88using namespace outliner;
89
90// Statistics for outlined functions.
91STATISTIC(NumOutlined, "Number of candidates outlined");
92STATISTIC(FunctionsCreated, "Number of functions created");
93
94// Statistics for instruction mapping.
95STATISTIC(NumLegalInUnsignedVec, "Outlinable instructions mapped");
96STATISTIC(NumIllegalInUnsignedVec,
97 "Unoutlinable instructions mapped + number of sentinel values");
98STATISTIC(NumSentinels, "Sentinel values inserted during mapping");
99STATISTIC(NumInvisible,
100 "Invisible instructions skipped during mapping");
101STATISTIC(UnsignedVecSize,
102 "Total number of instructions mapped and saved to mapping vector");
103STATISTIC(StableHashAttempts,
104 "Count of hashing attempts made for outlined functions");
105STATISTIC(StableHashDropped,
106 "Count of unsuccessful hashing attempts for outlined functions");
107
108// Set to true if the user wants the outliner to run on linkonceodr linkage
109// functions. This is false by default because the linker can dedupe linkonceodr
110// functions. Since the outliner is confined to a single module (modulo LTO),
111// this is off by default. It should, however, be the default behaviour in
112// LTO.
114 "enable-linkonceodr-outlining", cl::Hidden,
115 cl::desc("Enable the machine outliner on linkonceodr functions"),
116 cl::init(false));
117
118/// Number of times to re-run the outliner. This is not the total number of runs
119/// as the outliner will run at least one time. The default value is set to 0,
120/// meaning the outliner will run one time and rerun zero times after that.
122 "machine-outliner-reruns", cl::init(0), cl::Hidden,
123 cl::desc(
124 "Number of times to rerun the outliner after the initial outline"));
125
127 "outliner-benefit-threshold", cl::init(1), cl::Hidden,
128 cl::desc(
129 "The minimum size in bytes before an outlining candidate is accepted"));
130
132 "outliner-leaf-descendants", cl::init(true), cl::Hidden,
133 cl::desc("Consider all leaf descendants of internal nodes of the suffix "
134 "tree as candidates for outlining (if false, only leaf children "
135 "are considered)"));
136
137static cl::opt<bool>
138 DisableGlobalOutlining("disable-global-outlining", cl::Hidden,
139 cl::desc("Disable global outlining only by ignoring "
140 "the codegen data generation or use"),
141 cl::init(false));
142
144 "append-content-hash-outlined-name", cl::Hidden,
145 cl::desc("This appends the content hash to the globally outlined function "
146 "name. It's beneficial for enhancing the precision of the stable "
147 "hash and for ordering the outlined functions."),
148 cl::init(true));
149
150namespace {
151
152/// Maps \p MachineInstrs to unsigned integers and stores the mappings.
153struct InstructionMapper {
154 const MachineModuleInfo &MMI;
155
156 /// The next available integer to assign to a \p MachineInstr that
157 /// cannot be outlined.
158 ///
159 /// Set to -3 for compatability with \p DenseMapInfo<unsigned>.
160 unsigned IllegalInstrNumber = -3;
161
162 /// The next available integer to assign to a \p MachineInstr that can
163 /// be outlined.
164 unsigned LegalInstrNumber = 0;
165
166 /// Correspondence from \p MachineInstrs to unsigned integers.
168 InstructionIntegerMap;
169
170 /// Correspondence between \p MachineBasicBlocks and target-defined flags.
172
173 /// The vector of unsigned integers that the module is mapped to.
174 SmallVector<unsigned> UnsignedVec;
175
176 /// Stores the location of the instruction associated with the integer
177 /// at index i in \p UnsignedVec for each index i.
179
180 // Set if we added an illegal number in the previous step.
181 // Since each illegal number is unique, we only need one of them between
182 // each range of legal numbers. This lets us make sure we don't add more
183 // than one illegal number per range.
184 bool AddedIllegalLastTime = false;
185
186 /// Maps \p *It to a legal integer.
187 ///
188 /// Updates \p CanOutlineWithPrevInstr, \p HaveLegalRange, \p InstrListForMBB,
189 /// \p UnsignedVecForMBB, \p InstructionIntegerMap, and \p LegalInstrNumber.
190 ///
191 /// \returns The integer that \p *It was mapped to.
192 unsigned mapToLegalUnsigned(
193 MachineBasicBlock::iterator &It, bool &CanOutlineWithPrevInstr,
194 bool &HaveLegalRange, unsigned &NumLegalInBlock,
195 SmallVector<unsigned> &UnsignedVecForMBB,
197 // We added something legal, so we should unset the AddedLegalLastTime
198 // flag.
199 AddedIllegalLastTime = false;
200
201 // If we have at least two adjacent legal instructions (which may have
202 // invisible instructions in between), remember that.
203 if (CanOutlineWithPrevInstr)
204 HaveLegalRange = true;
205 CanOutlineWithPrevInstr = true;
206
207 // Keep track of the number of legal instructions we insert.
208 NumLegalInBlock++;
209
210 // Get the integer for this instruction or give it the current
211 // LegalInstrNumber.
212 InstrListForMBB.push_back(It);
213 MachineInstr &MI = *It;
214 bool WasInserted;
216 ResultIt;
217 std::tie(ResultIt, WasInserted) =
218 InstructionIntegerMap.insert(std::make_pair(&MI, LegalInstrNumber));
219 unsigned MINumber = ResultIt->second;
220
221 // There was an insertion.
222 if (WasInserted)
223 LegalInstrNumber++;
224
225 UnsignedVecForMBB.push_back(MINumber);
226
227 // Make sure we don't overflow or use any integers reserved by the DenseMap.
228 if (LegalInstrNumber >= IllegalInstrNumber)
229 report_fatal_error("Instruction mapping overflow!");
230
231 assert(LegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
232 "Tried to assign DenseMap tombstone or empty key to instruction.");
233 assert(LegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
234 "Tried to assign DenseMap tombstone or empty key to instruction.");
235
236 // Statistics.
237 ++NumLegalInUnsignedVec;
238 return MINumber;
239 }
240
241 /// Maps \p *It to an illegal integer.
242 ///
243 /// Updates \p InstrListForMBB, \p UnsignedVecForMBB, and \p
244 /// IllegalInstrNumber.
245 ///
246 /// \returns The integer that \p *It was mapped to.
247 unsigned mapToIllegalUnsigned(
248 MachineBasicBlock::iterator &It, bool &CanOutlineWithPrevInstr,
249 SmallVector<unsigned> &UnsignedVecForMBB,
251 // Can't outline an illegal instruction. Set the flag.
252 CanOutlineWithPrevInstr = false;
253
254 // Only add one illegal number per range of legal numbers.
255 if (AddedIllegalLastTime)
256 return IllegalInstrNumber;
257
258 // Remember that we added an illegal number last time.
259 AddedIllegalLastTime = true;
260 unsigned MINumber = IllegalInstrNumber;
261
262 InstrListForMBB.push_back(It);
263 UnsignedVecForMBB.push_back(IllegalInstrNumber);
264 IllegalInstrNumber--;
265 // Statistics.
266 ++NumIllegalInUnsignedVec;
267
268 assert(LegalInstrNumber < IllegalInstrNumber &&
269 "Instruction mapping overflow!");
270
271 assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getEmptyKey() &&
272 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
273
274 assert(IllegalInstrNumber != DenseMapInfo<unsigned>::getTombstoneKey() &&
275 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
276
277 return MINumber;
278 }
279
280 /// Transforms a \p MachineBasicBlock into a \p vector of \p unsigneds
281 /// and appends it to \p UnsignedVec and \p InstrList.
282 ///
283 /// Two instructions are assigned the same integer if they are identical.
284 /// If an instruction is deemed unsafe to outline, then it will be assigned an
285 /// unique integer. The resulting mapping is placed into a suffix tree and
286 /// queried for candidates.
287 ///
288 /// \param MBB The \p MachineBasicBlock to be translated into integers.
289 /// \param TII \p TargetInstrInfo for the function.
290 void convertToUnsignedVec(MachineBasicBlock &MBB,
291 const TargetInstrInfo &TII) {
292 LLVM_DEBUG(dbgs() << "*** Converting MBB '" << MBB.getName()
293 << "' to unsigned vector ***\n");
294 unsigned Flags = 0;
295
296 // Don't even map in this case.
297 if (!TII.isMBBSafeToOutlineFrom(MBB, Flags))
298 return;
299
300 auto OutlinableRanges = TII.getOutlinableRanges(MBB, Flags);
301 LLVM_DEBUG(dbgs() << MBB.getName() << ": " << OutlinableRanges.size()
302 << " outlinable range(s)\n");
303 if (OutlinableRanges.empty())
304 return;
305
306 // Store info for the MBB for later outlining.
307 MBBFlagsMap[&MBB] = Flags;
308
310
311 // The number of instructions in this block that will be considered for
312 // outlining.
313 unsigned NumLegalInBlock = 0;
314
315 // True if we have at least two legal instructions which aren't separated
316 // by an illegal instruction.
317 bool HaveLegalRange = false;
318
319 // True if we can perform outlining given the last mapped (non-invisible)
320 // instruction. This lets us know if we have a legal range.
321 bool CanOutlineWithPrevInstr = false;
322
323 // FIXME: Should this all just be handled in the target, rather than using
324 // repeated calls to getOutliningType?
325 SmallVector<unsigned> UnsignedVecForMBB;
327
328 LLVM_DEBUG(dbgs() << "*** Mapping outlinable ranges ***\n");
329 for (auto &OutlinableRange : OutlinableRanges) {
330 auto OutlinableRangeBegin = OutlinableRange.first;
331 auto OutlinableRangeEnd = OutlinableRange.second;
332#ifndef NDEBUG
334 dbgs() << "Mapping "
335 << std::distance(OutlinableRangeBegin, OutlinableRangeEnd)
336 << " instruction range\n");
337 // Everything outside of an outlinable range is illegal.
338 unsigned NumSkippedInRange = 0;
339#endif
340 for (; It != OutlinableRangeBegin; ++It) {
341#ifndef NDEBUG
342 ++NumSkippedInRange;
343#endif
344 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
345 InstrListForMBB);
346 }
347#ifndef NDEBUG
348 LLVM_DEBUG(dbgs() << "Skipped " << NumSkippedInRange
349 << " instructions outside outlinable range\n");
350#endif
351 assert(It != MBB.end() && "Should still have instructions?");
352 // `It` is now positioned at the beginning of a range of instructions
353 // which may be outlinable. Check if each instruction is known to be safe.
354 for (; It != OutlinableRangeEnd; ++It) {
355 // Keep track of where this instruction is in the module.
356 switch (TII.getOutliningType(MMI, It, Flags)) {
357 case InstrType::Illegal:
358 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
359 InstrListForMBB);
360 break;
361
362 case InstrType::Legal:
363 mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
364 NumLegalInBlock, UnsignedVecForMBB,
365 InstrListForMBB);
366 break;
367
368 case InstrType::LegalTerminator:
369 mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
370 NumLegalInBlock, UnsignedVecForMBB,
371 InstrListForMBB);
372 // The instruction also acts as a terminator, so we have to record
373 // that in the string.
374 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
375 InstrListForMBB);
376 break;
377
378 case InstrType::Invisible:
379 // Normally this is set by mapTo(Blah)Unsigned, but we just want to
380 // skip this instruction. So, unset the flag here.
381 ++NumInvisible;
382 AddedIllegalLastTime = false;
383 break;
384 }
385 }
386 }
387
388 LLVM_DEBUG(dbgs() << "HaveLegalRange = " << HaveLegalRange << "\n");
389
390 // Are there enough legal instructions in the block for outlining to be
391 // possible?
392 if (HaveLegalRange) {
393 // After we're done every insertion, uniquely terminate this part of the
394 // "string". This makes sure we won't match across basic block or function
395 // boundaries since the "end" is encoded uniquely and thus appears in no
396 // repeated substring.
397 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
398 InstrListForMBB);
399 ++NumSentinels;
400 append_range(InstrList, InstrListForMBB);
401 append_range(UnsignedVec, UnsignedVecForMBB);
402 }
403 }
404
405 InstructionMapper(const MachineModuleInfo &MMI_) : MMI(MMI_) {
406 // Make sure that the implementation of DenseMapInfo<unsigned> hasn't
407 // changed.
409 "DenseMapInfo<unsigned>'s empty key isn't -1!");
411 "DenseMapInfo<unsigned>'s tombstone key isn't -2!");
412 }
413};
414
415/// An interprocedural pass which finds repeated sequences of
416/// instructions and replaces them with calls to functions.
417///
418/// Each instruction is mapped to an unsigned integer and placed in a string.
419/// The resulting mapping is then placed in a \p SuffixTree. The \p SuffixTree
420/// is then repeatedly queried for repeated sequences of instructions. Each
421/// non-overlapping repeated sequence is then placed in its own
422/// \p MachineFunction and each instance is then replaced with a call to that
423/// function.
424struct MachineOutliner : public ModulePass {
425
426 static char ID;
427
428 MachineModuleInfo *MMI = nullptr;
429
430 /// Set to true if the outliner should consider functions with
431 /// linkonceodr linkage.
432 bool OutlineFromLinkOnceODRs = false;
433
434 /// The current repeat number of machine outlining.
435 unsigned OutlineRepeatedNum = 0;
436
437 /// Set to true if the outliner should run on all functions in the module
438 /// considered safe for outlining.
439 /// Set to true by default for compatibility with llc's -run-pass option.
440 /// Set when the pass is constructed in TargetPassConfig.
441 bool RunOnAllFunctions = true;
442
443 /// This is a compact representation of hash sequences of outlined functions.
444 /// It is used when OutlinerMode = CGDataMode::Write.
445 /// The resulting hash tree will be emitted into __llvm_outlined section
446 /// which will be dead-stripped not going to the final binary.
447 /// A post-process using llvm-cgdata, lld, or ThinLTO can merge them into
448 /// a global oulined hash tree for the subsequent codegen.
449 std::unique_ptr<OutlinedHashTree> LocalHashTree;
450
451 /// The mode of the outliner.
452 /// When is's CGDataMode::None, candidates are populated with the suffix tree
453 /// within a module and outlined.
454 /// When it's CGDataMode::Write, in addition to CGDataMode::None, the hash
455 /// sequences of outlined functions are published into LocalHashTree.
456 /// When it's CGDataMode::Read, candidates are populated with the global
457 /// outlined hash tree that has been built by the previous codegen.
458 CGDataMode OutlinerMode = CGDataMode::None;
459
460 StringRef getPassName() const override { return "Machine Outliner"; }
461
462 void getAnalysisUsage(AnalysisUsage &AU) const override {
466 AU.setPreservesAll();
468 }
469
470 MachineOutliner() : ModulePass(ID) {
472 }
473
474 /// Remark output explaining that not outlining a set of candidates would be
475 /// better than outlining that set.
476 void emitNotOutliningCheaperRemark(
477 unsigned StringLen, std::vector<Candidate> &CandidatesForRepeatedSeq,
478 OutlinedFunction &OF);
479
480 /// Remark output explaining that a function was outlined.
481 void emitOutlinedFunctionRemark(OutlinedFunction &OF);
482
483 /// Find all repeated substrings that satisfy the outlining cost model by
484 /// constructing a suffix tree.
485 ///
486 /// If a substring appears at least twice, then it must be represented by
487 /// an internal node which appears in at least two suffixes. Each suffix
488 /// is represented by a leaf node. To do this, we visit each internal node
489 /// in the tree, using the leaf children of each internal node. If an
490 /// internal node represents a beneficial substring, then we use each of
491 /// its leaf children to find the locations of its substring.
492 ///
493 /// \param Mapper Contains outlining mapping information.
494 /// \param[out] FunctionList Filled with a list of \p OutlinedFunctions
495 /// each type of candidate.
496 void
497 findCandidates(InstructionMapper &Mapper,
498 std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList);
499
500 /// Find all repeated substrings that match in the global outlined hash
501 /// tree built from the previous codegen.
502 ///
503 /// \param Mapper Contains outlining mapping information.
504 /// \param[out] FunctionList Filled with a list of \p OutlinedFunctions
505 /// each type of candidate.
506 void findGlobalCandidates(
507 InstructionMapper &Mapper,
508 std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList);
509
510 /// Replace the sequences of instructions represented by \p OutlinedFunctions
511 /// with calls to functions.
512 ///
513 /// \param M The module we are outlining from.
514 /// \param FunctionList A list of functions to be inserted into the module.
515 /// \param Mapper Contains the instruction mappings for the module.
516 /// \param[out] OutlinedFunctionNum The outlined function number.
517 bool outline(Module &M,
518 std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList,
519 InstructionMapper &Mapper, unsigned &OutlinedFunctionNum);
520
521 /// Creates a function for \p OF and inserts it into the module.
523 InstructionMapper &Mapper,
524 unsigned Name);
525
526 /// Compute and publish the stable hash sequence of instructions in the
527 /// outlined function, \p MF. The parameter \p CandSize represents the number
528 /// of candidates that have identical instruction sequences to \p MF.
529 void computeAndPublishHashSequence(MachineFunction &MF, unsigned CandSize);
530
531 /// Initialize the outliner mode.
532 void initializeOutlinerMode(const Module &M);
533
534 /// Emit the outlined hash tree into __llvm_outline section.
535 void emitOutlinedHashTree(Module &M);
536
537 /// Calls 'doOutline()' 1 + OutlinerReruns times.
538 bool runOnModule(Module &M) override;
539
540 /// Construct a suffix tree on the instructions in \p M and outline repeated
541 /// strings from that tree.
542 bool doOutline(Module &M, unsigned &OutlinedFunctionNum);
543
544 /// Return a DISubprogram for OF if one exists, and null otherwise. Helper
545 /// function for remark emission.
547 for (const Candidate &C : OF.Candidates)
548 if (MachineFunction *MF = C.getMF())
549 if (DISubprogram *SP = MF->getFunction().getSubprogram())
550 return SP;
551 return nullptr;
552 }
553
554 /// Populate and \p InstructionMapper with instruction-to-integer mappings.
555 /// These are used to construct a suffix tree.
556 void populateMapper(InstructionMapper &Mapper, Module &M);
557
558 /// Initialize information necessary to output a size remark.
559 /// FIXME: This should be handled by the pass manager, not the outliner.
560 /// FIXME: This is nearly identical to the initSizeRemarkInfo in the legacy
561 /// pass manager.
562 void initSizeRemarkInfo(const Module &M,
563 StringMap<unsigned> &FunctionToInstrCount);
564
565 /// Emit the remark.
566 // FIXME: This should be handled by the pass manager, not the outliner.
567 void
568 emitInstrCountChangedRemark(const Module &M,
569 const StringMap<unsigned> &FunctionToInstrCount);
570};
571} // Anonymous namespace.
572
573char MachineOutliner::ID = 0;
574
575namespace llvm {
576ModulePass *createMachineOutlinerPass(bool RunOnAllFunctions) {
577 MachineOutliner *OL = new MachineOutliner();
578 OL->RunOnAllFunctions = RunOnAllFunctions;
579 return OL;
580}
581
582} // namespace llvm
583
584INITIALIZE_PASS(MachineOutliner, DEBUG_TYPE, "Machine Function Outliner", false,
585 false)
586
587void MachineOutliner::emitNotOutliningCheaperRemark(
588 unsigned StringLen, std::vector<Candidate> &CandidatesForRepeatedSeq,
589 OutlinedFunction &OF) {
590 // FIXME: Right now, we arbitrarily choose some Candidate from the
591 // OutlinedFunction. This isn't necessarily fixed, nor does it have to be.
592 // We should probably sort these by function name or something to make sure
593 // the remarks are stable.
594 Candidate &C = CandidatesForRepeatedSeq.front();
595 MachineOptimizationRemarkEmitter MORE(*(C.getMF()), nullptr);
596 MORE.emit([&]() {
597 MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper",
598 C.front().getDebugLoc(), C.getMBB());
599 R << "Did not outline " << NV("Length", StringLen) << " instructions"
600 << " from " << NV("NumOccurrences", CandidatesForRepeatedSeq.size())
601 << " locations."
602 << " Bytes from outlining all occurrences ("
603 << NV("OutliningCost", OF.getOutliningCost()) << ")"
604 << " >= Unoutlined instruction bytes ("
605 << NV("NotOutliningCost", OF.getNotOutlinedCost()) << ")"
606 << " (Also found at: ";
607
608 // Tell the user the other places the candidate was found.
609 for (unsigned i = 1, e = CandidatesForRepeatedSeq.size(); i < e; i++) {
610 R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
611 CandidatesForRepeatedSeq[i].front().getDebugLoc());
612 if (i != e - 1)
613 R << ", ";
614 }
615
616 R << ")";
617 return R;
618 });
619}
620
621void MachineOutliner::emitOutlinedFunctionRemark(OutlinedFunction &OF) {
622 MachineBasicBlock *MBB = &*OF.MF->begin();
624 MachineOptimizationRemark R(DEBUG_TYPE, "OutlinedFunction",
626 R << "Saved " << NV("OutliningBenefit", OF.getBenefit()) << " bytes by "
627 << "outlining " << NV("Length", OF.getNumInstrs()) << " instructions "
628 << "from " << NV("NumOccurrences", OF.getOccurrenceCount())
629 << " locations. "
630 << "(Found at: ";
631
632 // Tell the user the other places the candidate was found.
633 for (size_t i = 0, e = OF.Candidates.size(); i < e; i++) {
634
635 R << NV((Twine("StartLoc") + Twine(i)).str(),
636 OF.Candidates[i].front().getDebugLoc());
637 if (i != e - 1)
638 R << ", ";
639 }
640
641 R << ")";
642
643 MORE.emit(R);
644}
645
647 unsigned StartIdx;
648 unsigned EndIdx;
649 unsigned Count;
650 MatchedEntry(unsigned StartIdx, unsigned EndIdx, unsigned Count)
652 MatchedEntry() = delete;
653};
654
655// Find all matches in the global outlined hash tree.
656// It's quadratic complexity in theory, but it's nearly linear in practice
657// since the length of outlined sequences are small within a block.
658static SmallVector<MatchedEntry> getMatchedEntries(InstructionMapper &Mapper) {
659 auto &InstrList = Mapper.InstrList;
660 auto &UnsignedVec = Mapper.UnsignedVec;
661
662 SmallVector<MatchedEntry> MatchedEntries;
663 auto Size = UnsignedVec.size();
664
665 // Get the global outlined hash tree built from the previous run.
667 const auto *RootNode = cgdata::getOutlinedHashTree()->getRoot();
668
669 auto getValidInstr = [&](unsigned Index) -> const MachineInstr * {
670 if (UnsignedVec[Index] >= Mapper.LegalInstrNumber)
671 return nullptr;
672 return &(*InstrList[Index]);
673 };
674
675 auto getStableHashAndFollow =
676 [](const MachineInstr &MI, const HashNode *CurrNode) -> const HashNode * {
677 stable_hash StableHash = stableHashValue(MI);
678 if (!StableHash)
679 return nullptr;
680 auto It = CurrNode->Successors.find(StableHash);
681 return (It == CurrNode->Successors.end()) ? nullptr : It->second.get();
682 };
683
684 for (unsigned I = 0; I < Size; ++I) {
685 const MachineInstr *MI = getValidInstr(I);
686 if (!MI || MI->isDebugInstr())
687 continue;
688 const HashNode *CurrNode = getStableHashAndFollow(*MI, RootNode);
689 if (!CurrNode)
690 continue;
691
692 for (unsigned J = I + 1; J < Size; ++J) {
693 const MachineInstr *MJ = getValidInstr(J);
694 if (!MJ)
695 break;
696 // Skip debug instructions as we did for the outlined function.
697 if (MJ->isDebugInstr())
698 continue;
699 CurrNode = getStableHashAndFollow(*MJ, CurrNode);
700 if (!CurrNode)
701 break;
702 // Even with a match ending with a terminal, we continue finding
703 // matches to populate all candidates.
704 if (auto Count = CurrNode->Terminals)
705 MatchedEntries.emplace_back(I, J, *Count);
706 }
707 }
708
709 return MatchedEntries;
710}
711
712void MachineOutliner::findGlobalCandidates(
713 InstructionMapper &Mapper,
714 std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList) {
715 FunctionList.clear();
716 auto &InstrList = Mapper.InstrList;
717 auto &MBBFlagsMap = Mapper.MBBFlagsMap;
718
719 std::vector<Candidate> CandidatesForRepeatedSeq;
720 for (auto &ME : getMatchedEntries(Mapper)) {
721 CandidatesForRepeatedSeq.clear();
722 MachineBasicBlock::iterator StartIt = InstrList[ME.StartIdx];
723 MachineBasicBlock::iterator EndIt = InstrList[ME.EndIdx];
724 auto Length = ME.EndIdx - ME.StartIdx + 1;
725 MachineBasicBlock *MBB = StartIt->getParent();
726 CandidatesForRepeatedSeq.emplace_back(ME.StartIdx, Length, StartIt, EndIt,
727 MBB, FunctionList.size(),
728 MBBFlagsMap[MBB]);
729 const TargetInstrInfo *TII =
731 unsigned MinRepeats = 1;
732 std::optional<std::unique_ptr<OutlinedFunction>> OF =
733 TII->getOutliningCandidateInfo(*MMI, CandidatesForRepeatedSeq,
734 MinRepeats);
735 if (!OF.has_value() || OF.value()->Candidates.empty())
736 continue;
737 // We create a global candidate for each match.
738 assert(OF.value()->Candidates.size() == MinRepeats);
739 FunctionList.emplace_back(std::make_unique<GlobalOutlinedFunction>(
740 std::move(OF.value()), ME.Count));
741 }
742}
743
744void MachineOutliner::findCandidates(
745 InstructionMapper &Mapper,
746 std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList) {
747 FunctionList.clear();
748 SuffixTree ST(Mapper.UnsignedVec, OutlinerLeafDescendants);
749
750 // First, find all of the repeated substrings in the tree of minimum length
751 // 2.
752 std::vector<Candidate> CandidatesForRepeatedSeq;
753 LLVM_DEBUG(dbgs() << "*** Discarding overlapping candidates *** \n");
755 dbgs() << "Searching for overlaps in all repeated sequences...\n");
756 for (SuffixTree::RepeatedSubstring &RS : ST) {
757 CandidatesForRepeatedSeq.clear();
758 unsigned StringLen = RS.Length;
759 LLVM_DEBUG(dbgs() << " Sequence length: " << StringLen << "\n");
760 // Debug code to keep track of how many candidates we removed.
761#ifndef NDEBUG
762 unsigned NumDiscarded = 0;
763 unsigned NumKept = 0;
764#endif
765 // Sort the start indices so that we can efficiently check if candidates
766 // overlap with the ones we've already found for this sequence.
767 llvm::sort(RS.StartIndices);
768 for (const unsigned &StartIdx : RS.StartIndices) {
769 // Trick: Discard some candidates that would be incompatible with the
770 // ones we've already found for this sequence. This will save us some
771 // work in candidate selection.
772 //
773 // If two candidates overlap, then we can't outline them both. This
774 // happens when we have candidates that look like, say
775 //
776 // AA (where each "A" is an instruction).
777 //
778 // We might have some portion of the module that looks like this:
779 // AAAAAA (6 A's)
780 //
781 // In this case, there are 5 different copies of "AA" in this range, but
782 // at most 3 can be outlined. If only outlining 3 of these is going to
783 // be unbeneficial, then we ought to not bother.
784 //
785 // Note that two things DON'T overlap when they look like this:
786 // start1...end1 .... start2...end2
787 // That is, one must either
788 // * End before the other starts
789 // * Start after the other ends
790 unsigned EndIdx = StartIdx + StringLen - 1;
791 if (!CandidatesForRepeatedSeq.empty() &&
792 StartIdx <= CandidatesForRepeatedSeq.back().getEndIdx()) {
793#ifndef NDEBUG
794 ++NumDiscarded;
795 LLVM_DEBUG(dbgs() << " .. DISCARD candidate @ [" << StartIdx << ", "
796 << EndIdx << "]; overlaps with candidate @ ["
797 << CandidatesForRepeatedSeq.back().getStartIdx()
798 << ", " << CandidatesForRepeatedSeq.back().getEndIdx()
799 << "]\n");
800#endif
801 continue;
802 }
803 // It doesn't overlap with anything, so we can outline it.
804 // Each sequence is over [StartIt, EndIt].
805 // Save the candidate and its location.
806#ifndef NDEBUG
807 ++NumKept;
808#endif
809 MachineBasicBlock::iterator StartIt = Mapper.InstrList[StartIdx];
810 MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
811 MachineBasicBlock *MBB = StartIt->getParent();
812 CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen, StartIt, EndIt,
813 MBB, FunctionList.size(),
814 Mapper.MBBFlagsMap[MBB]);
815 }
816#ifndef NDEBUG
817 LLVM_DEBUG(dbgs() << " Candidates discarded: " << NumDiscarded
818 << "\n");
819 LLVM_DEBUG(dbgs() << " Candidates kept: " << NumKept << "\n\n");
820#endif
821 unsigned MinRepeats = 2;
822
823 // We've found something we might want to outline.
824 // Create an OutlinedFunction to store it and check if it'd be beneficial
825 // to outline.
826 if (CandidatesForRepeatedSeq.size() < MinRepeats)
827 continue;
828
829 // Arbitrarily choose a TII from the first candidate.
830 // FIXME: Should getOutliningCandidateInfo move to TargetMachine?
831 const TargetInstrInfo *TII =
832 CandidatesForRepeatedSeq[0].getMF()->getSubtarget().getInstrInfo();
833
834 std::optional<std::unique_ptr<OutlinedFunction>> OF =
835 TII->getOutliningCandidateInfo(*MMI, CandidatesForRepeatedSeq,
836 MinRepeats);
837
838 // If we deleted too many candidates, then there's nothing worth outlining.
839 // FIXME: This should take target-specified instruction sizes into account.
840 if (!OF.has_value() || OF.value()->Candidates.size() < MinRepeats)
841 continue;
842
843 // Is it better to outline this candidate than not?
844 if (OF.value()->getBenefit() < OutlinerBenefitThreshold) {
845 emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq,
846 *OF.value());
847 continue;
848 }
849
850 FunctionList.emplace_back(std::move(OF.value()));
851 }
852}
853
854void MachineOutliner::computeAndPublishHashSequence(MachineFunction &MF,
855 unsigned CandSize) {
856 // Compute the hash sequence for the outlined function.
857 SmallVector<stable_hash> OutlinedHashSequence;
858 for (auto &MBB : MF) {
859 for (auto &NewMI : MBB) {
860 stable_hash Hash = stableHashValue(NewMI);
861 if (!Hash) {
862 OutlinedHashSequence.clear();
863 break;
864 }
865 OutlinedHashSequence.push_back(Hash);
866 }
867 }
868
869 // Append a unique name based on the non-empty hash sequence.
870 if (AppendContentHashToOutlinedName && !OutlinedHashSequence.empty()) {
871 auto CombinedHash = stable_hash_combine(OutlinedHashSequence);
872 auto NewName =
873 MF.getName().str() + ".content." + std::to_string(CombinedHash);
874 MF.getFunction().setName(NewName);
875 }
876
877 // Publish the non-empty hash sequence to the local hash tree.
878 if (OutlinerMode == CGDataMode::Write) {
879 StableHashAttempts++;
880 if (!OutlinedHashSequence.empty())
881 LocalHashTree->insert({OutlinedHashSequence, CandSize});
882 else
883 StableHashDropped++;
884 }
885}
886
887MachineFunction *MachineOutliner::createOutlinedFunction(
888 Module &M, OutlinedFunction &OF, InstructionMapper &Mapper, unsigned Name) {
889
890 // Create the function name. This should be unique.
891 // FIXME: We should have a better naming scheme. This should be stable,
892 // regardless of changes to the outliner's cost model/traversal order.
893 std::string FunctionName = "OUTLINED_FUNCTION_";
894 if (OutlineRepeatedNum > 0)
895 FunctionName += std::to_string(OutlineRepeatedNum + 1) + "_";
896 FunctionName += std::to_string(Name);
897 LLVM_DEBUG(dbgs() << "NEW FUNCTION: " << FunctionName << "\n");
898
899 // Create the function using an IR-level function.
900 LLVMContext &C = M.getContext();
901 Function *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
902 Function::ExternalLinkage, FunctionName, M);
903
904 // NOTE: If this is linkonceodr, then we can take advantage of linker deduping
905 // which gives us better results when we outline from linkonceodr functions.
906 F->setLinkage(GlobalValue::InternalLinkage);
907 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
908
909 // Set optsize/minsize, so we don't insert padding between outlined
910 // functions.
911 F->addFnAttr(Attribute::OptimizeForSize);
912 F->addFnAttr(Attribute::MinSize);
913
914 Candidate &FirstCand = OF.Candidates.front();
915 const TargetInstrInfo &TII =
916 *FirstCand.getMF()->getSubtarget().getInstrInfo();
917
918 TII.mergeOutliningCandidateAttributes(*F, OF.Candidates);
919
920 // Set uwtable, so we generate eh_frame.
921 UWTableKind UW = std::accumulate(
922 OF.Candidates.cbegin(), OF.Candidates.cend(), UWTableKind::None,
923 [](UWTableKind K, const outliner::Candidate &C) {
924 return std::max(K, C.getMF()->getFunction().getUWTableKind());
925 });
926 F->setUWTableKind(UW);
927
928 BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F);
929 IRBuilder<> Builder(EntryBB);
930 Builder.CreateRetVoid();
931
932 MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
934 MF.setIsOutlined(true);
936
937 // Insert the new function into the module.
938 MF.insert(MF.begin(), &MBB);
939
940 MachineFunction *OriginalMF = FirstCand.front().getMF();
941 const std::vector<MCCFIInstruction> &Instrs =
942 OriginalMF->getFrameInstructions();
943 for (auto &MI : FirstCand) {
944 if (MI.isDebugInstr())
945 continue;
946
947 // Don't keep debug information for outlined instructions.
948 auto DL = DebugLoc();
949 if (MI.isCFIInstruction()) {
950 unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
951 MCCFIInstruction CFI = Instrs[CFIIndex];
952 BuildMI(MBB, MBB.end(), DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
953 .addCFIIndex(MF.addFrameInst(CFI));
954 } else {
955 MachineInstr &NewMI = TII.duplicate(MBB, MBB.end(), MI);
956 NewMI.dropMemRefs(MF);
957 NewMI.setDebugLoc(DL);
958 }
959 }
960
961 if (OutlinerMode != CGDataMode::None)
962 computeAndPublishHashSequence(MF, OF.Candidates.size());
963
964 // Set normal properties for a late MachineFunction.
965 MF.getProperties().reset(MachineFunctionProperties::Property::IsSSA);
966 MF.getProperties().set(MachineFunctionProperties::Property::NoPHIs);
967 MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
968 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness);
970
971 // Compute live-in set for outlined fn
972 const MachineRegisterInfo &MRI = MF.getRegInfo();
973 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
974 LivePhysRegs LiveIns(TRI);
975 for (auto &Cand : OF.Candidates) {
976 // Figure out live-ins at the first instruction.
977 MachineBasicBlock &OutlineBB = *Cand.front().getParent();
978 LivePhysRegs CandLiveIns(TRI);
979 CandLiveIns.addLiveOuts(OutlineBB);
980 for (const MachineInstr &MI :
981 reverse(make_range(Cand.begin(), OutlineBB.end())))
982 CandLiveIns.stepBackward(MI);
983
984 // The live-in set for the outlined function is the union of the live-ins
985 // from all the outlining points.
986 for (MCPhysReg Reg : CandLiveIns)
987 LiveIns.addReg(Reg);
988 }
989 addLiveIns(MBB, LiveIns);
990
991 TII.buildOutlinedFrame(MBB, MF, OF);
992
993 // If there's a DISubprogram associated with this outlined function, then
994 // emit debug info for the outlined function.
995 if (DISubprogram *SP = getSubprogramOrNull(OF)) {
996 // We have a DISubprogram. Get its DICompileUnit.
997 DICompileUnit *CU = SP->getUnit();
998 DIBuilder DB(M, true, CU);
999 DIFile *Unit = SP->getFile();
1000 Mangler Mg;
1001 // Get the mangled name of the function for the linkage name.
1002 std::string Dummy;
1003 raw_string_ostream MangledNameStream(Dummy);
1004 Mg.getNameWithPrefix(MangledNameStream, F, false);
1005
1006 DISubprogram *OutlinedSP = DB.createFunction(
1007 Unit /* Context */, F->getName(), StringRef(Dummy), Unit /* File */,
1008 0 /* Line 0 is reserved for compiler-generated code. */,
1009 DB.createSubroutineType(DB.getOrCreateTypeArray({})), /* void type */
1010 0, /* Line 0 is reserved for compiler-generated code. */
1011 DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
1012 /* Outlined code is optimized code by definition. */
1013 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
1014
1015 // Don't add any new variables to the subprogram.
1016 DB.finalizeSubprogram(OutlinedSP);
1017
1018 // Attach subprogram to the function.
1019 F->setSubprogram(OutlinedSP);
1020 // We're done with the DIBuilder.
1021 DB.finalize();
1022 }
1023
1024 return &MF;
1025}
1026
1027bool MachineOutliner::outline(
1028 Module &M, std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList,
1029 InstructionMapper &Mapper, unsigned &OutlinedFunctionNum) {
1030 LLVM_DEBUG(dbgs() << "*** Outlining ***\n");
1031 LLVM_DEBUG(dbgs() << "NUMBER OF POTENTIAL FUNCTIONS: " << FunctionList.size()
1032 << "\n");
1033 bool OutlinedSomething = false;
1034
1035 // Sort by priority where priority := getNotOutlinedCost / getOutliningCost.
1036 // The function with highest priority should be outlined first.
1037 stable_sort(FunctionList, [](const std::unique_ptr<OutlinedFunction> &LHS,
1038 const std::unique_ptr<OutlinedFunction> &RHS) {
1039 return LHS->getNotOutlinedCost() * RHS->getOutliningCost() >
1040 RHS->getNotOutlinedCost() * LHS->getOutliningCost();
1041 });
1042
1043 // Walk over each function, outlining them as we go along. Functions are
1044 // outlined greedily, based off the sort above.
1045 auto *UnsignedVecBegin = Mapper.UnsignedVec.begin();
1046 LLVM_DEBUG(dbgs() << "WALKING FUNCTION LIST\n");
1047 for (auto &OF : FunctionList) {
1048#ifndef NDEBUG
1049 auto NumCandidatesBefore = OF->Candidates.size();
1050#endif
1051 // If we outlined something that overlapped with a candidate in a previous
1052 // step, then we can't outline from it.
1053 erase_if(OF->Candidates, [&UnsignedVecBegin](Candidate &C) {
1054 return std::any_of(UnsignedVecBegin + C.getStartIdx(),
1055 UnsignedVecBegin + C.getEndIdx() + 1, [](unsigned I) {
1056 return I == static_cast<unsigned>(-1);
1057 });
1058 });
1059
1060#ifndef NDEBUG
1061 auto NumCandidatesAfter = OF->Candidates.size();
1062 LLVM_DEBUG(dbgs() << "PRUNED: " << NumCandidatesBefore - NumCandidatesAfter
1063 << "/" << NumCandidatesBefore << " candidates\n");
1064#endif
1065
1066 // If we made it unbeneficial to outline this function, skip it.
1068 LLVM_DEBUG(dbgs() << "SKIP: Expected benefit (" << OF->getBenefit()
1069 << " B) < threshold (" << OutlinerBenefitThreshold
1070 << " B)\n");
1071 continue;
1072 }
1073
1074 LLVM_DEBUG(dbgs() << "OUTLINE: Expected benefit (" << OF->getBenefit()
1075 << " B) > threshold (" << OutlinerBenefitThreshold
1076 << " B)\n");
1077
1078 // It's beneficial. Create the function and outline its sequence's
1079 // occurrences.
1080 OF->MF = createOutlinedFunction(M, *OF, Mapper, OutlinedFunctionNum);
1081 emitOutlinedFunctionRemark(*OF);
1082 FunctionsCreated++;
1083 OutlinedFunctionNum++; // Created a function, move to the next name.
1084 MachineFunction *MF = OF->MF;
1085 const TargetSubtargetInfo &STI = MF->getSubtarget();
1086 const TargetInstrInfo &TII = *STI.getInstrInfo();
1087
1088 // Replace occurrences of the sequence with calls to the new function.
1089 LLVM_DEBUG(dbgs() << "CREATE OUTLINED CALLS\n");
1090 for (Candidate &C : OF->Candidates) {
1091 MachineBasicBlock &MBB = *C.getMBB();
1092 MachineBasicBlock::iterator StartIt = C.begin();
1093 MachineBasicBlock::iterator EndIt = std::prev(C.end());
1094
1095 // Insert the call.
1096 auto CallInst = TII.insertOutlinedCall(M, MBB, StartIt, *MF, C);
1097// Insert the call.
1098#ifndef NDEBUG
1099 auto MBBBeingOutlinedFromName =
1100 MBB.getName().empty() ? "<unknown>" : MBB.getName().str();
1101 auto MFBeingOutlinedFromName = MBB.getParent()->getName().empty()
1102 ? "<unknown>"
1103 : MBB.getParent()->getName().str();
1104 LLVM_DEBUG(dbgs() << " CALL: " << MF->getName() << " in "
1105 << MFBeingOutlinedFromName << ":"
1106 << MBBBeingOutlinedFromName << "\n");
1107 LLVM_DEBUG(dbgs() << " .. " << *CallInst);
1108#endif
1109
1110 // If the caller tracks liveness, then we need to make sure that
1111 // anything we outline doesn't break liveness assumptions. The outlined
1112 // functions themselves currently don't track liveness, but we should
1113 // make sure that the ranges we yank things out of aren't wrong.
1115 MachineFunctionProperties::Property::TracksLiveness)) {
1116 // The following code is to add implicit def operands to the call
1117 // instruction. It also updates call site information for moved
1118 // code.
1119 SmallSet<Register, 2> UseRegs, DefRegs;
1120 // Copy over the defs in the outlined range.
1121 // First inst in outlined range <-- Anything that's defined in this
1122 // ... .. range has to be added as an
1123 // implicit Last inst in outlined range <-- def to the call
1124 // instruction. Also remove call site information for outlined block
1125 // of code. The exposed uses need to be copied in the outlined range.
1127 Iter = EndIt.getReverse(),
1128 Last = std::next(CallInst.getReverse());
1129 Iter != Last; Iter++) {
1130 MachineInstr *MI = &*Iter;
1131 SmallSet<Register, 2> InstrUseRegs;
1132 for (MachineOperand &MOP : MI->operands()) {
1133 // Skip over anything that isn't a register.
1134 if (!MOP.isReg())
1135 continue;
1136
1137 if (MOP.isDef()) {
1138 // Introduce DefRegs set to skip the redundant register.
1139 DefRegs.insert(MOP.getReg());
1140 if (UseRegs.count(MOP.getReg()) &&
1141 !InstrUseRegs.count(MOP.getReg()))
1142 // Since the regiester is modeled as defined,
1143 // it is not necessary to be put in use register set.
1144 UseRegs.erase(MOP.getReg());
1145 } else if (!MOP.isUndef()) {
1146 // Any register which is not undefined should
1147 // be put in the use register set.
1148 UseRegs.insert(MOP.getReg());
1149 InstrUseRegs.insert(MOP.getReg());
1150 }
1151 }
1152 if (MI->isCandidateForCallSiteEntry())
1153 MI->getMF()->eraseCallSiteInfo(MI);
1154 }
1155
1156 for (const Register &I : DefRegs)
1157 // If it's a def, add it to the call instruction.
1158 CallInst->addOperand(
1159 MachineOperand::CreateReg(I, true, /* isDef = true */
1160 true /* isImp = true */));
1161
1162 for (const Register &I : UseRegs)
1163 // If it's a exposed use, add it to the call instruction.
1164 CallInst->addOperand(
1165 MachineOperand::CreateReg(I, false, /* isDef = false */
1166 true /* isImp = true */));
1167 }
1168
1169 // Erase from the point after where the call was inserted up to, and
1170 // including, the final instruction in the sequence.
1171 // Erase needs one past the end, so we need std::next there too.
1172 MBB.erase(std::next(StartIt), std::next(EndIt));
1173
1174 // Keep track of what we removed by marking them all as -1.
1175 for (unsigned &I : make_range(UnsignedVecBegin + C.getStartIdx(),
1176 UnsignedVecBegin + C.getEndIdx() + 1))
1177 I = static_cast<unsigned>(-1);
1178 OutlinedSomething = true;
1179
1180 // Statistics.
1181 NumOutlined++;
1182 }
1183 }
1184
1185 LLVM_DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n");
1186 return OutlinedSomething;
1187}
1188
1189void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
1190 // Build instruction mappings for each function in the module. Start by
1191 // iterating over each Function in M.
1192 LLVM_DEBUG(dbgs() << "*** Populating mapper ***\n");
1193 for (Function &F : M) {
1194 LLVM_DEBUG(dbgs() << "MAPPING FUNCTION: " << F.getName() << "\n");
1195
1196 if (F.hasFnAttribute("nooutline")) {
1197 LLVM_DEBUG(dbgs() << "SKIP: Function has nooutline attribute\n");
1198 continue;
1199 }
1200
1201 // There's something in F. Check if it has a MachineFunction associated with
1202 // it.
1204
1205 // If it doesn't, then there's nothing to outline from. Move to the next
1206 // Function.
1207 if (!MF) {
1208 LLVM_DEBUG(dbgs() << "SKIP: Function does not have a MachineFunction\n");
1209 continue;
1210 }
1211
1213 if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault(*MF)) {
1214 LLVM_DEBUG(dbgs() << "SKIP: Target does not want to outline from "
1215 "function by default\n");
1216 continue;
1217 }
1218
1219 // We have a MachineFunction. Ask the target if it's suitable for outlining.
1220 // If it isn't, then move on to the next Function in the module.
1221 if (!TII->isFunctionSafeToOutlineFrom(*MF, OutlineFromLinkOnceODRs)) {
1222 LLVM_DEBUG(dbgs() << "SKIP: " << MF->getName()
1223 << ": unsafe to outline from\n");
1224 continue;
1225 }
1226
1227 // We have a function suitable for outlining. Iterate over every
1228 // MachineBasicBlock in MF and try to map its instructions to a list of
1229 // unsigned integers.
1230 const unsigned MinMBBSize = 2;
1231
1232 for (MachineBasicBlock &MBB : *MF) {
1233 LLVM_DEBUG(dbgs() << " MAPPING MBB: '" << MBB.getName() << "'\n");
1234 // If there isn't anything in MBB, then there's no point in outlining from
1235 // it.
1236 // If there are fewer than 2 instructions in the MBB, then it can't ever
1237 // contain something worth outlining.
1238 // FIXME: This should be based off of the maximum size in B of an outlined
1239 // call versus the size in B of the MBB.
1240 if (MBB.size() < MinMBBSize) {
1241 LLVM_DEBUG(dbgs() << " SKIP: MBB size less than minimum size of "
1242 << MinMBBSize << "\n");
1243 continue;
1244 }
1245
1246 // Check if MBB could be the target of an indirect branch. If it is, then
1247 // we don't want to outline from it.
1248 if (MBB.hasAddressTaken()) {
1249 LLVM_DEBUG(dbgs() << " SKIP: MBB's address is taken\n");
1250 continue;
1251 }
1252
1253 // MBB is suitable for outlining. Map it to a list of unsigneds.
1254 Mapper.convertToUnsignedVec(MBB, *TII);
1255 }
1256 }
1257 // Statistics.
1258 UnsignedVecSize = Mapper.UnsignedVec.size();
1259}
1260
1261void MachineOutliner::initSizeRemarkInfo(
1262 const Module &M, StringMap<unsigned> &FunctionToInstrCount) {
1263 // Collect instruction counts for every function. We'll use this to emit
1264 // per-function size remarks later.
1265 for (const Function &F : M) {
1267
1268 // We only care about MI counts here. If there's no MachineFunction at this
1269 // point, then there won't be after the outliner runs, so let's move on.
1270 if (!MF)
1271 continue;
1272 FunctionToInstrCount[F.getName().str()] = MF->getInstructionCount();
1273 }
1274}
1275
1276void MachineOutliner::emitInstrCountChangedRemark(
1277 const Module &M, const StringMap<unsigned> &FunctionToInstrCount) {
1278 // Iterate over each function in the module and emit remarks.
1279 // Note that we won't miss anything by doing this, because the outliner never
1280 // deletes functions.
1281 for (const Function &F : M) {
1283
1284 // The outliner never deletes functions. If we don't have a MF here, then we
1285 // didn't have one prior to outlining either.
1286 if (!MF)
1287 continue;
1288
1289 std::string Fname = std::string(F.getName());
1290 unsigned FnCountAfter = MF->getInstructionCount();
1291 unsigned FnCountBefore = 0;
1292
1293 // Check if the function was recorded before.
1294 auto It = FunctionToInstrCount.find(Fname);
1295
1296 // Did we have a previously-recorded size? If yes, then set FnCountBefore
1297 // to that.
1298 if (It != FunctionToInstrCount.end())
1299 FnCountBefore = It->second;
1300
1301 // Compute the delta and emit a remark if there was a change.
1302 int64_t FnDelta = static_cast<int64_t>(FnCountAfter) -
1303 static_cast<int64_t>(FnCountBefore);
1304 if (FnDelta == 0)
1305 continue;
1306
1308 MORE.emit([&]() {
1309 MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
1310 DiagnosticLocation(), &MF->front());
1311 R << DiagnosticInfoOptimizationBase::Argument("Pass", "Machine Outliner")
1312 << ": Function: "
1313 << DiagnosticInfoOptimizationBase::Argument("Function", F.getName())
1314 << ": MI instruction count changed from "
1315 << DiagnosticInfoOptimizationBase::Argument("MIInstrsBefore",
1316 FnCountBefore)
1317 << " to "
1319 FnCountAfter)
1320 << "; Delta: "
1321 << DiagnosticInfoOptimizationBase::Argument("Delta", FnDelta);
1322 return R;
1323 });
1324 }
1325}
1326
1327void MachineOutliner::initializeOutlinerMode(const Module &M) {
1329 return;
1330
1331 if (auto *IndexWrapperPass =
1332 getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>()) {
1333 auto *TheIndex = IndexWrapperPass->getIndex();
1334 // (Full)LTO module does not have functions added to the index.
1335 // In this case, we run the outliner without using codegen data as usual.
1336 if (TheIndex && !TheIndex->hasExportedFunctions(M))
1337 return;
1338 }
1339
1340 // When codegen data write is enabled, we want to write the local outlined
1341 // hash tree to the custom section, `__llvm_outline`.
1342 // When the outlined hash tree is available from the previous codegen data,
1343 // we want to read it to optimistically create global outlining candidates.
1344 if (cgdata::emitCGData()) {
1345 OutlinerMode = CGDataMode::Write;
1346 // Create a local outlined hash tree to be published.
1347 LocalHashTree = std::make_unique<OutlinedHashTree>();
1348 // We don't need to read the outlined hash tree from the previous codegen
1349 } else if (cgdata::hasOutlinedHashTree())
1350 OutlinerMode = CGDataMode::Read;
1351}
1352
1353void MachineOutliner::emitOutlinedHashTree(Module &M) {
1354 assert(LocalHashTree);
1355 if (!LocalHashTree->empty()) {
1356 LLVM_DEBUG({
1357 dbgs() << "Emit outlined hash tree. Size: " << LocalHashTree->size()
1358 << "\n";
1359 });
1362
1363 OutlinedHashTreeRecord HTR(std::move(LocalHashTree));
1364 HTR.serialize(OS);
1365
1366 llvm::StringRef Data(Buf.data(), Buf.size());
1367 std::unique_ptr<MemoryBuffer> Buffer =
1368 MemoryBuffer::getMemBuffer(Data, "in-memory outlined hash tree", false);
1369
1370 Triple TT(M.getTargetTriple());
1372 M, *Buffer,
1373 getCodeGenDataSectionName(CG_outline, TT.getObjectFormat()));
1374 }
1375}
1376
1377bool MachineOutliner::runOnModule(Module &M) {
1378 // Check if there's anything in the module. If it's empty, then there's
1379 // nothing to outline.
1380 if (M.empty())
1381 return false;
1382
1383 // Initialize the outliner mode.
1384 initializeOutlinerMode(M);
1385
1386 MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
1387
1388 // Number to append to the current outlined function.
1389 unsigned OutlinedFunctionNum = 0;
1390
1391 OutlineRepeatedNum = 0;
1392 if (!doOutline(M, OutlinedFunctionNum))
1393 return false;
1394
1395 for (unsigned I = 0; I < OutlinerReruns; ++I) {
1396 OutlinedFunctionNum = 0;
1397 OutlineRepeatedNum++;
1398 if (!doOutline(M, OutlinedFunctionNum)) {
1399 LLVM_DEBUG({
1400 dbgs() << "Did not outline on iteration " << I + 2 << " out of "
1401 << OutlinerReruns + 1 << "\n";
1402 });
1403 break;
1404 }
1405 }
1406
1407 if (OutlinerMode == CGDataMode::Write)
1408 emitOutlinedHashTree(M);
1409
1410 return true;
1411}
1412
1413bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) {
1414 // If the user passed -enable-machine-outliner=always or
1415 // -enable-machine-outliner, the pass will run on all functions in the module.
1416 // Otherwise, if the target supports default outlining, it will run on all
1417 // functions deemed by the target to be worth outlining from by default. Tell
1418 // the user how the outliner is running.
1419 LLVM_DEBUG({
1420 dbgs() << "Machine Outliner: Running on ";
1421 if (RunOnAllFunctions)
1422 dbgs() << "all functions";
1423 else
1424 dbgs() << "target-default functions";
1425 dbgs() << "\n";
1426 });
1427
1428 // If the user specifies that they want to outline from linkonceodrs, set
1429 // it here.
1430 OutlineFromLinkOnceODRs = EnableLinkOnceODROutlining;
1431 InstructionMapper Mapper(*MMI);
1432
1433 // Prepare instruction mappings for the suffix tree.
1434 populateMapper(Mapper, M);
1435 std::vector<std::unique_ptr<OutlinedFunction>> FunctionList;
1436
1437 // Find all of the outlining candidates.
1438 if (OutlinerMode == CGDataMode::Read)
1439 findGlobalCandidates(Mapper, FunctionList);
1440 else
1441 findCandidates(Mapper, FunctionList);
1442
1443 // If we've requested size remarks, then collect the MI counts of every
1444 // function before outlining, and the MI counts after outlining.
1445 // FIXME: This shouldn't be in the outliner at all; it should ultimately be
1446 // the pass manager's responsibility.
1447 // This could pretty easily be placed in outline instead, but because we
1448 // really ultimately *don't* want this here, it's done like this for now
1449 // instead.
1450
1451 // Check if we want size remarks.
1452 bool ShouldEmitSizeRemarks = M.shouldEmitInstrCountChangedRemark();
1453 StringMap<unsigned> FunctionToInstrCount;
1454 if (ShouldEmitSizeRemarks)
1455 initSizeRemarkInfo(M, FunctionToInstrCount);
1456
1457 // Outline each of the candidates and return true if something was outlined.
1458 bool OutlinedSomething =
1459 outline(M, FunctionList, Mapper, OutlinedFunctionNum);
1460
1461 // If we outlined something, we definitely changed the MI count of the
1462 // module. If we've asked for size remarks, then output them.
1463 // FIXME: This should be in the pass manager.
1464 if (ShouldEmitSizeRemarks && OutlinedSomething)
1465 emitInstrCountChangedRemark(M, FunctionToInstrCount);
1466
1467 LLVM_DEBUG({
1468 if (!OutlinedSomething)
1469 dbgs() << "Stopped outlining at iteration " << OutlineRepeatedNum
1470 << " because no changes were found.\n";
1471 });
1472
1473 return OutlinedSomething;
1474}
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(...)
Definition: Debug.h:106
This file defines the DenseMap class.
std::string Name
uint64_t Size
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
Module.h This file contains the declarations for the Module class.
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< bool > DisableGlobalOutlining("disable-global-outlining", cl::Hidden, cl::desc("Disable global outlining only by ignoring " "the codegen data generation or use"), cl::init(false))
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< bool > AppendContentHashToOutlinedName("append-content-hash-outlined-name", cl::Hidden, cl::desc("This appends the content hash to the globally outlined function " "name. It's beneficial for enhancing the precision of the stable " "hash and for ordering the outlined functions."), cl::init(true))
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))
static SmallVector< MatchedEntry > getMatchedEntries(InstructionMapper &Mapper)
Contains all data structures shared between the outliner implemented in MachineOutliner....
unsigned const TargetRegisterInfo * TRI
This is the interface to build a ModuleSummaryIndex for a module.
static Expected< 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())
raw_pwrite_stream & OS
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:166
Value * RHS
Value * LHS
Represent the analysis usage information of a pass.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this 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:212
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:211
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:173
@ 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:2697
Legacy wrapper pass to provide the ModuleSummaryIndex object.
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
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.
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:347
bool isDebugInstr() const
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:121
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
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
const HashNode * getRoot() const
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:132
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:175
bool erase(const T &V)
Definition: SmallSet.h:193
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:181
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
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:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
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
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
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
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
@ 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
SmallVector< MachineInstr * > InstrList
bool hasOutlinedHashTree()
Definition: CodeGenData.h:171
const OutlinedHashTree * getOutlinedHashTree()
Definition: CodeGenData.h:179
bool emitCGData()
Definition: CodeGenData.h:187
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
@ Length
Definition: DWP.cpp:480
void stable_sort(R &&Range)
Definition: STLExtras.h:2037
CGDataMode
Definition: CodeGenData.h:105
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:2115
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
UWTableKind
Definition: CodeGen.h:120
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1664
stable_hash stableHashValue(const MachineOperand &MO)
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:2099
stable_hash stable_hash_combine(ArrayRef< stable_hash > Buffer)
Definition: StableHashing.h:30
void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName, Align Alignment=Align(1))
Embed the memory buffer Buf into the module M as a global using the specified section name.
void addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs)
Adds registers contained in LiveRegs to the block live-in list of MBB.
std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define MORE()
Definition: regcomp.c:252
MatchedEntry()=delete
MatchedEntry(unsigned StartIdx, unsigned EndIdx, unsigned Count)
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 HashNode is an entry in an OutlinedHashTree, holding a hash value and a collection of Successors (o...
std::optional< unsigned > Terminals
The number of terminals in the sequence ending at this node.
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.
virtual unsigned getOccurrenceCount() const
Return the number of candidates for this OutlinedFunction.
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.
std::vector< Candidate > Candidates