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 || 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,

745 MBB, FunctionList.size(),

746 MBBFlagsMap[MBB]);

747 const TargetInstrInfo *TII =

749 unsigned MinRepeats = 1;

750 std::optional<std::unique_ptr> OF =

752 MinRepeats);

753 if (OF.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,

831 MBB, FunctionList.size(),

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 (OF.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.