LLVM: lib/CodeGen/MachineOutliner.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
85#include
86#include
87
88#define DEBUG_TYPE "machine-outliner"
89
90using namespace llvm;
91using namespace ore;
93
94
95STATISTIC(NumOutlined, "Number of candidates outlined");
96STATISTIC(FunctionsCreated, "Number of functions created");
97
98
99STATISTIC(NumLegalInUnsignedVec, "Outlinable instructions mapped");
101 "Unoutlinable instructions mapped + number of sentinel values");
102STATISTIC(NumSentinels, "Sentinel values inserted during mapping");
104 "Invisible instructions skipped during mapping");
106 "Total number of instructions mapped and saved to mapping vector");
108 "Count of hashing attempts made for outlined functions");
110 "Count of unsuccessful hashing attempts for outlined functions");
111STATISTIC(NumRemovedLOHs, "Total number of Linker Optimization Hints removed");
113 "Number of times outlining was blocked by PGO");
115 "Number of times outlining was allowed from cold functions");
117 "Number of times outlining was blocked conservatively when profile "
118 "counts were missing");
120 "Number of times outlining was allowed optimistically when profile "
121 "counts were missing");
122
123
124
125
126
127
129 "enable-linkonceodr-outlining", cl::Hidden,
130 cl::desc("Enable the machine outliner on linkonceodr functions"),
132
133
134
135
139 "Number of times to rerun the outliner after the initial outline"));
140
144 "The minimum size in bytes before an outlining candidate is accepted"));
145
148 cl::desc("Consider all leaf descendants of internal nodes of the suffix "
149 "tree as candidates for outlining (if false, only leaf children "
150 "are considered)"));
151
154 cl::desc("Disable global outlining only by ignoring "
155 "the codegen data generation or use"),
157
159 "append-content-hash-outlined-name", cl::Hidden,
160 cl::desc("This appends the content hash to the globally outlined function "
161 "name. It's beneficial for enhancing the precision of the stable "
162 "hash and for ordering the outlined functions."),
164
165namespace {
166
167
168struct InstructionMapper {
170
171
172
173
174
175 unsigned IllegalInstrNumber = -3;
176
177
178
179 unsigned LegalInstrNumber = 0;
180
181
183 InstructionIntegerMap;
184
185
187
188
190
191
192
194
195
196
197
198
199 bool AddedIllegalLastTime = false;
200
201
202
203
204
205
206
207 unsigned mapToLegalUnsigned(
209 bool &HaveLegalRange, unsigned &NumLegalInBlock,
212
213
214 AddedIllegalLastTime = false;
215
216
217
218 if (CanOutlineWithPrevInstr)
219 HaveLegalRange = true;
220 CanOutlineWithPrevInstr = true;
221
222
223 NumLegalInBlock++;
224
225
226
229 bool WasInserted;
231 ResultIt;
232 std::tie(ResultIt, WasInserted) =
233 InstructionIntegerMap.insert(std::make_pair(&MI, LegalInstrNumber));
234 unsigned MINumber = ResultIt->second;
235
236
237 if (WasInserted)
238 LegalInstrNumber++;
239
240 UnsignedVecForMBB.push_back(MINumber);
241
242
243 if (LegalInstrNumber >= IllegalInstrNumber)
245
247 "Tried to assign DenseMap tombstone or empty key to instruction.");
249 "Tried to assign DenseMap tombstone or empty key to instruction.");
250
251
252 ++NumLegalInUnsignedVec;
253 return MINumber;
254 }
255
256
257
258
259
260
261
262 unsigned mapToIllegalUnsigned(
264 SmallVector &UnsignedVecForMBB,
266
267 CanOutlineWithPrevInstr = false;
268
269
270 if (AddedIllegalLastTime)
271 return IllegalInstrNumber;
272
273
274 AddedIllegalLastTime = true;
275 unsigned MINumber = IllegalInstrNumber;
276
278 UnsignedVecForMBB.push_back(IllegalInstrNumber);
279 IllegalInstrNumber--;
280
281 ++NumIllegalInUnsignedVec;
282
283 assert(LegalInstrNumber < IllegalInstrNumber &&
284 "Instruction mapping overflow!");
285
286 assert(IllegalInstrNumber != DenseMapInfo::getEmptyKey() &&
287 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
288
289 assert(IllegalInstrNumber != DenseMapInfo::getTombstoneKey() &&
290 "IllegalInstrNumber cannot be DenseMap tombstone or empty key!");
291
292 return MINumber;
293 }
294
295
296
297
298
299
300
301
302
303
304
305 void convertToUnsignedVec(MachineBasicBlock &MBB,
306 const TargetInstrInfo &TII) {
308 << "' to unsigned vector ***\n");
309 unsigned Flags = 0;
310
311
313 return;
314
317 << " outlinable range(s)\n");
318 if (OutlinableRanges.empty())
319 return;
320
321
323
325
326
327
328 unsigned NumLegalInBlock = 0;
329
330
331
332 bool HaveLegalRange = false;
333
334
335
336 bool CanOutlineWithPrevInstr = false;
337
338
339
340 SmallVector UnsignedVecForMBB;
342
343 LLVM_DEBUG(dbgs() << "*** Mapping outlinable ranges ***\n");
344 for (auto &OutlinableRange : OutlinableRanges) {
345 auto OutlinableRangeBegin = OutlinableRange.first;
346 auto OutlinableRangeEnd = OutlinableRange.second;
347#ifndef NDEBUG
349 dbgs() << "Mapping "
350 << std::distance(OutlinableRangeBegin, OutlinableRangeEnd)
351 << " instruction range\n");
352
353 unsigned NumSkippedInRange = 0;
354#endif
355 for (; It != OutlinableRangeBegin; ++It) {
356#ifndef NDEBUG
357 ++NumSkippedInRange;
358#endif
359 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
360 InstrListForMBB);
361 }
362#ifndef NDEBUG
364 << " instructions outside outlinable range\n");
365#endif
366 assert(It != MBB.end() && "Should still have instructions?");
367
368
369 for (; It != OutlinableRangeEnd; ++It) {
370
372 case InstrType::Illegal:
373 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
374 InstrListForMBB);
375 break;
376
377 case InstrType::Legal:
378 mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
379 NumLegalInBlock, UnsignedVecForMBB,
380 InstrListForMBB);
381 break;
382
383 case InstrType::LegalTerminator:
384 mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
385 NumLegalInBlock, UnsignedVecForMBB,
386 InstrListForMBB);
387
388
389 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
390 InstrListForMBB);
391 break;
392
393 case InstrType::Invisible:
394
395
396 ++NumInvisible;
397 AddedIllegalLastTime = false;
398 break;
399 }
400 }
401 }
402
403 LLVM_DEBUG(dbgs() << "HaveLegalRange = " << HaveLegalRange << "\n");
404
405
406
407 if (HaveLegalRange) {
408
409
410
411
412 mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
413 InstrListForMBB);
414 ++NumSentinels;
416 append_range(UnsignedVec, UnsignedVecForMBB);
417 }
418 }
419
420 InstructionMapper(const MachineModuleInfo &MMI_) : MMI(MMI_) {
421
422
423 static_assert(DenseMapInfo::getEmptyKey() ==
424 static_cast<unsigned>(-1));
425 static_assert(DenseMapInfo::getTombstoneKey() ==
426 static_cast<unsigned>(-2));
427 }
428};
429
430
431
432
433
434
435
436
437
438
439struct MachineOutliner : public ModulePass {
440
441 static char ID;
442
443 MachineModuleInfo *MMI = nullptr;
444 const TargetMachine *TM = nullptr;
445
446
447
448 bool OutlineFromLinkOnceODRs = false;
449
450
451 unsigned OutlineRepeatedNum = 0;
452
453
454
455
456 RunOutliner RunOutlinerMode = RunOutliner::AlwaysOutline;
457
458
459
460
461
462
463
464 std::unique_ptr LocalHashTree;
465
466
467
468
469
470
471
472
473 CGDataMode OutlinerMode = CGDataMode::None;
474
475 StringRef getPassName() const override { return "Machine Outliner"; }
476
477 void getAnalysisUsage(AnalysisUsage &AU) const override {
478 AU.addRequired();
480 AU.addPreserved();
482 if (RunOutlinerMode == RunOutliner::OptimisticPGO ||
483 RunOutlinerMode == RunOutliner::ConservativePGO) {
484 AU.addRequired();
485 AU.addRequired();
486 }
488 ModulePass::getAnalysisUsage(AU);
489 }
490
491 MachineOutliner() : ModulePass(ID) {
493 }
494
495
496
497 void emitNotOutliningCheaperRemark(
498 unsigned StringLen, std::vector &CandidatesForRepeatedSeq,
499 OutlinedFunction &OF);
500
501
502 void emitOutlinedFunctionRemark(OutlinedFunction &OF);
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517 void
518 findCandidates(InstructionMapper &Mapper,
519 std::vector<std::unique_ptr> &FunctionList);
520
521
522
523
524
525
526
527 void findGlobalCandidates(
528 InstructionMapper &Mapper,
529 std::vector<std::unique_ptr> &FunctionList);
530
531
532
533
534
535
536
537
538 bool outline(Module &M,
539 std::vector<std::unique_ptr> &FunctionList,
540 InstructionMapper &Mapper, unsigned &OutlinedFunctionNum);
541
542
544 InstructionMapper &Mapper,
545 unsigned Name);
546
547
548
549
550 void computeAndPublishHashSequence(MachineFunction &MF, unsigned CandSize);
551
552
553 void initializeOutlinerMode(const Module &M);
554
555
556 void emitOutlinedHashTree(Module &M);
557
558
559 bool runOnModule(Module &M) override;
560
561
562
563 bool doOutline(Module &M, unsigned &OutlinedFunctionNum);
564
565
566
568 for (const Candidate &C : OF.Candidates)
569 if (MachineFunction *MF = C.getMF())
570 if (DISubprogram *SP = MF->getFunction().getSubprogram())
571 return SP;
572 return nullptr;
573 }
574
575
576
577 void populateMapper(InstructionMapper &Mapper, Module &M);
578
579
580
581
582
583 void initSizeRemarkInfo(const Module &M,
584 StringMap &FunctionToInstrCount);
585
586
587
588 void
589 emitInstrCountChangedRemark(const Module &M,
590 const StringMap &FunctionToInstrCount);
591};
592}
593
594char MachineOutliner::ID = 0;
595
597 MachineOutliner *OL = new MachineOutliner();
598 OL->RunOutlinerMode = RunOutlinerMode;
599 return OL;
600}
601
603 false)
604
605void MachineOutliner::emitNotOutliningCheaperRemark(
606 unsigned StringLen, std::vector<Candidate> &CandidatesForRepeatedSeq,
608
609
610
611
612 Candidate &C = CandidatesForRepeatedSeq.front();
614 MORE.emit([&]() {
616 C.front().getDebugLoc(), C.getMBB());
617 R << "Did not outline " << NV("Length", StringLen) << " instructions"
618 << " from " << NV("NumOccurrences", CandidatesForRepeatedSeq.size())
619 << " locations."
620 << " Bytes from outlining all occurrences ("
621 << NV("OutliningCost", OF.getOutliningCost()) << ")"
622 << " >= Unoutlined instruction bytes ("
623 << NV("NotOutliningCost", OF.getNotOutlinedCost()) << ")"
624 << " (Also found at: ";
625
626
627 for (unsigned i = 1, e = CandidatesForRepeatedSeq.size(); i < e; i++) {
628 R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
629 CandidatesForRepeatedSeq[i].front().getDebugLoc());
630 if (i != e - 1)
631 R << ", ";
632 }
633
634 R << ")";
635 return R;
636 });
637}
638
639void MachineOutliner::emitOutlinedFunctionRemark(OutlinedFunction &OF) {
640 MachineBasicBlock *MBB = &*OF.MF->begin();
641 MachineOptimizationRemarkEmitter MORE(*OF.MF, nullptr);
642 MachineOptimizationRemark R(DEBUG_TYPE, "OutlinedFunction",
644 R << "Saved " << NV("OutliningBenefit", OF.getBenefit()) << " bytes by "
645 << "outlining " << NV("Length", OF.getNumInstrs()) << " instructions "
646 << "from " << NV("NumOccurrences", OF.getOccurrenceCount())
647 << " locations. "
648 << "(Found at: ";
649
650
651 for (size_t i = 0, e = OF.Candidates.size(); i < e; i++) {
652
653 R << NV((Twine("StartLoc") + Twine(i)).str(),
654 OF.Candidates[i].front().getDebugLoc());
655 if (i != e - 1)
656 R << ", ";
657 }
658
659 R << ")";
660
661 MORE.emit(R);
662}
663
672
673
674
675
677 auto &InstrList = Mapper.InstrList;
678 auto &UnsignedVec = Mapper.UnsignedVec;
679
681 auto Size = UnsignedVec.size();
682
683
686
687 auto getValidInstr = [&](unsigned Index) -> const MachineInstr * {
688 if (UnsignedVec[Index] >= Mapper.LegalInstrNumber)
689 return nullptr;
690 return &(*InstrList[Index]);
691 };
692
693 auto getStableHashAndFollow =
696 if (!StableHash)
697 return nullptr;
698 auto It = CurrNode->Successors.find(StableHash);
699 return (It == CurrNode->Successors.end()) ? nullptr : It->second.get();
700 };
701
702 for (unsigned I = 0; I < Size; ++I) {
704 if ( || MI->isDebugInstr())
705 continue;
706 const HashNode *CurrNode = getStableHashAndFollow(*MI, RootNode);
707 if (!CurrNode)
708 continue;
709
710 for (unsigned J = I + 1; J < Size; ++J) {
712 if (!MJ)
713 break;
714
716 continue;
717 CurrNode = getStableHashAndFollow(*MJ, CurrNode);
718 if (!CurrNode)
719 break;
720
721
724 }
725 }
726
727 return MatchedEntries;
728}
729
730void MachineOutliner::findGlobalCandidates(
731 InstructionMapper &Mapper,
732 std::vector<std::unique_ptr> &FunctionList) {
733 FunctionList.clear();
734 auto &InstrList = Mapper.InstrList;
735 auto &MBBFlagsMap = Mapper.MBBFlagsMap;
736
737 std::vector CandidatesForRepeatedSeq;
739 CandidatesForRepeatedSeq.clear();
742 auto Length = ME.EndIdx - ME.StartIdx + 1;
743 MachineBasicBlock *MBB = StartIt->getParent();
744 CandidatesForRepeatedSeq.emplace_back(ME.StartIdx, Length, StartIt, EndIt,
746 MBBFlagsMap[MBB]);
747 const TargetInstrInfo *TII =
749 unsigned MinRepeats = 1;
750 std::optional<std::unique_ptr> OF =
752 MinRepeats);
753 if (.has_value() || OF.value()->Candidates.empty())
754 continue;
755
756 assert(OF.value()->Candidates.size() == MinRepeats);
757 FunctionList.emplace_back(std::make_unique(
758 std::move(OF.value()), ME.Count));
759 }
760}
761
762void MachineOutliner::findCandidates(
763 InstructionMapper &Mapper,
764 std::vector<std::unique_ptr> &FunctionList) {
765 FunctionList.clear();
767
768
769
770 std::vector CandidatesForRepeatedSeq;
771 LLVM_DEBUG(dbgs() << "*** Discarding overlapping candidates *** \n");
773 dbgs() << "Searching for overlaps in all repeated sequences...\n");
774 for (SuffixTree::RepeatedSubstring &RS : ST) {
775 CandidatesForRepeatedSeq.clear();
776 unsigned StringLen = RS.Length;
777 LLVM_DEBUG(dbgs() << " Sequence length: " << StringLen << "\n");
778
779#ifndef NDEBUG
780 unsigned NumDiscarded = 0;
781 unsigned NumKept = 0;
782#endif
783
784
786 for (const unsigned &StartIdx : RS.StartIndices) {
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808 unsigned EndIdx = StartIdx + StringLen - 1;
809 if (!CandidatesForRepeatedSeq.empty() &&
810 StartIdx <= CandidatesForRepeatedSeq.back().getEndIdx()) {
811#ifndef NDEBUG
812 ++NumDiscarded;
813 LLVM_DEBUG(dbgs() << " .. DISCARD candidate @ [" << StartIdx << ", "
814 << EndIdx << "]; overlaps with candidate @ ["
815 << CandidatesForRepeatedSeq.back().getStartIdx()
816 << ", " << CandidatesForRepeatedSeq.back().getEndIdx()
817 << "]\n");
818#endif
819 continue;
820 }
821
822
823
824#ifndef NDEBUG
825 ++NumKept;
826#endif
829 MachineBasicBlock *MBB = StartIt->getParent();
830 CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen, StartIt, EndIt,
832 Mapper.MBBFlagsMap[MBB]);
833 }
834#ifndef NDEBUG
835 LLVM_DEBUG(dbgs() << " Candidates discarded: " << NumDiscarded
836 << "\n");
837 LLVM_DEBUG(dbgs() << " Candidates kept: " << NumKept << "\n\n");
838#endif
839 unsigned MinRepeats = 2;
840
841
842
843
844 if (CandidatesForRepeatedSeq.size() < MinRepeats)
845 continue;
846
847
848
849 const TargetInstrInfo *TII =
850 CandidatesForRepeatedSeq[0].getMF()->getSubtarget().getInstrInfo();
851
852 std::optional<std::unique_ptr> OF =
854 MinRepeats);
855
856
857
858 if (.has_value() || OF.value()->Candidates.size() < MinRepeats)
859 continue;
860
861
863 emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq,
864 *OF.value());
865 continue;
866 }
867
868 FunctionList.emplace_back(std::move(OF.value()));
869 }
870}
871
872void MachineOutliner::computeAndPublishHashSequence(MachineFunction &MF,
873 unsigned CandSize) {
874
875 SmallVector<stable_hash> OutlinedHashSequence;
876 for (auto &MBB : MF) {
877 for (auto &NewMI : MBB) {
879 if (!Hash) {
880 OutlinedHashSequence.clear();
881 break;
882 }
883 OutlinedHashSequence.push_back(Hash);
884 }
885 }
886
887
890 auto NewName =
891 MF.getName().str() + ".content." + std::to_string(CombinedHash);
892 MF.getFunction().setName(NewName);
893 }
894
895
896 if (OutlinerMode == CGDataMode::Write) {
897 StableHashAttempts++;
898 if (!OutlinedHashSequence.empty())
899 LocalHashTree->insert({OutlinedHashSequence, CandSize});
900 else
901 StableHashDropped++;
902 }
903}
904
905MachineFunction *MachineOutliner::createOutlinedFunction(
906 Module &M, OutlinedFunction &OF, InstructionMapper &Mapper, unsigned Name) {
907
908
909
910
911 std::string FunctionName = "OUTLINED_FUNCTION_";
912 if (OutlineRepeatedNum > 0)
913 FunctionName += std::to_string(OutlineRepeatedNum + 1) + "_";
914 FunctionName += std::to_string(Name);
915 LLVM_DEBUG(dbgs() << "NEW FUNCTION: " << FunctionName << "\n");
916
917
918 LLVMContext &C = M.getContext();
920 Function::ExternalLinkage, FunctionName, M);
921
922
923
925 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
926
927
928
929 F->addFnAttr(Attribute::OptimizeForSize);
930 F->addFnAttr(Attribute::MinSize);
931
932 Candidate &FirstCand = OF.Candidates.front();
933 const TargetInstrInfo &TII =
935
937
938
940 OF.Candidates.cbegin(), OF.Candidates.cend(), UWTableKind::None,
941 [](UWTableKind K, const outliner::Candidate &C) {
942 return std::max(K, C.getMF()->getFunction().getUWTableKind());
943 });
944 F->setUWTableKind(UW);
945
948 Builder.CreateRetVoid();
949
950 MachineModuleInfo &MMI = getAnalysis().getMMI();
954
955
957
958 MachineFunction *OriginalMF = FirstCand.front().getMF();
959 const std::vector &Instrs =
961 for (auto &MI : FirstCand) {
962 if (MI.isDebugInstr())
963 continue;
964
965
967 if (MI.isCFIInstruction()) {
968 unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
969 MCCFIInstruction CFI = Instrs[CFIIndex];
972 } else {
976 }
977 }
978
979 if (OutlinerMode != CGDataMode::None)
980 computeAndPublishHashSequence(MF, OF.Candidates.size());
981
982
988
989
990 const MachineRegisterInfo &MRI = MF.getRegInfo();
991 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
992 LivePhysRegs LiveIns(TRI);
993 for (auto &Cand : OF.Candidates) {
994
995 MachineBasicBlock &OutlineBB = *Cand.front().getParent();
996 LivePhysRegs CandLiveIns(TRI);
997 CandLiveIns.addLiveOuts(OutlineBB);
998 for (const MachineInstr &MI :
1000 CandLiveIns.stepBackward(MI);
1001
1002
1003
1005 LiveIns.addReg(Reg);
1006 }
1008
1010
1011
1012
1014
1015 DICompileUnit *CU = SP->getUnit();
1016 DIBuilder DB(M, true, CU);
1017 DIFile *Unit = SP->getFile();
1018 Mangler Mg;
1019
1020 std::string Dummy;
1021 raw_string_ostream MangledNameStream(Dummy);
1023
1024 DISubprogram *OutlinedSP = DB.createFunction(
1025 Unit , F->getName(), StringRef(Dummy), Unit ,
1026 0 ,
1027 DB.createSubroutineType(DB.getOrCreateTypeArray({})),
1028 0,
1029 DINode::DIFlags::FlagArtificial ,
1030
1031 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
1032
1033
1034 F->setSubprogram(OutlinedSP);
1035
1036 DB.finalize();
1037 }
1038
1039 return &MF;
1040}
1041
1042bool MachineOutliner::outline(
1043 Module &M, std::vector<std::unique_ptr> &FunctionList,
1044 InstructionMapper &Mapper, unsigned &OutlinedFunctionNum) {
1046 LLVM_DEBUG(dbgs() << "NUMBER OF POTENTIAL FUNCTIONS: " << FunctionList.size()
1047 << "\n");
1048 bool OutlinedSomething = false;
1049
1050
1051
1052 stable_sort(FunctionList, [](const std::unique_ptr &LHS,
1053 const std::unique_ptr &RHS) {
1054 return LHS->getNotOutlinedCost() * RHS->getOutliningCost() >
1055 RHS->getNotOutlinedCost() * LHS->getOutliningCost();
1056 });
1057
1058
1059
1060 auto *UnsignedVecBegin = Mapper.UnsignedVec.begin();
1062 for (auto &OF : FunctionList) {
1063#ifndef NDEBUG
1064 auto NumCandidatesBefore = OF->Candidates.size();
1065#endif
1066
1067
1068 erase_if(OF->Candidates, [&UnsignedVecBegin](Candidate &C) {
1069 return std::any_of(UnsignedVecBegin + C.getStartIdx(),
1070 UnsignedVecBegin + C.getEndIdx() + 1, [](unsigned I) {
1071 return I == static_cast(-1);
1072 });
1073 });
1074
1075#ifndef NDEBUG
1076 auto NumCandidatesAfter = OF->Candidates.size();
1077 LLVM_DEBUG(dbgs() << "PRUNED: " << NumCandidatesBefore - NumCandidatesAfter
1078 << "/" << NumCandidatesBefore << " candidates\n");
1079#endif
1080
1081
1083 LLVM_DEBUG(dbgs() << "SKIP: Expected benefit (" << OF->getBenefit()
1085 << " B)\n");
1086 continue;
1087 }
1088
1089 LLVM_DEBUG(dbgs() << "OUTLINE: Expected benefit (" << OF->getBenefit()
1091 << " B)\n");
1092
1093
1094
1095
1096 SmallPtrSet<MachineInstr *, 2> MIs;
1097 for (Candidate &C : OF->Candidates) {
1098 for (MachineInstr &MI : C)
1102 }
1103
1104
1105
1107 emitOutlinedFunctionRemark(*OF);
1108 FunctionsCreated++;
1109 OutlinedFunctionNum++;
1110 MachineFunction *MF = OF->MF;
1111 const TargetSubtargetInfo &STI = MF->getSubtarget();
1113
1114
1116 for (Candidate &C : OF->Candidates) {
1117 MachineBasicBlock &MBB = *C.getMBB();
1120
1121
1123
1124#ifndef NDEBUG
1125 auto MBBBeingOutlinedFromName =
1128 ? ""
1131 << MFBeingOutlinedFromName << ":"
1132 << MBBBeingOutlinedFromName << "\n");
1134#endif
1135
1136
1137
1138
1139
1141
1142
1143
1144 SmallSet<Register, 2> UseRegs, DefRegs;
1145
1146
1147
1148
1149
1150
1153 Last = std::next(CallInst.getReverse());
1154 Iter != Last; Iter++) {
1155 MachineInstr *MI = &*Iter;
1156 SmallSet<Register, 2> InstrUseRegs;
1157 for (MachineOperand &MOP : MI->operands()) {
1158
1159 if (!MOP.isReg())
1160 continue;
1161
1162 if (MOP.isDef()) {
1163
1164 DefRegs.insert(MOP.getReg());
1165 if (UseRegs.count(MOP.getReg()) &&
1166 !InstrUseRegs.count(MOP.getReg()))
1167
1168
1169 UseRegs.erase(MOP.getReg());
1170 } else if (!MOP.isUndef()) {
1171
1172
1173 UseRegs.insert(MOP.getReg());
1174 InstrUseRegs.insert(MOP.getReg());
1175 }
1176 }
1177 if (MI->isCandidateForAdditionalCallInfo())
1178 MI->getMF()->eraseAdditionalCallInfo(MI);
1179 }
1180
1181 for (const Register &I : DefRegs)
1182
1183 CallInst->addOperand(
1185 true ));
1186
1187 for (const Register &I : UseRegs)
1188
1189 CallInst->addOperand(
1191 true ));
1192 }
1193
1194
1195
1196
1197 MBB.erase(std::next(StartIt), std::next(EndIt));
1198
1199
1200 for (unsigned &I : make_range(UnsignedVecBegin + C.getStartIdx(),
1201 UnsignedVecBegin + C.getEndIdx() + 1))
1202 I = static_cast<unsigned>(-1);
1203 OutlinedSomething = true;
1204
1205
1206 NumOutlined++;
1207 }
1208 }
1209
1210 LLVM_DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n");
1211 return OutlinedSomething;
1212}
1213
1220 return true;
1221 auto *MF = MBB.getParent();
1223 ++NumPGOAllowedCold;
1224 return true;
1225 }
1226
1227 auto *BB = MBB.getBasicBlock();
1228 if (BB && PSI && BFI)
1231
1234 if (TII->shouldOutlineFromFunctionByDefault(*MF)) {
1235
1236 ++NumPGOOptimisticOutlined;
1237 return true;
1238 }
1239 return false;
1240 }
1242
1243 ++NumPGOConservativeBlockedOutlined;
1244 return false;
1245}
1246
1247void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
1248
1249
1250 LLVM_DEBUG(dbgs() << "*** Populating mapper ***\n");
1251 bool EnableProfileGuidedOutlining =
1252 RunOutlinerMode == RunOutliner::OptimisticPGO ||
1253 RunOutlinerMode == RunOutliner::ConservativePGO;
1254 ProfileSummaryInfo *PSI = nullptr;
1255 if (EnableProfileGuidedOutlining)
1256 PSI = &getAnalysis().getPSI();
1257 for (Function &F : M) {
1258 LLVM_DEBUG(dbgs() << "MAPPING FUNCTION: " << F.getName() << "\n");
1259
1260 if (F.hasFnAttribute("nooutline")) {
1261 LLVM_DEBUG(dbgs() << "SKIP: Function has nooutline attribute\n");
1262 continue;
1263 }
1264
1265
1266
1268
1269
1270
1271 if (!MF) {
1272 LLVM_DEBUG(dbgs() << "SKIP: Function does not have a MachineFunction\n");
1273 continue;
1274 }
1275
1277 BlockFrequencyInfo *BFI = nullptr;
1278 if (EnableProfileGuidedOutlining && F.hasProfileData())
1279 BFI = &getAnalysis(F).getBFI();
1280 if (RunOutlinerMode == RunOutliner::TargetDefault &&
1282 LLVM_DEBUG(dbgs() << "SKIP: Target does not want to outline from "
1283 "function by default\n");
1284 continue;
1285 }
1286
1287
1288
1291 << ": unsafe to outline from\n");
1292 continue;
1293 }
1294
1295
1296
1297
1298 const unsigned MinMBBSize = 2;
1299
1300 for (MachineBasicBlock &MBB : *MF) {
1302
1303
1304
1305
1306
1307
1308 if (MBB.size() < MinMBBSize) {
1309 LLVM_DEBUG(dbgs() << " SKIP: MBB size less than minimum size of "
1310 << MinMBBSize << "\n");
1311 continue;
1312 }
1313
1314
1315
1317 LLVM_DEBUG(dbgs() << " SKIP: MBB's address is taken\n");
1318 continue;
1319 }
1320
1322 ++NumPGOBlockedOutlined;
1323 continue;
1324 }
1325
1326
1327 Mapper.convertToUnsignedVec(MBB, *TII);
1328 }
1329 }
1330
1331 UnsignedVecSize = Mapper.UnsignedVec.size();
1332}
1333
1334void MachineOutliner::initSizeRemarkInfo(
1335 const Module &M, StringMap &FunctionToInstrCount) {
1336
1337
1338 for (const Function &F : M) {
1340
1341
1342
1343 if (!MF)
1344 continue;
1346 }
1347}
1348
1349void MachineOutliner::emitInstrCountChangedRemark(
1350 const Module &M, const StringMap &FunctionToInstrCount) {
1351
1352
1353
1354 for (const Function &F : M) {
1356
1357
1358
1359 if (!MF)
1360 continue;
1361
1362 std::string Fname = std::string(F.getName());
1364 unsigned FnCountBefore = 0;
1365
1366
1367 auto It = FunctionToInstrCount.find(Fname);
1368
1369
1370
1371 if (It != FunctionToInstrCount.end())
1372 FnCountBefore = It->second;
1373
1374
1375 int64_t FnDelta = static_cast<int64_t>(FnCountAfter) -
1376 static_cast<int64_t>(FnCountBefore);
1377 if (FnDelta == 0)
1378 continue;
1379
1380 MachineOptimizationRemarkEmitter MORE(*MF, nullptr);
1381 MORE.emit([&]() {
1382 MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
1383 DiagnosticLocation(), &MF->front());
1384 R << DiagnosticInfoOptimizationBase::Argument("Pass", "Machine Outliner")
1385 << ": Function: "
1386 << DiagnosticInfoOptimizationBase::Argument("Function", F.getName())
1387 << ": MI instruction count changed from "
1388 << DiagnosticInfoOptimizationBase::Argument("MIInstrsBefore",
1389 FnCountBefore)
1390 << " to "
1391 << DiagnosticInfoOptimizationBase::Argument("MIInstrsAfter",
1392 FnCountAfter)
1393 << "; Delta: "
1394 << DiagnosticInfoOptimizationBase::Argument("Delta", FnDelta);
1395 return R;
1396 });
1397 }
1398}
1399
1400void MachineOutliner::initializeOutlinerMode(const Module &M) {
1402 return;
1403
1404 if (auto *IndexWrapperPass =
1405 getAnalysisIfAvailable()) {
1406 auto *TheIndex = IndexWrapperPass->getIndex();
1407
1408
1409 if (TheIndex && !TheIndex->hasExportedFunctions(M))
1410 return;
1411 }
1412
1413
1414
1415
1416
1418 OutlinerMode = CGDataMode::Write;
1419
1420 LocalHashTree = std::make_unique();
1421
1423 OutlinerMode = CGDataMode::Read;
1424}
1425
1426void MachineOutliner::emitOutlinedHashTree(Module &M) {
1427 assert(LocalHashTree);
1428 if (!LocalHashTree->empty()) {
1430 dbgs() << "Emit outlined hash tree. Size: " << LocalHashTree->size()
1431 << "\n";
1432 });
1433 SmallVector Buf;
1434 raw_svector_ostream OS(Buf);
1435
1436 OutlinedHashTreeRecord HTR(std::move(LocalHashTree));
1437 HTR.serialize(OS);
1438
1439 llvm::StringRef Data(Buf.data(), Buf.size());
1440 std::unique_ptr Buffer =
1442
1443 Triple TT(M.getTargetTriple());
1445 M, *Buffer,
1447 }
1448}
1449
1450bool MachineOutliner::runOnModule(Module &M) {
1451 if (skipModule(M))
1452 return false;
1453
1454
1455
1456 if (M.empty())
1457 return false;
1458
1459
1460 initializeOutlinerMode(M);
1461
1462 MMI = &getAnalysis().getMMI();
1463 TM = &getAnalysis().getTM();
1464
1465
1466 unsigned OutlinedFunctionNum = 0;
1467
1468 OutlineRepeatedNum = 0;
1469 if (!doOutline(M, OutlinedFunctionNum))
1470 return false;
1471
1473 OutlinedFunctionNum = 0;
1474 OutlineRepeatedNum++;
1475 if (!doOutline(M, OutlinedFunctionNum)) {
1477 dbgs() << "Did not outline on iteration " << I + 2 << " out of "
1479 });
1480 break;
1481 }
1482 }
1483
1484 if (OutlinerMode == CGDataMode::Write)
1485 emitOutlinedHashTree(M);
1486
1487 return true;
1488}
1489
1490bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) {
1491
1492
1493
1494
1495
1497 dbgs() << "Machine Outliner: Running on ";
1498 switch (RunOutlinerMode) {
1499 case RunOutliner::AlwaysOutline:
1500 dbgs() << "all functions";
1501 break;
1502 case RunOutliner::OptimisticPGO:
1503 dbgs() << "optimistically cold functions";
1504 break;
1505 case RunOutliner::ConservativePGO:
1506 dbgs() << "conservatively cold functions";
1507 break;
1508 case RunOutliner::TargetDefault:
1509 dbgs() << "target-default functions";
1510 break;
1511 case RunOutliner::NeverOutline:
1513 }
1514 dbgs() << "\n";
1515 });
1516
1517
1518
1520 InstructionMapper Mapper(*MMI);
1521
1522
1523 populateMapper(Mapper, M);
1524 std::vector<std::unique_ptr> FunctionList;
1525
1526
1527 if (OutlinerMode == CGDataMode::Read)
1528 findGlobalCandidates(Mapper, FunctionList);
1529 else
1530 findCandidates(Mapper, FunctionList);
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541 bool ShouldEmitSizeRemarks = M.shouldEmitInstrCountChangedRemark();
1542 StringMap FunctionToInstrCount;
1543 if (ShouldEmitSizeRemarks)
1544 initSizeRemarkInfo(M, FunctionToInstrCount);
1545
1546
1547 bool OutlinedSomething =
1548 outline(M, FunctionList, Mapper, OutlinedFunctionNum);
1549
1550
1551
1552
1553 if (ShouldEmitSizeRemarks && OutlinedSomething)
1554 emitInstrCountChangedRemark(M, FunctionToInstrCount);
1555
1557 if (!OutlinedSomething)
1558 dbgs() << "Stopped outlining at iteration " << OutlineRepeatedNum
1559 << " because no changes were found.\n";
1560 });
1561
1562 return OutlinedSomething;
1563}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the DenseMap class.
static DISubprogram * getSubprogramOrNull(OutlinableGroup &Group)
Get the subprogram if it exists for one of the outlined regions.
Module.h This file contains the declarations for the Module class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Machine Check Debug Module
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
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 bool allowPGOOutlining(RunOutliner RunOutlinerMode, const ProfileSummaryInfo *PSI, const BlockFrequencyInfo *BFI, MachineBasicBlock &MBB)
Definition MachineOutliner.cpp:1214
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.
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)
Definition MachineOutliner.cpp:676
Contains all data structures shared between the outliner implemented in MachineOutliner....
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This is the interface to build a ModuleSummaryIndex for a module.
static Expected< Function * > createOutlinedFunction(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder, const OpenMPIRBuilder::TargetKernelDefaultAttrs &DefaultAttrs, StringRef FuncName, SmallVectorImpl< Value * > &Inputs, OpenMPIRBuilder::TargetBodyGenCallbackTy &CBFunc, OpenMPIRBuilder::TargetGenArgAccessorsCallbackTy &ArgAccessorFuncCB)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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)
Target-Independent Code Generator Pass Configuration Options 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.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const
Returns the estimated profile count of BB.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
@ InternalLinkage
Rename collisions when linking (static functions).
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
void setIsOutlined(bool V)
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
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.
bool isDebugInstr() const
LLVM_ABI void dropMemRefs(MachineFunction &MF)
Clear this MachineInstr's memory reference descriptor list.
LLVM_ABI 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.
LLVM_ABI MachineFunction & getOrCreateMachineFunction(Function &F)
Returns the MachineFunction constructed for the IR function F.
LLVM_ABI MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
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)
LLVM_ABI void freezeReservedRegs()
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
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...
const HashNode * getRoot() const
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Analysis providing profile information.
LLVM_ABI uint64_t getOrCompColdCountThreshold() const
Returns ColdCountThreshold if set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
virtual SmallVector< std::pair< MachineBasicBlock::iterator, MachineBasicBlock::iterator > > getOutlinableRanges(MachineBasicBlock &MBB, unsigned &Flags) const
Optional target hook which partitions MBB into outlinable ranges for instruction mapping purposes.
virtual bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const
Return true if the function should be outlined from by default.
outliner::InstrType getOutliningType(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MIT, unsigned Flags) const
Returns how or if MIT should be outlined.
virtual void mergeOutliningCandidateAttributes(Function &F, std::vector< outliner::Candidate > &Candidates) const
Optional target hook to create the LLVM IR attributes for the outlined function.
virtual bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const
Return true if the function can safely be outlined from.
virtual void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const
Insert a custom frame for outlined functions.
virtual MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const
Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore.
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const
Optional target hook that returns true if MBB is safe to outline from, and returns any target-specifi...
virtual std::optional< std::unique_ptr< outliner::OutlinedFunction > > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs, unsigned MinRepeats) const
Returns a outliner::OutlinedFunction struct containing target-specific information for a set of outli...
virtual MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const
Insert a call to an outlined function into the program.
virtual size_t clearLinkerOptimizationHints(const SmallPtrSetImpl< MachineInstr * > &MIs) const
Remove all Linker Optimization Hints (LOH) associated with instructions in MIs and.
virtual const TargetInstrInfo * getInstrInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
SmallVector< const MachineInstr * > InstrList
bool hasOutlinedHashTree()
const OutlinedHashTree * getOutlinedHashTree()
initializer< Ty > init(const Ty &Val)
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
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.
uint64_t stable_hash
An opaque object representing a stable hash code.
LLVM_ABI void initializeMachineOutlinerPass(PassRegistry &)
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI stable_hash stableHashValue(const MachineOperand &MO)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI ModulePass * createMachineOutlinerPass(RunOutliner RunOutlinerMode)
This pass performs outlining on machine instructions directly before printing assembly.
Definition MachineOutliner.cpp:596
FunctionAddr VTableAddr uintptr_t uintptr_t Data
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
stable_hash stable_hash_combine(ArrayRef< stable_hash > Buffer)
LLVM_ABI 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.
LLVM_ABI std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Implement std::hash so that hash_code can be used in STL containers.
unsigned StartIdx
Definition MachineOutliner.cpp:665
unsigned EndIdx
Definition MachineOutliner.cpp:666
MatchedEntry(unsigned StartIdx, unsigned EndIdx, unsigned Count)
Definition MachineOutliner.cpp:668
unsigned Count
Definition MachineOutliner.cpp:667
An information struct used to provide DenseMap with the various necessary components for a given valu...
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.
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.