LLVM: lib/Transforms/Instrumentation/PGOInstrumentation.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

118#include

119#include

120#include

121#include

122#include

123#include

124#include

125#include

126#include <unordered_map>

127#include

128#include

129

130using namespace llvm;

133

134#define DEBUG_TYPE "pgo-instrumentation"

135

136STATISTIC(NumOfPGOInstrument, "Number of edges instrumented.");

137STATISTIC(NumOfPGOSelectInsts, "Number of select instruction instrumented.");

138STATISTIC(NumOfPGOMemIntrinsics, "Number of mem intrinsics instrumented.");

140STATISTIC(NumOfPGOBB, "Number of basic-blocks.");

141STATISTIC(NumOfPGOSplit, "Number of critical edge splits.");

142STATISTIC(NumOfPGOFunc, "Number of functions having valid profile counts.");

143STATISTIC(NumOfPGOMismatch, "Number of functions having mismatch profile.");

144STATISTIC(NumOfPGOMissing, "Number of functions without profile.");

145STATISTIC(NumOfPGOICall, "Number of indirect call value instrumentations.");

146STATISTIC(NumOfCSPGOInstrument, "Number of edges instrumented in CSPGO.");

148 "Number of select instruction instrumented in CSPGO.");

150 "Number of mem intrinsics instrumented in CSPGO.");

151STATISTIC(NumOfCSPGOEdge, "Number of edges in CSPGO.");

152STATISTIC(NumOfCSPGOBB, "Number of basic-blocks in CSPGO.");

153STATISTIC(NumOfCSPGOSplit, "Number of critical edge splits in CSPGO.");

155 "Number of functions having valid profile counts in CSPGO.");

157 "Number of functions having mismatch profile in CSPGO.");

158STATISTIC(NumOfCSPGOMissing, "Number of functions without profile in CSPGO.");

159STATISTIC(NumCoveredBlocks, "Number of basic blocks that were executed");

160

161

162

166 cl::desc("Specify the path of profile data file. This is "

167 "mainly for test purpose."));

171 cl::desc("Specify the path of profile remapping file. This is mainly for "

172 "test purpose."));

173

174

175

178 cl::desc("Disable Value Profiling"));

179

180

181

184 cl::desc("Max number of annotations for a single indirect "

185 "call callsite"));

186

187

188

191 cl::desc("Max number of precise value annotations for a single memop"

192 "intrinsic"));

193

194

195

198 cl::desc("Append function hash to the name of COMDAT function to avoid "

199 "function hash mismatch due to the preinliner"));

200

201namespace llvm {

202

203

206 cl::desc("Use this option to turn on/off "

207 "warnings about missing profile data for "

208 "functions."));

209

210

211

214 cl::desc("Use this option to turn off/on "

215 "warnings about profile cfg mismatch."));

216

217

218

219

222 cl::desc("The option is used to turn on/off "

223 "warnings about hash mismatch for comdat "

224 "or weak functions."));

225

226

229 cl::desc("Use this option to turn on/off SELECT "

230 "instruction instrumentation. "));

231

232

235 cl::desc("A boolean option to show CFG dag or text "

236 "with raw profile counts from "

237 "profile data. See also option "

238 "-pgo-view-counts. To limit graph "

239 "display to only one function, use "

240 "filtering option -view-bfi-func-name."),

244

245

248 cl::desc("Use this option to turn on/off "

249 "memory intrinsic size profiling."));

250

251

254 cl::desc("When this option is on, the annotated "

255 "branch probability will be emitted as "

256 "optimization remarks: -{Rpass|"

257 "pass-remarks}=pgo-instrumentation"));

258

261 cl::desc("Force to instrument function entry basicblock."));

262

266 cl::desc("Force to instrument loop entries."));

267

269 "pgo-function-entry-coverage", cl::Hidden,

271 "Use this option to enable function entry coverage instrumentation."));

272

274 "pgo-block-coverage",

275 cl::desc("Use this option to enable basic block coverage instrumentation"));

276

279 cl::desc("Create a dot file of CFGs with block "

280 "coverage inference information"));

281

283 "pgo-temporal-instrumentation",

284 cl::desc("Use this option to enable temporal instrumentation"));

285

288 cl::desc("Fix function entry count in profile use."));

289

292 cl::desc("Print out the non-match BFI count if a hot raw profile count "

293 "becomes non-hot, or a cold raw profile count becomes hot. "

294 "The print is enabled under -Rpass-analysis=pgo, or "

295 "internal option -pass-remarks-analysis=pgo."));

296

299 cl::desc("Print out mismatched BFI counts after setting profile metadata "

300 "The print is enabled under -Rpass-analysis=pgo, or "

301 "internal option -pass-remarks-analysis=pgo."));

302

305 cl::desc("Set the threshold for pgo-verify-bfi: only print out "

306 "mismatched BFI if the difference percentage is greater than "

307 "this value (in percentage)."));

308

311 cl::desc("Set the threshold for pgo-verify-bfi: skip the counts whose "

312 "profile count value is below."));

313

317 cl::desc("Trace the hash of the function with this name."));

318

320 "pgo-function-size-threshold", cl::Hidden,

321 cl::desc("Do not instrument functions smaller than this threshold."));

322

325 cl::desc("Do not instrument functions with the number of critical edges "

326 " greater than this threshold."));

327

330 cl::desc("For cold function instrumentation, skip instrumenting functions "

331 "whose entry count is above the given value."));

332

335 cl::desc("For cold function instrumentation, treat count unknown(e.g. "

336 "unprofiled) functions as cold."));

337

340 cl::desc("Enable cold function only instrumentation."));

341

343 "ctx-prof-skip-callsite-instr", cl::Hidden,

344 cl::desc("Do not instrument callsites to functions in this list. Intended "

345 "for testing."));

346

348

349

350

352

353

354

356

357

358

363}

364

365namespace {

366class FunctionInstrumenter final {

370 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;

374

376

377

378

379

380

381 bool isValueProfilingDisabled() const {

384 }

385

386 bool shouldInstrumentEntryBB() const {

389 }

390

392

393public:

394 FunctionInstrumenter(

396 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,

400 : M(M), F(F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),

401 LI(LI), InstrumentationType(InstrumentationType) {}

402

404};

405}

406

407

408

412 return std::string();

413

416 if (!CI)

417 return std::string();

418

419 std::string result;

423

426 if (CV) {

428 OS << "_Zero";

429 else if (CV->isOne())

430 OS << "_One";

432 OS << "_MinusOne";

433 else

434 OS << "_Const";

435 }

436 return result;

437}

438

440#define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,

442};

443

444

445

462 ProfileVersion |=

473 IRLevelVersionVariable->setVisibility(

475

476 Triple TT(M.getTargetTriple());

477 if (TT.supportsCOMDAT()) {

479 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));

480 }

481 return IRLevelVersionVariable;

482}

483

484namespace {

485

486

487

488

489

490

491enum VisitMode { VM_counting, VM_instrument, VM_annotate };

492class PGOUseFunc;

493

494

495struct SelectInstVisitor : public InstVisitor {

497 unsigned NSIs = 0;

498 VisitMode Mode = VM_counting;

499 unsigned *CurCtrIdx = nullptr;

500 unsigned TotalNumCtrs = 0;

501 GlobalValue *FuncNameVar = nullptr;

502 uint64_t FuncHash = 0;

503 PGOUseFunc *UseFunc = nullptr;

504 bool HasSingleByteCoverage;

505

506 SelectInstVisitor(Function &Func, bool HasSingleByteCoverage)

507 : F(Func), HasSingleByteCoverage(HasSingleByteCoverage) {}

508

509 void countSelects() {

510 NSIs = 0;

511 Mode = VM_counting;

513 }

514

515

516

517

518

519 void instrumentSelects(unsigned *Ind, unsigned TotalNC, GlobalValue *FNV,

520 uint64_t FHash) {

521 Mode = VM_instrument;

522 CurCtrIdx = Ind;

523 TotalNumCtrs = TotalNC;

524 FuncHash = FHash;

525 FuncNameVar = FNV;

527 }

528

529

530 void annotateSelects(PGOUseFunc *UF, unsigned *Ind) {

531 Mode = VM_annotate;

532 UseFunc = UF;

533 CurCtrIdx = Ind;

535 }

536

537 void instrumentOneSelectInst(SelectInst &SI);

538 void annotateOneSelectInst(SelectInst &SI);

539

540

541 void visitSelectInst(SelectInst &SI);

542

543

544

545 unsigned getNumOfSelectInsts() const { return NSIs; }

546};

547

548

549

550

551

552struct PGOEdge {

555 uint64_t Weight;

556 bool InMST = false;

557 bool Removed = false;

558 bool IsCritical = false;

559

560 PGOEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W = 1)

561 : SrcBB(Src), DestBB(Dest), Weight(W) {}

562

563

564 std::string infoString() const {

565 return (Twine(Removed ? "-" : " ") + (InMST ? " " : "*") +

566 (IsCritical ? "c" : " ") + " W=" + Twine(Weight))

567 .str();

568 }

569};

570

571

572struct PGOBBInfo {

573 PGOBBInfo *Group;

574 uint32_t Index;

575 uint32_t Rank = 0;

576

577 PGOBBInfo(unsigned IX) : Group(this), Index(IX) {}

578

579

580 std::string infoString() const {

581 return (Twine("Index=") + Twine(Index)).str();

582 }

583};

584

585

586template <class Edge, class BBInfo> class FuncPGOInstrumentation {

587private:

589

590

591 bool IsCS;

592

593

594 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;

595

596 ValueProfileCollector VPC;

597

598 void computeCFGHash();

599 void renameComdatFunction();

600

601public:

602 const TargetLibraryInfo &TLI;

603 std::vector<std::vector> ValueSites;

604 SelectInstVisitor SIVisitor;

605 std::string FuncName;

606 std::string DeprecatedFuncName;

607 GlobalVariable *FuncNameVar;

608

609

610 uint64_t FunctionHash = 0;

611

612

613 CFGMST<Edge, BBInfo> MST;

614

615 const std::optional BCI;

616

617 static std::optional

618 constructBCI(Function &Func, bool HasSingleByteCoverage,

619 bool InstrumentFuncEntry) {

620 if (HasSingleByteCoverage)

621 return BlockCoverageInference(Func, InstrumentFuncEntry);

622 return {};

623 }

624

625

626

627 void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);

628

629

630

632

633

634 BBInfo &getBBInfo(const BasicBlock *BB) const { return MST.getBBInfo(BB); }

635

636

637 BBInfo *findBBInfo(const BasicBlock *BB) const { return MST.findBBInfo(BB); }

638

639

640 void dumpInfo(StringRef Str = "") const {

641 MST.dumpEdges(dbgs(), Twine("Dump Function ") + FuncName +

642 " Hash: " + Twine(FunctionHash) + "\t" + Str);

643 }

644

645 FuncPGOInstrumentation(

646 Function &Func, TargetLibraryInfo &TLI,

647 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,

648 bool CreateGlobalVar = false, BranchProbabilityInfo *BPI = nullptr,

649 BlockFrequencyInfo *BFI = nullptr, LoopInfo *LI = nullptr,

650 bool IsCS = false, bool InstrumentFuncEntry = true,

651 bool InstrumentLoopEntries = false, bool HasSingleByteCoverage = false)

652 : F(Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(Func, TLI),

653 TLI(TLI), ValueSites(IPVK_Last + 1),

654 SIVisitor(Func, HasSingleByteCoverage),

655 MST(F, InstrumentFuncEntry, InstrumentLoopEntries, BPI, BFI, LI),

656 BCI(constructBCI(Func, HasSingleByteCoverage, InstrumentFuncEntry)) {

658 BCI->viewBlockCoverageGraph();

659

660 SIVisitor.countSelects();

661 ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);

662 if (!IsCS) {

663 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();

664 NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();

665 NumOfPGOBB += MST.bbInfoSize();

666 ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);

668 ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);

669 } else {

670 NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();

671 NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();

672 NumOfCSPGOBB += MST.bbInfoSize();

673 }

674

677 computeCFGHash();

678 if (!ComdatMembers.empty())

679 renameComdatFunction();

680 LLVM_DEBUG(dumpInfo("after CFGMST"));

681

682 for (const auto &E : MST.allEdges()) {

683 if (E->Removed)

684 continue;

685 IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;

686 if (E->InMST)

687 IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;

688 }

689

690 if (CreateGlobalVar)

692 }

693};

694

695}

696

697

698

699

700template <class Edge, class BBInfo>

701void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {

702 std::vector<uint8_t> Indexes;

704 for (auto &BB : F) {

706 auto BI = findBBInfo(Succ);

707 if (BI == nullptr)

708 continue;

710 for (int J = 0; J < 4; J++)

711 Indexes.push_back((uint8_t)(Index >> (J * 8)));

712 }

713 }

715

717

718 auto updateJCH = [&JCH](uint64_t Num) {

722 };

723 updateJCH((uint64_t)SIVisitor.getNumOfSelectInsts());

724 updateJCH((uint64_t)ValueSites[IPVK_IndirectCallTarget].size());

725 updateJCH((uint64_t)ValueSites[IPVK_MemOPSize].size());

726 if (BCI) {

727 updateJCH(BCI->getInstrumentedBlocksHash());

728 } else {

730 }

731

732

733

735

736

738 if (IsCS)

740 LLVM_DEBUG(dbgs() << "Function Hash Computation for " << F.getName() << ":\n"

741 << " CRC = " << JC.getCRC()

742 << ", Selects = " << SIVisitor.getNumOfSelectInsts()

743 << ", Edges = " << MST.numEdges() << ", ICSites = "

744 << ValueSites[IPVK_IndirectCallTarget].size()

745 << ", Memops = " << ValueSites[IPVK_MemOPSize].size()

746 << ", High32 CRC = " << JCH.getCRC()

747 << ", Hash = " << FunctionHash << "\n";);

748

750 dbgs() << "Funcname=" << F.getName() << ", Hash=" << FunctionHash

751 << " in building " << F.getParent()->getSourceFileName() << "\n";

752}

753

754

757 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {

759 return false;

760

761

762

763

764

765

766

767

769 for (auto &&CM : make_range(ComdatMembers.equal_range(C))) {

772 if (FM != &F)

773 return false;

774 }

775 return true;

776}

777

778

779template <class Edge, class BBInfo>

780void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {

782 return;

783 std::string OrigName = F.getName().str();

784 std::string NewFuncName =

785 Twine(F.getName() + "." + Twine(FunctionHash)).str();

786 F.setName(Twine(NewFuncName));

788 FuncName = Twine(FuncName + "." + Twine(FunctionHash)).str();

790 Module *M = F.getParent();

791

792

793

794 if (F.hasComdat()) {

796 NewComdat = M->getOrInsertComdat(StringRef(NewFuncName));

798 F.setComdat(NewComdat);

799 return;

800 }

801

802

803 Comdat *OrigComdat = F.getComdat();

804 std::string NewComdatName =

806 NewComdat = M->getOrInsertComdat(StringRef(NewComdatName));

808

809 for (auto &&CM : make_range(ComdatMembers.equal_range(OrigComdat))) {

810

812 }

813}

814

815

816

817template <class Edge, class BBInfo>

818void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(

819 std::vector<BasicBlock *> &InstrumentBBs) {

820 if (BCI) {

821 for (auto &BB : F)

822 if (BCI->shouldInstrumentBlock(BB))

823 InstrumentBBs.push_back(&BB);

824 return;

825 }

826

827

828 std::vector<Edge *> EdgeList;

829 EdgeList.reserve(MST.numEdges());

830 for (const auto &E : MST.allEdges())

831 EdgeList.push_back(E.get());

832

833 for (auto &E : EdgeList) {

835 if (InstrBB)

836 InstrumentBBs.push_back(InstrBB);

837 }

838}

839

840

841

842template <class Edge, class BBInfo>

843BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {

844 if (E->InMST || E->Removed)

845 return nullptr;

846

849

850 if (SrcBB == nullptr)

851 return DestBB;

852 if (DestBB == nullptr)

853 return SrcBB;

854

856

857

859 return nullptr;

860 return BB;

861 };

862

863

864

867 return canInstrument(SrcBB);

868 if (E->IsCritical)

869 return canInstrument(DestBB);

870

871

872

876 if (!InstrBB) {

878 dbgs() << "Fail to split critical edge: not instrument this edge.\n");

879 return nullptr;

880 }

881

882

883 IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;

884 LLVM_DEBUG(dbgs() << "Split critical edge: " << getBBInfo(SrcBB).Index

885 << " --> " << getBBInfo(DestBB).Index << "\n");

886

887 MST.addEdge(SrcBB, InstrBB, 0);

888

889 Edge &NewEdge1 = MST.addEdge(InstrBB, DestBB, 0);

890 NewEdge1.InMST = true;

891 E->Removed = true;

892

893 return canInstrument(InstrBB);

894}

895

896

897

898

899

900

901static void

906 if (!OrigCall)

907 return;

908

910

911

912 std::optional ParentFunclet =

914 if (ParentFunclet)

916 } else {

917

918

919

920 if (!BlockColors.empty()) {

921 const ColorVector &CV = BlockColors.find(OrigCall->getParent())->second;

922 assert(CV.size() == 1 && "non-unique color for block!");

924 if (EHPadIt->isEHPad())

925 OpBundles.emplace_back("funclet", &*EHPadIt);

926 }

927 }

928}

929

930

931

932void FunctionInstrumenter::instrument() {

934

935

937 }

938

939 const bool IsCtxProf = InstrumentationType == PGOInstrumentationType::CTXPROF;

940 FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(

941 F, TLI, ComdatMembers, !IsCtxProf, BPI, BFI, LI,

942 InstrumentationType == PGOInstrumentationType::CSFDO,

943 shouldInstrumentEntryBB(), shouldInstrumentLoopEntries(),

945

947 auto *const CFGHash =

948 ConstantInt::get(Type::getInt64Ty(M.getContext()), FuncInfo.FunctionHash);

949

950

952 Name, PointerType::get(M.getContext(), 0));

954 auto &EntryBB = F.getEntryBlock();

955 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());

956

957

958 Builder.CreateIntrinsic(

959 Intrinsic::instrprof_cover,

960 {NormalizedNamePtr, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});

961 return;

962 }

963

964 std::vector<BasicBlock *> InstrumentBBs;

965 FuncInfo.getInstrumentBBs(InstrumentBBs);

967 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();

968

969 if (IsCtxProf) {

971

972 auto *CSIntrinsic =

974

975

976

977

978

979

980

981

982 auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {

983 for (auto &BB : F)

984 for (auto &Instr : BB)

987 continue;

988 if (CS->getCalledFunction() &&

989 SkipCSInstr.contains(CS->getCalledFunction()->getName()))

990 continue;

991 Visitor(CS);

992 }

993 };

994

995 uint32_t TotalNumCallsites = 0;

996 Visit([&TotalNumCallsites](auto *) { ++TotalNumCallsites; });

997

998

1000 Visit([&](auto *CB) {

1002 Builder.CreateCall(CSIntrinsic,

1003 {Name, CFGHash, Builder.getInt32(TotalNumCallsites),

1005 CB->getCalledOperand()});

1006 });

1007 }

1008

1009 uint32_t I = 0;

1012 auto &EntryBB = F.getEntryBlock();

1013 IRBuilder<> Builder(&EntryBB, EntryBB.getFirstNonPHIOrDbgOrAlloca());

1014

1015

1016 Builder.CreateIntrinsic(Intrinsic::instrprof_timestamp,

1017 {NormalizedNamePtr, CFGHash,

1019 Builder.getInt32(I)});

1021 }

1022

1023 for (auto *InstrBB : InstrumentBBs) {

1025 assert(Builder.GetInsertPoint() != InstrBB->end() &&

1026 "Cannot get the Instrumentation point");

1027

1028

1029 Builder.CreateIntrinsic(PGOBlockCoverage ? Intrinsic::instrprof_cover

1030 : Intrinsic::instrprof_increment,

1031 {NormalizedNamePtr, CFGHash,

1033 Builder.getInt32(I++)});

1034 }

1035

1036

1037 FuncInfo.SIVisitor.instrumentSelects(&I, NumCounters, Name,

1038 FuncInfo.FunctionHash);

1040

1041 if (isValueProfilingDisabled())

1042 return;

1043

1044 NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();

1045

1046

1047

1048

1049

1050 DenseMap<BasicBlock *, ColorVector> BlockColors;

1051 if (F.hasPersonalityFn() &&

1054

1055

1056 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {

1057 unsigned SiteIndex = 0;

1059 continue;

1060

1061 for (VPCandidateInfo Cand : FuncInfo.ValueSites[Kind]) {

1063 << " site: CallSite Index = " << SiteIndex << "\n");

1064

1066 assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&

1067 "Cannot get the Instrumentation point");

1068

1069 Value *ToProfile = nullptr;

1070 if (Cand.V->getType()->isIntegerTy())

1071 ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());

1072 else if (Cand.V->getType()->isPointerTy())

1073 ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());

1074 assert(ToProfile && "value profiling Value is of unexpected type");

1075

1077 Name, PointerType::get(M.getContext(), 0));

1078

1081 Builder.CreateCall(

1083 Intrinsic::instrprof_value_profile),

1084 {NormalizedNamePtr, Builder.getInt64(FuncInfo.FunctionHash),

1085 ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},

1086 OpBundles);

1087 }

1088 }

1089}

1090

1091namespace {

1092

1093

1094struct PGOUseEdge : public PGOEdge {

1095 using PGOEdge::PGOEdge;

1096

1097 std::optional<uint64_t> Count;

1098

1099

1101

1102

1103 std::string infoString() const {

1105 return PGOEdge::infoString();

1106 return (Twine(PGOEdge::infoString()) + " Count=" + Twine(*Count)).str();

1107 }

1108};

1109

1111

1112

1113struct PGOUseBBInfo : public PGOBBInfo {

1114 std::optional<uint64_t> Count;

1115 int32_t UnknownCountInEdge = 0;

1116 int32_t UnknownCountOutEdge = 0;

1117 DirectEdges InEdges;

1118 DirectEdges OutEdges;

1119

1120 PGOUseBBInfo(unsigned IX) : PGOBBInfo(IX) {}

1121

1122

1124

1125

1126 std::string infoString() const {

1128 return PGOBBInfo::infoString();

1129 return (Twine(PGOBBInfo::infoString()) + " Count=" + Twine(*Count)).str();

1130 }

1131

1132

1133 void addOutEdge(PGOUseEdge *E) {

1134 OutEdges.push_back(E);

1135 UnknownCountOutEdge++;

1136 }

1137

1138

1139 void addInEdge(PGOUseEdge *E) {

1140 InEdges.push_back(E);

1141 UnknownCountInEdge++;

1142 }

1143};

1144

1145}

1146

1147

1150 for (const auto &E : Edges) {

1151 if (E->Removed)

1152 continue;

1153 if (E->Count)

1155 }

1157}

1158

1159namespace {

1160

1161class PGOUseFunc {

1162public:

1163 PGOUseFunc(Function &Func, Module *Modu, TargetLibraryInfo &TLI,

1164 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,

1165 BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,

1166 LoopInfo *LI, ProfileSummaryInfo *PSI, bool IsCS,

1167 bool InstrumentFuncEntry, bool InstrumentLoopEntries,

1168 bool HasSingleByteCoverage)

1169 : F(Func), M(Modu), BFI(BFIin), PSI(PSI),

1170 FuncInfo(Func, TLI, ComdatMembers, false, BPI, BFIin, LI, IsCS,

1171 InstrumentFuncEntry, InstrumentLoopEntries,

1172 HasSingleByteCoverage),

1173 FreqAttr(FFA_Normal), IsCS(IsCS), VPC(Func, TLI) {}

1174

1175 void handleInstrProfError(Error Err, uint64_t MismatchedFuncSum);

1176

1177

1178

1179

1180 bool getRecord(IndexedInstrProfReader *PGOReader);

1181

1182

1183 bool readCounters(bool &AllZeros,

1185

1186

1187 void populateCounters();

1188

1189

1190 void populateCoverage();

1191

1192

1194

1195

1196 void annotateValueSites();

1197

1198

1199 void annotateValueSites(uint32_t Kind);

1200

1201

1202 void annotateIrrLoopHeaderWeights();

1203

1204

1205 enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };

1206

1207

1208 FuncFreqAttr getFuncFreqAttr() const { return FreqAttr; }

1209

1210

1211 uint64_t getFuncHash() const { return FuncInfo.FunctionHash; }

1212

1213

1214 NamedInstrProfRecord &getProfileRecord() { return ProfileRecord; }

1215

1216

1217 PGOUseBBInfo &getBBInfo(const BasicBlock *BB) const {

1218 return FuncInfo.getBBInfo(BB);

1219 }

1220

1221

1222 PGOUseBBInfo *findBBInfo(const BasicBlock *BB) const {

1223 return FuncInfo.findBBInfo(BB);

1224 }

1225

1226 Function &getFunc() const { return F; }

1227

1228 void dumpInfo(StringRef Str = "") const { FuncInfo.dumpInfo(Str); }

1229

1230 uint64_t getProgramMaxCount() const { return ProgramMaxCount; }

1231

1232private:

1235 BlockFrequencyInfo *BFI;

1236 ProfileSummaryInfo *PSI;

1237

1238

1239 FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;

1240

1241

1242

1243 uint64_t ProgramMaxCount;

1244

1245

1246 uint32_t CountPosition = 0;

1247

1248

1249 uint32_t ProfileCountSize = 0;

1250

1251

1252 NamedInstrProfRecord ProfileRecord;

1253

1254

1255 FuncFreqAttr FreqAttr;

1256

1257

1258 bool IsCS;

1259

1260 ValueProfileCollector VPC;

1261

1262

1263 bool setInstrumentedCounts(const std::vector<uint64_t> &CountFromProfile);

1264

1265

1266

1267 void setEdgeCount(DirectEdges &Edges, uint64_t Value);

1268

1269

1270

1271

1272 void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {

1274 FreqAttr = FFA_Hot;

1276 FreqAttr = FFA_Cold;

1277 }

1278};

1279

1280}

1281

1282

1284 const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {

1285

1286 if (FuncInfo.BCI)

1287 return;

1288 for (const auto &E : FuncInfo.MST.allEdges()) {

1289 if (E->Removed)

1290 continue;

1293 PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);

1294 PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);

1295 SrcInfo.addOutEdge(E.get());

1296 DestInfo.addInEdge(E.get());

1297 }

1298}

1299

1300

1301

1302bool PGOUseFunc::setInstrumentedCounts(

1303 const std::vector<uint64_t> &CountFromProfile) {

1304

1305 std::vector<BasicBlock *> InstrumentBBs;

1306 FuncInfo.getInstrumentBBs(InstrumentBBs);

1307

1309

1311 InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();

1312

1313

1314 if (NumCounters != CountFromProfile.size()) {

1315 return false;

1316 }

1317 auto *FuncEntry = &*F.begin();

1318

1319

1320 uint32_t I = 0;

1321 for (BasicBlock *InstrBB : InstrumentBBs) {

1322 uint64_t CountValue = CountFromProfile[I++];

1323 PGOUseBBInfo &Info = getBBInfo(InstrBB);

1324

1325

1326

1327 if (InstrBB == FuncEntry && CountValue == 0)

1328 CountValue = 1;

1329 Info.setBBInfoCount(CountValue);

1330 }

1331 ProfileCountSize = CountFromProfile.size();

1332 CountPosition = I;

1333

1334

1335 auto setEdgeCount = [this](PGOUseEdge *E, uint64_t Value) -> void {

1336 E->setEdgeCount(Value);

1337 this->getBBInfo(E->SrcBB).UnknownCountOutEdge--;

1338 this->getBBInfo(E->DestBB).UnknownCountInEdge--;

1339 };

1340

1341

1342

1343

1344 for (const auto &E : FuncInfo.MST.allEdges()) {

1345 if (E->Removed || E->InMST)

1346 continue;

1348 PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);

1349

1350

1351

1352 if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)

1353 setEdgeCount(E.get(), *SrcInfo.Count);

1354 else {

1356 PGOUseBBInfo &DestInfo = getBBInfo(DestBB);

1357

1358

1359 if (DestInfo.Count && DestInfo.InEdges.size() == 1)

1360 setEdgeCount(E.get(), *DestInfo.Count);

1361 }

1362 if (E->Count)

1363 continue;

1364

1365

1366 setEdgeCount(E.get(), 0);

1367 }

1368 return true;

1369}

1370

1371

1372

1373void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t Value) {

1374 for (auto &E : Edges) {

1375 if (E->Count)

1376 continue;

1377 E->setEdgeCount(Value);

1378

1379 getBBInfo(E->SrcBB).UnknownCountOutEdge--;

1380 getBBInfo(E->DestBB).UnknownCountInEdge--;

1381 return;

1382 }

1384}

1385

1386

1388 const char MetadataName[] = "instr_prof_hash_mismatch";

1390

1391 auto *Existing = F.getMetadata(LLVMContext::MD_annotation);

1392 if (Existing) {

1394 for (const auto &N : Tuple->operands()) {

1395 if (N.equalsStr(MetadataName))

1396 return;

1398 }

1399 }

1400

1404 F.setMetadata(LLVMContext::MD_annotation, MD);

1405}

1406

1407void PGOUseFunc::handleInstrProfError(Error Err, uint64_t MismatchedFuncSum) {

1408 handleAllErrors(std::move(Err), [&](const InstrProfError &IPE) {

1409 auto &Ctx = M->getContext();

1410 auto Err = IPE.get();

1411 bool SkipWarning = false;

1412 LLVM_DEBUG(dbgs() << "Error in reading profile for Func "

1413 << FuncInfo.FuncName << ": ");

1414 if (Err == instrprof_error::unknown_function) {

1415 IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;

1418 } else if (Err == instrprof_error::hash_mismatch ||

1419 Err == instrprof_error::malformed) {

1420 IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;

1421 SkipWarning =

1426 LLVM_DEBUG(dbgs() << "hash mismatch (hash= " << FuncInfo.FunctionHash

1427 << " skip=" << SkipWarning << ")");

1428

1430 }

1431

1433 if (SkipWarning)

1434 return;

1435

1436 std::string Msg =

1437 IPE.message() + std::string(" ") + F.getName().str() +

1438 std::string(" Hash = ") + std::to_string(FuncInfo.FunctionHash) +

1439 std::string(" up to ") + std::to_string(MismatchedFuncSum) +

1440 std::string(" count discarded");

1441

1442 Ctx.diagnose(

1443 DiagnosticInfoPGOProfile(M->getName().data(), Msg, DS_Warning));

1444 });

1445}

1446

1447bool PGOUseFunc::getRecord(IndexedInstrProfReader *PGOReader) {

1448 uint64_t MismatchedFuncSum = 0;

1450 FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,

1451 &MismatchedFuncSum);

1453 handleInstrProfError(std::move(E), MismatchedFuncSum);

1454 return false;

1455 }

1456 ProfileRecord = std::move(Result.get());

1458 return true;

1459}

1460

1461

1462

1463

1464bool PGOUseFunc::readCounters(bool &AllZeros,

1466 auto &Ctx = M->getContext();

1469 return true;

1470 }

1471 std::vector<uint64_t> &CountFromProfile = ProfileRecord.Counts;

1472

1473 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;

1474 LLVM_DEBUG(dbgs() << CountFromProfile.size() << " counts\n");

1475

1476 uint64_t ValueSum = 0;

1477 for (unsigned I = 0, S = CountFromProfile.size(); I < S; I++) {

1478 LLVM_DEBUG(dbgs() << " " << I << ": " << CountFromProfile[I] << "\n");

1479 ValueSum += CountFromProfile[I];

1480 }

1481 AllZeros = (ValueSum == 0);

1482

1484

1485 getBBInfo(nullptr).UnknownCountOutEdge = 2;

1486 getBBInfo(nullptr).UnknownCountInEdge = 2;

1487

1488 if (!setInstrumentedCounts(CountFromProfile)) {

1490 dbgs() << "Inconsistent number of counts, skipping this function");

1491 Ctx.diagnose(DiagnosticInfoPGOProfile(

1492 M->getName().data(),

1493 Twine("Inconsistent number of counts in ") + F.getName().str() +

1494 Twine(": the profile may be stale or there is a function name "

1495 "collision."),

1497 return false;

1498 }

1499 return true;

1500}

1501

1502void PGOUseFunc::populateCoverage() {

1503 IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;

1504

1505 ArrayRef<uint64_t> CountsFromProfile = ProfileRecord.Counts;

1506 DenseMap<const BasicBlock *, bool> Coverage;

1507 unsigned Index = 0;

1508 for (auto &BB : F)

1509 if (FuncInfo.BCI->shouldInstrumentBlock(BB))

1510 Coverage[&BB] = (CountsFromProfile[Index++] != 0);

1511 assert(Index == CountsFromProfile.size());

1512

1513

1514 DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>

1515 InverseDependencies;

1516 for (auto &BB : F) {

1517 for (auto *Dep : FuncInfo.BCI->getDependencies(BB)) {

1518

1519 InverseDependencies[Dep].insert(&BB);

1520 }

1521 }

1522

1523

1524 std::stack<const BasicBlock *> CoveredBlocksToProcess;

1525 for (auto &[BB, IsCovered] : Coverage)

1526 if (IsCovered)

1527 CoveredBlocksToProcess.push(BB);

1528

1529 while (!CoveredBlocksToProcess.empty()) {

1530 auto *CoveredBlock = CoveredBlocksToProcess.top();

1531 assert(Coverage[CoveredBlock]);

1532 CoveredBlocksToProcess.pop();

1533 for (auto *BB : InverseDependencies[CoveredBlock]) {

1534

1536 if (Cov)

1537 continue;

1538 Cov = true;

1539 CoveredBlocksToProcess.push(BB);

1540 }

1541 }

1542

1543

1544 MDBuilder MDB(F.getContext());

1545

1546

1547 F.setEntryCount(Coverage[&F.getEntryBlock()] ? 10000 : 0);

1548 for (auto &BB : F) {

1549

1550

1551

1552

1553

1554

1555 SmallVector<uint32_t, 4> Weights;

1557 Weights.push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);

1558 if (Weights.size() >= 2)

1560 false);

1561 }

1562

1563 unsigned NumCorruptCoverage = 0;

1564 DominatorTree DT(F);

1565 LoopInfo LI(DT);

1566 BranchProbabilityInfo BPI(F, LI);

1567 BlockFrequencyInfo BFI(F, BPI, LI);

1568 auto IsBlockDead = [&](const BasicBlock &BB) -> std::optional {

1570 return C == 0;

1571 return {};

1572 };

1573 LLVM_DEBUG(dbgs() << "Block Coverage: (Instrumented=*, Covered=X)\n");

1574 for (auto &BB : F) {

1575 LLVM_DEBUG(dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ? "* " : " ")

1576 << (Coverage[&BB] ? "X " : " ") << " " << BB.getName()

1577 << "\n");

1578

1579

1580

1581

1582 const bool &Cov = Coverage[&BB];

1583 if (Cov == IsBlockDead(BB).value_or(false)) {

1585 dbgs() << "Found inconsistent block covearge for " << BB.getName()

1586 << ": BCI=" << (Cov ? "Covered" : "Dead") << " BFI="

1587 << (IsBlockDead(BB).value() ? "Dead" : "Covered") << "\n");

1588 ++NumCorruptCoverage;

1589 }

1590 if (Cov)

1591 ++NumCoveredBlocks;

1592 }

1594 auto &Ctx = M->getContext();

1595 Ctx.diagnose(DiagnosticInfoPGOProfile(

1596 M->getName().data(),

1597 Twine("Found inconsistent block coverage for function ") + F.getName() +

1598 " in " + Twine(NumCorruptCoverage) + " blocks.",

1600 }

1602 FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);

1603}

1604

1605

1606

1607void PGOUseFunc::populateCounters() {

1608 bool Changes = true;

1609 unsigned NumPasses = 0;

1610 while (Changes) {

1611 NumPasses++;

1612 Changes = false;

1613

1614

1615

1616 for (auto &BB : reverse(F)) {

1617 PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);

1618 if (UseBBInfo == nullptr)

1619 continue;

1620 if (!UseBBInfo->Count) {

1621 if (UseBBInfo->UnknownCountOutEdge == 0) {

1622 UseBBInfo->Count = sumEdgeCount(UseBBInfo->OutEdges);

1623 Changes = true;

1624 } else if (UseBBInfo->UnknownCountInEdge == 0) {

1625 UseBBInfo->Count = sumEdgeCount(UseBBInfo->InEdges);

1626 Changes = true;

1627 }

1628 }

1629 if (UseBBInfo->Count) {

1630 if (UseBBInfo->UnknownCountOutEdge == 1) {

1631 uint64_t Total = 0;

1632 uint64_t OutSum = sumEdgeCount(UseBBInfo->OutEdges);

1633

1634

1635

1636 if (*UseBBInfo->Count > OutSum)

1637 Total = *UseBBInfo->Count - OutSum;

1638 setEdgeCount(UseBBInfo->OutEdges, Total);

1639 Changes = true;

1640 }

1641 if (UseBBInfo->UnknownCountInEdge == 1) {

1642 uint64_t Total = 0;

1643 uint64_t InSum = sumEdgeCount(UseBBInfo->InEdges);

1644 if (*UseBBInfo->Count > InSum)

1645 Total = *UseBBInfo->Count - InSum;

1646 setEdgeCount(UseBBInfo->InEdges, Total);

1647 Changes = true;

1648 }

1649 }

1650 }

1651 }

1652

1653 LLVM_DEBUG(dbgs() << "Populate counts in " << NumPasses << " passes.\n");

1654 (void)NumPasses;

1655#ifndef NDEBUG

1656

1657 for (auto &BB : F) {

1658 auto BI = findBBInfo(&BB);

1659 if (BI == nullptr)

1660 continue;

1661 assert(BI->Count && "BB count is not valid");

1662 }

1663#endif

1664

1665 FuncInfo.SIVisitor.annotateSelects(this, &CountPosition);

1666 assert(CountPosition == ProfileCountSize);

1667

1668 uint64_t FuncEntryCount = *getBBInfo(&*F.begin()).Count;

1670 for (auto &BB : F) {

1671 auto BI = findBBInfo(&BB);

1672 if (BI == nullptr)

1673 continue;

1674 FuncMaxCount = std::max(FuncMaxCount, *BI->Count);

1675 }

1676

1677

1681 markFunctionAttributes(FuncEntryCount, FuncMaxCount);

1682

1683 LLVM_DEBUG(FuncInfo.dumpInfo("after reading profile."));

1684}

1685

1686

1687void PGOUseFunc::setBranchWeights() {

1688

1689 LLVM_DEBUG(dbgs() << "\nSetting branch weights for func " << F.getName()

1690 << " IsCS=" << IsCS << "\n");

1691 for (auto &BB : F) {

1694 continue;

1698 continue;

1699

1700 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);

1701 if (!*BBCountInfo.Count)

1702 continue;

1703

1704

1705

1706

1707

1708 unsigned OutEdgesCount = BBCountInfo.OutEdges.size();

1709 unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();

1710 assert(OutEdgesCount <= SuccessorCount);

1711

1713 uint64_t MaxCount = 0;

1714 for (unsigned It = 0; It < OutEdgesCount; It++) {

1715 const PGOUseEdge *E = BBCountInfo.OutEdges[It];

1718 if (DestBB == nullptr)

1719 continue;

1721 uint64_t EdgeCount = *E->Count;

1722 if (EdgeCount > MaxCount)

1723 MaxCount = EdgeCount;

1724 EdgeCounts[SuccNum] = EdgeCount;

1725 }

1726

1727 if (MaxCount)

1729 else {

1730

1731

1732

1733 auto &Ctx = M->getContext();

1734 Ctx.diagnose(DiagnosticInfoPGOProfile(

1735 M->getName().data(),

1736 Twine("Profile in ") + F.getName().str() +

1737 Twine(" partially ignored") +

1738 Twine(", possibly due to the lack of a return path."),

1740 }

1741 }

1742}

1743

1747 return true;

1748 }

1749 return false;

1750}

1751

1752void PGOUseFunc::annotateIrrLoopHeaderWeights() {

1753 LLVM_DEBUG(dbgs() << "\nAnnotating irreducible loop header weights.\n");

1754

1755 for (auto &BB : F) {

1756

1757

1758

1761 const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);

1763 }

1764 }

1765}

1766

1767void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {

1770 Type *Int64Ty = Builder.getInt64Ty();

1771 auto *Step = Builder.CreateZExt(SI.getCondition(), Int64Ty);

1772 auto *NormalizedFuncNameVarPtr =

1774 FuncNameVar, PointerType::get(M->getContext(), 0));

1775 Builder.CreateIntrinsic(Intrinsic::instrprof_increment_step,

1776 {NormalizedFuncNameVarPtr, Builder.getInt64(FuncHash),

1777 Builder.getInt32(TotalNumCtrs),

1778 Builder.getInt32(*CurCtrIdx), Step});

1779 ++(*CurCtrIdx);

1780}

1781

1782void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {

1783 std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;

1784 assert(*CurCtrIdx < CountFromProfile.size() &&

1785 "Out of bound access of counters");

1786 uint64_t SCounts[2];

1787 SCounts[0] = CountFromProfile[*CurCtrIdx];

1788 ++(*CurCtrIdx);

1789 uint64_t TotalCount = 0;

1790 auto BI = UseFunc->findBBInfo(SI.getParent());

1791 if (BI != nullptr) {

1792 TotalCount = *BI->Count;

1793

1794

1795 if (TotalCount < SCounts[0])

1796 BI->Count = SCounts[0];

1797 }

1798

1799 SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);

1800 uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);

1801 if (MaxCount)

1803}

1804

1805void SelectInstVisitor::visitSelectInst(SelectInst &SI) {

1807 return;

1808

1809 if (SI.getCondition()->getType()->isVectorTy())

1810 return;

1811

1812 switch (Mode) {

1813 case VM_counting:

1814 NSIs++;

1815 return;

1816 case VM_instrument:

1817 instrumentOneSelectInst(SI);

1818 return;

1819 case VM_annotate:

1820 annotateOneSelectInst(SI);

1821 return;

1822 }

1823

1825}

1826

1828 if (ValueProfKind == IPVK_MemOPSize)

1830 if (ValueProfKind == llvm::IPVK_VTableTarget)

1833}

1834

1835

1836void PGOUseFunc::annotateValueSites() {

1838 return;

1839

1840

1842

1843 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)

1844 annotateValueSites(Kind);

1845}

1846

1847

1848void PGOUseFunc::annotateValueSites(uint32_t Kind) {

1849 assert(Kind <= IPVK_Last);

1850 unsigned ValueSiteIndex = 0;

1851

1853

1854

1855

1856

1857

1858

1859

1860

1861

1862

1863 if (NumValueSites > 0 && Kind == IPVK_VTableTarget &&

1864 NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&

1866 FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);

1867 auto &ValueSites = FuncInfo.ValueSites[Kind];

1869 auto &Ctx = M->getContext();

1870 Ctx.diagnose(DiagnosticInfoPGOProfile(

1871 M->getName().data(),

1872 Twine("Inconsistent number of value sites for ") +

1874 F.getName().str() +

1875 Twine("\", possibly due to the use of a stale profile."),

1877 return;

1878 }

1879

1881 LLVM_DEBUG(dbgs() << "Read one value site profile (kind = " << Kind

1882 << "): Index = " << ValueSiteIndex << " out of "

1885 *M, *I.AnnotatedInst, ProfileRecord,

1888 ValueSiteIndex++;

1889 }

1890}

1891

1892

1893

1896 std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {

1898 return;

1900 if (Comdat *C = F.getComdat())

1901 ComdatMembers.insert(std::make_pair(C, &F));

1903 if (Comdat *C = GV.getComdat())

1904 ComdatMembers.insert(std::make_pair(C, &GV));

1906 if (Comdat *C = GA.getComdat())

1907 ComdatMembers.insert(std::make_pair(C, &GA));

1908}

1909

1910

1912 if (F.isDeclaration())

1913 return true;

1914

1915

1916

1917 unsigned NumCriticalEdges = 0;

1918 for (auto &BB : F) {

1919 const Instruction *TI = BB.getTerminator();

1922 NumCriticalEdges++;

1923 }

1924 }

1927 << ", NumCriticalEdges=" << NumCriticalEdges

1928 << " exceed the threshold. Skip PGO.\n");

1929 return true;

1930 }

1931 return false;

1932}

1933

1934

1937 return true;

1938 if (F.hasFnAttribute(llvm::Attribute::Naked))

1939 return true;

1940 if (F.hasFnAttribute(llvm::Attribute::NoProfile))

1941 return true;

1942 if (F.hasFnAttribute(llvm::Attribute::SkipProfile))

1943 return true;

1945 return true;

1947 if (auto EntryCount = F.getEntryCount())

1950 }

1951 return false;

1952}

1953

1960

1961

1964

1965 Triple TT(M.getTargetTriple());

1969 M.getName().data(),

1970 Twine("VTable value profiling is presently not "

1971 "supported for non-ELF object formats"),

1973 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;

1975

1976 for (auto &F : M) {

1978 continue;

1983 FunctionInstrumenter FI(M, F, TLI, ComdatMembers, BPI, BFI, LI,

1984 InstrumentationType);

1985 FI.instrument();

1986 }

1987 return true;

1988}

1989

1990PreservedAnalyses

1993

1994

1997 if (ProfileSampling)

2002 return PA;

2003}

2004

2010 };

2013 };

2016 };

2019 };

2020

2022 InstrumentationType))

2024

2026}

2027

2028

2029

2034#ifndef NDEBUG

2035 auto BFIEntryCount = F.getEntryCount();

2036 assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&

2037 "Invalid BFI Entrycount");

2038#endif

2041 for (auto &BBI : F) {

2044 if (!Func.findBBInfo(&BBI))

2045 continue;

2047 CountValue = *Func.getBBInfo(&BBI).Count;

2048 BFICountValue = *BFICount;

2051 }

2052 if (SumCount.isZero())

2053 return;

2054

2056 "Incorrect sum of BFI counts");

2058 return;

2059 double Scale = (SumCount / SumBFICount).convertToDouble();

2060 if (Scale < 1.001 && Scale > 0.999)

2061 return;

2062

2065 if (NewEntryCount == 0)

2066 NewEntryCount = 1;

2069 LLVM_DEBUG(dbgs() << "FixFuncEntryCount: in " << F.getName()

2071 << NewEntryCount << "\n");

2072 }

2073}

2074

2075

2076

2083

2087

2088 unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;

2089 for (auto &BBI : F) {

2090 PGOUseBBInfo *BBInfo = Func.findBBInfo(&BBI);

2091 if (!BBInfo)

2092 continue;

2093

2094 uint64_t CountValue = BBInfo->Count.value_or(CountValue);

2096

2097 BBNum++;

2098 if (CountValue)

2099 NonZeroBBNum++;

2101 if (BFICount)

2102 BFICountValue = *BFICount;

2103

2104 if (HotBBOnly) {

2105 bool rawIsHot = CountValue >= HotCountThreshold;

2106 bool BFIIsHot = BFICountValue >= HotCountThreshold;

2108 bool ShowCount = false;

2109 if (rawIsHot && !BFIIsHot) {

2110 Msg = "raw-Hot to BFI-nonHot";

2111 ShowCount = true;

2112 } else if (rawIsCold && BFIIsHot) {

2113 Msg = "raw-Cold to BFI-Hot";

2114 ShowCount = true;

2115 }

2116 if (!ShowCount)

2117 continue;

2118 } else {

2121 continue;

2122 uint64_t Diff = (BFICountValue >= CountValue)

2123 ? BFICountValue - CountValue

2124 : CountValue - BFICountValue;

2126 continue;

2127 }

2128 BBMisMatchNum++;

2129

2130 ORE.emit([&]() {

2132 F.getSubprogram(), &BBI);

2133 Remark << "BB " << ore::NV("Block", BBI.getName())

2134 << " Count=" << ore::NV("Count", CountValue)

2135 << " BFI_Count=" << ore::NV("Count", BFICountValue);

2136 if (!Msg.empty())

2137 Remark << " (" << Msg << ")";

2139 });

2140 }

2141 if (BBMisMatchNum)

2142 ORE.emit([&]() {

2144 F.getSubprogram(), &F.getEntryBlock())

2145 << "In Func " << ore::NV("Function", F.getName())

2146 << ": Num_of_BB=" << ore::NV("Count", BBNum)

2147 << ", Num_of_non_zerovalue_BB=" << ore::NV("Count", NonZeroBBNum)

2148 << ", Num_of_mis_matching_BB=" << ore::NV("Count", BBMisMatchNum);

2149 });

2150}

2151

2159 bool IsCS) {

2161 auto &Ctx = M.getContext();

2162

2164 ProfileRemappingFileName);

2165 if (Error E = ReaderOrErr.takeError()) {

2167 Ctx.diagnose(

2169 });

2170 return false;

2171 }

2172

2173 std::unique_ptr PGOReader =

2174 std::move(ReaderOrErr.get());

2175 if (!PGOReader) {

2177 StringRef("Cannot get PGOReader")));

2178 return false;

2179 }

2180 if (!PGOReader->hasCSIRLevelProfile() && IsCS)

2181 return false;

2182

2183

2184 if (!PGOReader->isIRLevelProfile()) {

2186 ProfileFileName.data(), "Not an IR level instrumentation profile"));

2187 return false;

2188 }

2189 if (PGOReader->functionEntryOnly()) {

2191 ProfileFileName.data(),

2192 "Function entry profiles are not yet supported for optimization"));

2193 return false;

2194 }

2195

2198 if (G.hasName() || G.hasMetadata(LLVMContext::MD_type))

2199 continue;

2200

2201

2203 }

2204 }

2205

2206

2207

2208

2209 M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),

2213

2214 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;

2216 std::vector<Function *> HotFunctions;

2217 std::vector<Function *> ColdFunctions;

2218

2219

2220

2221 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();

2224 bool InstrumentLoopEntries = PGOReader->instrLoopEntriesEnabled();

2227

2228 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();

2229 for (auto &F : M) {

2231 continue;

2236 if (!HasSingleByteCoverage) {

2237

2238

2240 BFI);

2241 }

2242 PGOUseFunc Func(F, &M, TLI, ComdatMembers, BPI, BFI, LI, PSI, IsCS,

2243 InstrumentFuncEntry, InstrumentLoopEntries,

2244 HasSingleByteCoverage);

2245 if (!Func.getRecord(PGOReader.get()))

2246 continue;

2247 if (HasSingleByteCoverage) {

2248 Func.populateCoverage();

2249 continue;

2250 }

2251

2252

2253

2254

2256 bool AllZeros = false;

2257 if (!Func.readCounters(AllZeros, PseudoKind))

2258 continue;

2259 if (AllZeros) {

2261 if (Func.getProgramMaxCount() != 0)

2262 ColdFunctions.push_back(&F);

2263 continue;

2264 }

2266

2267 if (F.hasFnAttribute(Attribute::Cold))

2268 F.removeFnAttr(Attribute::Cold);

2269

2271 F.addFnAttr(Attribute::Hot);

2272 continue;

2273 }

2274 Func.populateCounters();

2275 Func.setBranchWeights();

2276 Func.annotateValueSites();

2277 Func.annotateIrrLoopHeaderWeights();

2278 PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();

2279 if (FreqAttr == PGOUseFunc::FFA_Cold)

2280 ColdFunctions.push_back(&F);

2281 else if (FreqAttr == PGOUseFunc::FFA_Hot)

2282 HotFunctions.push_back(&F);

2287 std::unique_ptr NewBPI =

2288 std::make_unique(F, LI);

2289 std::unique_ptr NewBFI =

2290 std::make_unique(F, *NewBPI, LI);

2292 NewBFI->view();

2294 dbgs() << "pgo-view-counts: " << Func.getFunc().getName() << "\n";

2295 NewBFI->print(dbgs());

2296 }

2297 }

2303 WriteGraph(&Func, Twine("PGORawCounts_") + Func.getFunc().getName());

2304 else

2305 ViewGraph(&Func, Twine("PGORawCounts_") + Func.getFunc().getName());

2307 dbgs() << "pgo-view-raw-counts: " << Func.getFunc().getName() << "\n";

2308 Func.dumpInfo();

2309 }

2310 }

2311

2315

2316

2319

2320

2325 }

2327 }

2328 }

2329

2330

2331

2332

2333

2334 for (auto &F : HotFunctions) {

2335 F->addFnAttr(Attribute::InlineHint);

2336 LLVM_DEBUG(dbgs() << "Set inline attribute to function: " << F->getName()

2337 << "\n");

2338 }

2339 for (auto &F : ColdFunctions) {

2340

2341

2342 if (F->hasFnAttribute(Attribute::Hot)) {

2343 auto &Ctx = M.getContext();

2344 std::string Msg = std::string("Function ") + F->getName().str() +

2345 std::string(" is annotated as a hot function but"

2346 " the profile is cold");

2347 Ctx.diagnose(

2349 continue;

2350 }

2351 F->addFnAttr(Attribute::Cold);

2352 LLVM_DEBUG(dbgs() << "Set cold attribute to function: " << F->getName()

2353 << "\n");

2354 }

2355 return true;

2356}

2357

2359 std::string Filename, std::string RemappingFilename, bool IsCS,

2361 : ProfileFileName(std::move(Filename)),

2362 ProfileRemappingFileName(std::move(RemappingFilename)), IsCS(IsCS),

2368 if (!FS)

2370}

2371

2374

2378 };

2381 };

2384 };

2387 };

2388

2390 if (annotateAllFunctions(M, ProfileFileName, ProfileRemappingFileName, *FS,

2391 LookupTLI, LookupBPI, LookupBFI, LookupLI, PSI,

2392 IsCS))

2394

2396}

2397

2399 if (Node->getName().empty())

2400 return Node->getName().str();

2401

2402 std::string SimpleNodeName;

2405 return SimpleNodeName;

2406}

2407

2411

2412 LLVM_DEBUG(dbgs() << "Weight is: "; for (const auto &W

2413 : Weights) {

2414 dbgs() << W << " ";

2415 } dbgs() << "\n";);

2416

2418

2422 if (BrCondStr.empty())

2423 return;

2424

2426 std::accumulate(Weights.begin(), Weights.end(), (uint64_t)0,

2429 std::accumulate(EdgeCounts.begin(), EdgeCounts.end(), (uint64_t)0,

2434 std::string BranchProbStr;

2436 OS << BP;

2437 OS << " (total count : " << TotalCount << ")";

2440 ORE.emit([&]() {

2442 << BrCondStr << " is true with probability : " << BranchProbStr;

2443 });

2444 }

2445}

2446

2447namespace llvm {

2448

2451 TI->setMetadata(llvm::LLVMContext::MD_irr_loop,

2453}

2454

2459

2461 return &G->getFunc().front();

2462 }

2463

2467

2469

2473

2477};

2478

2482

2484 return std::string(G->getFunc().getName());

2485 }

2486

2488 std::string Result;

2490

2492 PGOUseBBInfo *BI = Graph->findBBInfo(Node);

2493 OS << "Count : ";

2494 if (BI && BI->Count)

2495 OS << *BI->Count << "\\l";

2496 else

2497 OS << "Unknown\\l";

2498

2500 return Result;

2501

2504 continue;

2505

2506 OS << "SELECT : { T = ";

2509 if (!HasProf)

2510 OS << "Unknown, F = Unknown }\\l";

2511 else

2512 OS << TC << ", F = " << FC << " }\\l";

2513 }

2514 return Result;

2515 }

2516};

2517

2518}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file implements a class to represent arbitrary precision integral constant values and operations...

Function Alias Analysis false

This file contains the simple types necessary to represent the attributes associated with functions a...

This file finds the minimum set of blocks on a CFG that must be instrumented to infer execution cover...

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

#define clEnumValN(ENUMVAL, FLAGNAME, DESC)

This file contains the declarations for the subclasses of Constant, which represent the different fla...

post inline ee instrument

static BasicBlock * getInstrBB(CFGMST< Edge, BBInfo > &MST, Edge &E, const DenseSet< const BasicBlock * > &ExecBlocks)

This file provides various utilities for inspecting and working with the control flow graph in LLVM I...

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

#define INSTR_PROF_QUOTE(x)

#define VARIANT_MASK_CSIR_PROF

#define VARIANT_MASK_DBG_CORRELATE

#define INSTR_PROF_RAW_VERSION

#define INSTR_PROF_RAW_VERSION_VAR

#define VARIANT_MASK_TEMPORAL_PROF

#define VARIANT_MASK_IR_PROF

#define VARIANT_MASK_BYTE_COVERAGE

#define VARIANT_MASK_INSTR_ENTRY

#define VARIANT_MASK_FUNCTION_ENTRY_ONLY

#define VARIANT_MASK_INSTR_LOOP_ENTRIES

Machine Check Debug Module

static cl::opt< unsigned > ColdCountThreshold("mfs-count-threshold", cl::desc("Minimum number of times a block must be executed to be retained."), cl::init(1), cl::Hidden)

static GlobalVariable * createIRLevelProfileFlagVar(Module &M, PGOInstrumentationType InstrumentationType)

Definition PGOInstrumentation.cpp:447

static cl::opt< std::string > PGOTestProfileRemappingFile("pgo-test-profile-remapping-file", cl::init(""), cl::Hidden, cl::value_desc("filename"), cl::desc("Specify the path of profile remapping file. This is mainly for " "test purpose."))

static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI, BranchProbabilityInfo &NBPI)

Definition PGOInstrumentation.cpp:2030

static void annotateFunctionWithHashMismatch(Function &F, LLVMContext &ctx)

Definition PGOInstrumentation.cpp:1387

static cl::opt< unsigned > MaxNumMemOPAnnotations("memop-max-annotations", cl::init(4), cl::Hidden, cl::desc("Max number of precise value annotations for a single memop" "intrinsic"))

static cl::opt< unsigned > MaxNumAnnotations("icp-max-annotations", cl::init(3), cl::Hidden, cl::desc("Max number of annotations for a single indirect " "call callsite"))

static bool skipPGOGen(const Function &F)

Definition PGOInstrumentation.cpp:1935

static void collectComdatMembers(Module &M, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)

Definition PGOInstrumentation.cpp:1894

static void populateEHOperandBundle(VPCandidateInfo &Cand, DenseMap< BasicBlock *, ColorVector > &BlockColors, SmallVectorImpl< OperandBundleDef > &OpBundles)

Definition PGOInstrumentation.cpp:902

static void verifyFuncBFI(PGOUseFunc &Func, LoopInfo &LI, BranchProbabilityInfo &NBPI, uint64_t HotCountThreshold, uint64_t ColdCountThreshold)

Definition PGOInstrumentation.cpp:2077

static cl::opt< bool > DoComdatRenaming("do-comdat-renaming", cl::init(false), cl::Hidden, cl::desc("Append function hash to the name of COMDAT function to avoid " "function hash mismatch due to the preinliner"))

static bool annotateAllFunctions(Module &M, StringRef ProfileFileName, StringRef ProfileRemappingFileName, vfs::FileSystem &FS, function_ref< TargetLibraryInfo &(Function &)> LookupTLI, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI, function_ref< LoopInfo *(Function &)> LookupLI, ProfileSummaryInfo *PSI, bool IsCS)

Definition PGOInstrumentation.cpp:2152

static void setupBBInfoEdges(const FuncPGOInstrumentation< PGOUseEdge, PGOUseBBInfo > &FuncInfo)

Set up InEdges/OutEdges for all BBs in the MST.

Definition PGOInstrumentation.cpp:1283

static bool skipPGOUse(const Function &F)

Definition PGOInstrumentation.cpp:1911

static bool canRenameComdat(Function &F, std::unordered_multimap< Comdat *, GlobalValue * > &ComdatMembers)

Definition PGOInstrumentation.cpp:755

ValueProfileCollector::CandidateInfo VPCandidateInfo

Definition PGOInstrumentation.cpp:132

static bool InstrumentAllFunctions(Module &M, function_ref< TargetLibraryInfo &(Function &)> LookupTLI, function_ref< BranchProbabilityInfo *(Function &)> LookupBPI, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI, function_ref< LoopInfo *(Function &)> LookupLI, PGOInstrumentationType InstrumentationType)

Definition PGOInstrumentation.cpp:1954

static uint64_t sumEdgeCount(const ArrayRef< PGOUseEdge * > Edges)

Definition PGOInstrumentation.cpp:1148

static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind)

Definition PGOInstrumentation.cpp:1827

static cl::opt< bool > DisableValueProfiling("disable-vp", cl::init(false), cl::Hidden, cl::desc("Disable Value Profiling"))

static std::string getSimpleNodeName(const BasicBlock *Node)

Definition PGOInstrumentation.cpp:2398

static bool isIndirectBrTarget(BasicBlock *BB)

Definition PGOInstrumentation.cpp:1744

static cl::opt< std::string > PGOTestProfileFile("pgo-test-profile-file", cl::init(""), cl::Hidden, cl::value_desc("filename"), cl::desc("Specify the path of profile data file. This is " "mainly for test purpose."))

static std::string getBranchCondString(Instruction *TI)

Definition PGOInstrumentation.cpp:409

static const char * ValueProfKindDescr[]

Definition PGOInstrumentation.cpp:439

This file provides the interface for IR based instrumentation passes ( (profile-gen,...

FunctionAnalysisManager FAM

ModuleAnalysisManager MAM

This file contains the declarations for profiling metadata utility functions.

const SmallVectorImpl< MachineOperand > & Cond

static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))

void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)

std::pair< BasicBlock *, BasicBlock * > Edge

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

StringSet - A set-like wrapper for the StringMap.

Defines the virtual file system interface vfs::FileSystem.

void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const

static const fltSemantics & IEEEdouble()

static constexpr roundingMode rmNearestTiesToEven

static APFloat getZero(const fltSemantics &Sem, bool Negative=false)

Factory for Positive and Negative Zero.

Class for arbitrary precision integers.

This templated class represents "all analyses that operate over " (e....

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

LLVM Basic Block Representation.

LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const

Returns an iterator to the first instruction in this block that is not a PHINode instruction.

InstListType::iterator iterator

Instruction iterators...

LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const

Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

Analysis pass which computes BlockFrequencyInfo.

BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...

LLVM_ABI bool isIrrLoopHeader(const BasicBlock *BB)

Returns true if BB is an irreducible loop header block.

LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const

Returns the estimated profile count of BB.

Conditional or Unconditional Branch instruction.

bool isConditional() const

Value * getCondition() const

Analysis pass which computes BranchProbabilityInfo.

Analysis providing branch probability information.

Edge & addEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W)

const std::vector< std::unique_ptr< Edge > > & allEdges() const

Predicate getPredicate() const

Return the predicate for this instruction.

LLVM_ABI StringRef getName() const

void setSelectionKind(SelectionKind Val)

SelectionKind getSelectionKind() const

static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)

Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.

This is the shared class of boolean and integer constants.

bool isMinusOne() const

This function will return true iff every bit in this constant is set to true.

bool isOne() const

This is just a convenience method to make client code smaller for a common case.

bool isZero() const

This is just a convenience method to make client code smaller for a common code.

static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)

Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Diagnostic information for the PGO profiler.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

Base class for error info classes.

virtual std::string message() const

Return the error message as a string.

Lightweight error class with error context and mandatory checking.

Class to represent profile counts.

static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)

If a parent module is specified, the alias is automatically inserted into the end of the specified mo...

@ HiddenVisibility

The GV is hidden.

@ ProtectedVisibility

The GV is protected.

@ ExternalLinkage

Externally visible function.

@ WeakAnyLinkage

Keep one copy of named function when linking (weak)

@ AvailableExternallyLinkage

Available for inspection, not emission.

@ LinkOnceODRLinkage

Same, but only replaced by something equivalent.

This instruction compares its operands according to the predicate given to the constructor.

static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const Twine &RemappingPath="")

Factory method to create an indexed reader.

uint64_t getMaximumFunctionCount(bool UseCS)

Return the maximum of all known function counts.

Expected< NamedInstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, StringRef DeprecatedFuncName="", uint64_t *MismatchedFuncSum=nullptr)

Return the NamedInstrProfRecord associated with FuncName and FuncHash.

Base class for instruction visitors.

static bool canInstrumentCallsite(const CallBase &CB)

instrprof_error get() const

std::string message() const override

Return the error message as a string.

LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY

Return the number of successors that this instruction has.

LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)

Set the metadata of the specified kind to the specified node.

A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...

LLVM_ABI void update(ArrayRef< uint8_t > Data)

This is an important class for using LLVM in a threaded context.

LLVM_ABI void diagnose(const DiagnosticInfo &DI)

Report a message to the currently installed diagnostic handler.

Analysis pass that exposes the LoopInfo for a function.

LLVM_ABI MDString * createString(StringRef Str)

Return the given string as metadata.

LLVM_ABI MDNode * createIrrLoopHeaderWeight(uint64_t Weight)

Return metadata containing an irreducible loop header weight.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

A Module instance is used to store all the information related to an LLVM module.

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)

Definition PGOInstrumentation.cpp:1991

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)

Definition PGOInstrumentation.cpp:2005

LLVM_ABI PGOInstrumentationUse(std::string Filename="", std::string RemappingFilename="", bool IsCS=false, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr)

Definition PGOInstrumentation.cpp:2358

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)

Definition PGOInstrumentation.cpp:2372

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

PreservedAnalyses & preserveSet()

Mark an analysis set as preserved.

PreservedAnalyses & preserve()

Mark an analysis as preserved.

An analysis pass based on the new PM to deliver ProfileSummaryInfo.

Analysis providing profile information.

LLVM_ABI uint64_t getOrCompColdCountThreshold() const

Returns ColdCountThreshold if set.

LLVM_ABI bool isColdCount(uint64_t C) const

Returns true if count C is considered cold.

LLVM_ABI void refresh(std::unique_ptr< ProfileSummary > &&Other=nullptr)

If a summary is provided as argument, use that.

LLVM_ABI bool isHotCount(uint64_t C) const

Returns true if count C is considered hot.

LLVM_ABI uint64_t getOrCompHotCountThreshold() const

Returns HotCountThreshold if set.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

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.

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Analysis pass providing the TargetLibraryInfo.

Provides information about what library functions are available for the current target.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM_ABI std::string str() const

Return the twine contents as a std::string.

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)

LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const

Print the current type.

Value * getOperand(unsigned i) const

std::vector< CandidateInfo > get(InstrProfValueKind Kind) const

returns a list of value profiling candidates of the given kind

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

An efficient, type-erasing, non-owning reference to a callable.

const ParentTy * getParent() const

A raw_ostream that writes to an std::string.

The virtual file system interface.

This provides a very simple, boring adaptor for a begin and end iterator into a range type.

This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.

#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.

LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

ValuesClass values(OptsTy... Options)

Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...

initializer< Ty > init(const Ty &Val)

uint64_t getFuncHash(const FuncRecordTy *Record)

Return the structural hash associated with the function.

void checkExpectAnnotations(const Instruction &I, ArrayRef< uint32_t > ExistingWeights, bool IsFrontend)

checkExpectAnnotations - compares PGO counters to the thresholds used for llvm.expect and warns if th...

DiagnosticInfoOptimizationBase::Argument NV

NodeAddr< FuncNode * > Func

friend class Instruction

Iterator for Instructions in a `BasicBlock.

void write64le(void *P, uint64_t V)

LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()

Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.

This is an optimization pass for GlobalISel generic memory operations.

static cl::opt< bool > PGOTreatUnknownAsCold("pgo-treat-unknown-as-cold", cl::init(false), cl::Hidden, cl::desc("For cold function instrumentation, treat count unknown(e.g. " "unprofiled) functions as cold."))

FunctionAddr VTableAddr Value

static cl::opt< bool > PGOInstrMemOP("pgo-instr-memop", cl::init(true), cl::Hidden, cl::desc("Use this option to turn on/off " "memory intrinsic size profiling."))

LLVM_ABI void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count)

Definition PGOInstrumentation.cpp:2449

LLVM_ABI void setProfMetadata(Instruction *TI, ArrayRef< uint64_t > EdgeCounts, uint64_t MaxCount)

Definition PGOInstrumentation.cpp:2408

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

LLVM_ABI std::string getPGOFuncName(const Function &F, bool InLTO=false, uint64_t Version=INSTR_PROF_INDEX_VERSION)

Please use getIRPGOFuncName for LLVM IR instrumentation.

static cl::opt< bool > PGOViewBlockCoverageGraph("pgo-view-block-coverage-graph", cl::desc("Create a dot file of CFGs with block " "coverage inference information"))

LLVM_ABI void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName)

Create the PGOFuncName meta data if PGOFuncName is different from function's raw name.

LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)

Search for the specified successor of basic block BB and return its position in the terminator instru...

LLVM_ABI std::string getIRPGOFuncName(const Function &F, bool InLTO=false)

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto successors(const MachineBasicBlock *BB)

LLVM_ABI void createProfileSamplingVar(Module &M)

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

constexpr from_range_t from_range

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)

If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...

LLVM_ABI void createPGONameMetadata(GlobalObject &GO, StringRef PGOName)

Create the PGOName metadata if a global object's PGO name is different from its mangled name.

InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy

Provide the FunctionAnalysisManager to Module proxy.

static cl::opt< bool > PGOBlockCoverage("pgo-block-coverage", cl::desc("Use this option to enable basic block coverage instrumentation"))

cl::opt< bool > PGOWarnMissing

raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")

cl::opt< unsigned > MaxNumVTableAnnotations("icp-max-num-vtables", cl::init(6), cl::Hidden, cl::desc("Max number of vtables annotated for a vtable load instruction."))

static cl::opt< bool > PGOTemporalInstrumentation("pgo-temporal-instrumentation", cl::desc("Use this option to enable temporal instrumentation"))

LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)

cl::opt< bool > EnableVTableProfileUse("enable-vtable-profile-use", cl::init(false), cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable " "profiles will be used by ICP pass for more efficient indirect " "call sequence. If false, type profiles won't be used."))

bool isScopedEHPersonality(EHPersonality Pers)

Returns true if this personality uses scope-style EH IR instructions: catchswitch,...

LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)

Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...

LLVM_ABI std::string getPGOName(const GlobalVariable &V, bool InLTO=false)

cl::opt< std::string > ViewBlockFreqFuncName("view-bfi-func-name", cl::Hidden, cl::desc("The option to specify " "the name of the function " "whose CFG will be displayed."))

LLVM_ABI GlobalVariable * createPGOFuncNameVar(Function &F, StringRef PGOFuncName)

Create and return the global variable for function name used in PGO instrumentation.

LLVM_ABI void annotateValueSite(Module &M, Instruction &Inst, const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIndx, uint32_t MaxMDCount=3)

Get the value profile data for value site SiteIdx from InstrProfR and annotate the instruction Inst w...

auto reverse(ContainerTy &&C)

static cl::opt< bool > EmitBranchProbability("pgo-emit-branch-prob", cl::init(false), cl::Hidden, cl::desc("When this option is on, the annotated " "branch probability will be emitted as " "optimization remarks: -{Rpass|" "pass-remarks}=pgo-instrumentation"))

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionAddr NumValueSites[IPVK_Last+1]

FunctionAddr VTableAddr Count

Function::ProfileCount ProfileCount

static cl::opt< unsigned > PGOVerifyBFIRatio("pgo-verify-bfi-ratio", cl::init(2), cl::Hidden, cl::desc("Set the threshold for pgo-verify-bfi: only print out " "mismatched BFI if the difference percentage is greater than " "this value (in percentage)."))

static cl::opt< bool > PGOInstrumentLoopEntries("pgo-instrument-loop-entries", cl::init(false), cl::Hidden, cl::desc("Force to instrument loop entries."))

static cl::opt< unsigned > PGOFunctionSizeThreshold("pgo-function-size-threshold", cl::Hidden, cl::desc("Do not instrument functions smaller than this threshold."))

LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)

See if the given exception handling personality function is one that we understand.

static cl::opt< bool > PGOFixEntryCount("pgo-fix-entry-count", cl::init(true), cl::Hidden, cl::desc("Fix function entry count in profile use."))

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

static cl::opt< PGOViewCountsType > PGOViewRawCounts("pgo-view-raw-counts", cl::Hidden, cl::desc("A boolean option to show CFG dag or text " "with raw profile counts from " "profile data. See also option " "-pgo-view-counts. To limit graph " "display to only one function, use " "filtering option -view-bfi-func-name."), cl::values(clEnumValN(PGOVCT_None, "none", "do not show."), clEnumValN(PGOVCT_Graph, "graph", "show a graph."), clEnumValN(PGOVCT_Text, "text", "show in text.")))

static cl::opt< bool > PGOVerifyBFI("pgo-verify-bfi", cl::init(false), cl::Hidden, cl::desc("Print out mismatched BFI counts after setting profile metadata " "The print is enabled under -Rpass-analysis=pgo, or " "internal option -pass-remarks-analysis=pgo."))

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

cl::opt< bool > NoPGOWarnMismatch

RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)

static cl::opt< uint64_t > PGOColdInstrumentEntryThreshold("pgo-cold-instrument-entry-threshold", cl::init(0), cl::Hidden, cl::desc("For cold function instrumentation, skip instrumenting functions " "whose entry count is above the given value."))

FunctionAddr VTableAddr uintptr_t uintptr_t Data

IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >

cl::opt< PGOViewCountsType > PGOViewCounts("pgo-view-counts", cl::Hidden, cl::desc("A boolean option to show CFG dag or text with " "block profile counts and branch probabilities " "right after PGO profile annotation step. The " "profile counts are computed using branch " "probabilities from the runtime profile data and " "block frequency propagation algorithm. To view " "the raw counts from the profile, use option " "-pgo-view-raw-counts instead. To limit graph " "display to only one function, use filtering option " "-view-bfi-func-name."), cl::values(clEnumValN(PGOVCT_None, "none", "do not show."), clEnumValN(PGOVCT_Graph, "graph", "show a graph."), clEnumValN(PGOVCT_Text, "text", "show in text.")))

Definition PGOInstrumentation.cpp:351

RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)

OperandBundleDefT< Value * > OperandBundleDef

LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)

Adds global values to the llvm.compiler.used list.

static cl::opt< unsigned > PGOVerifyBFICutoff("pgo-verify-bfi-cutoff", cl::init(5), cl::Hidden, cl::desc("Set the threshold for pgo-verify-bfi: skip the counts whose " "profile count value is below."))

LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")

If this edge is a critical edge, insert a new node to split the critical edge.

void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)

ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.

LLVM_ABI bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)

Return true if the specified edge is a critical edge.

cl::opt< bool > PGOInstrumentColdFunctionOnly

cl::list< std::string > CtxPGOSkipCallsiteInstrument("ctx-prof-skip-callsite-instr", cl::Hidden, cl::desc("Do not instrument callsites to functions in this list. Intended " "for testing."))

LLVM_ABI bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken=false)

Check if we can safely rename this Comdat function.

static cl::opt< bool > PGOInstrSelect("pgo-instr-select", cl::init(true), cl::Hidden, cl::desc("Use this option to turn on/off SELECT " "instruction instrumentation. "))

LLVM_ABI void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput)

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

TinyPtrVector< BasicBlock * > ColorVector

LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)

Extract branch weights from MD_prof metadata.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

auto predecessors(const MachineBasicBlock *BB)

llvm:🆑:opt< llvm::InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate

Definition PGOInstrumentation.cpp:362

static cl::opt< bool > PGOFunctionEntryCoverage("pgo-function-entry-coverage", cl::Hidden, cl::desc("Use this option to enable function entry coverage instrumentation."))

static cl::opt< unsigned > PGOFunctionCriticalEdgeThreshold("pgo-critical-edge-threshold", cl::init(20000), cl::Hidden, cl::desc("Do not instrument functions with the number of critical edges " " greater than this threshold."))

uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)

Scale an individual branch count.

static cl::opt< bool > PGOVerifyHotBFI("pgo-verify-hot-bfi", cl::init(false), cl::Hidden, cl::desc("Print out the non-match BFI count if a hot raw profile count " "becomes non-hot, or a cold raw profile count becomes hot. " "The print is enabled under -Rpass-analysis=pgo, or " "internal option -pass-remarks-analysis=pgo."))

SuccIterator< const Instruction, const BasicBlock > const_succ_iterator

uint64_t calculateCountScale(uint64_t MaxCount)

Calculate what to divide by to scale counts.

LLVM_ABI SmallVector< uint32_t > downscaleWeights(ArrayRef< uint64_t > Weights, std::optional< uint64_t > KnownMaxCount=std::nullopt)

downscale the given weights preserving the ratio.

LLVM_ABI bool isGPUProfTarget(const Module &M)

Determines whether module targets a GPU eligable for PGO instrumentation.

cl::opt< bool > EnableVTableValueProfiling("enable-vtable-value-profiling", cl::init(false), cl::desc("If true, the virtual table address will be instrumented to know " "the types of a C++ pointer. The information is used in indirect " "call promotion to do selective vtable-based comparison."))

static cl::opt< bool > PGOInstrumentEntry("pgo-instrument-entry", cl::init(false), cl::Hidden, cl::desc("Force to instrument function entry basicblock."))

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

static cl::opt< std::string > PGOTraceFuncHash("pgo-trace-func-hash", cl::init("-"), cl::Hidden, cl::value_desc("function name"), cl::desc("Trace the hash of the function with this name."))

cl::opt< bool > NoPGOWarnMismatchComdatWeak

Implement std::hash so that hash_code can be used in STL containers.

DOTGraphTraits(bool isSimple=false)

Definition PGOInstrumentation.cpp:2480

static std::string getGraphName(const PGOUseFunc *G)

Definition PGOInstrumentation.cpp:2483

std::string getNodeLabel(const BasicBlock *Node, const PGOUseFunc *Graph)

Definition PGOInstrumentation.cpp:2487

DefaultDOTGraphTraits(bool simple=false)

static ChildIteratorType child_end(const NodeRef N)

Definition PGOInstrumentation.cpp:2468

static NodeRef getEntryNode(const PGOUseFunc *G)

Definition PGOInstrumentation.cpp:2460

static ChildIteratorType child_begin(const NodeRef N)

Definition PGOInstrumentation.cpp:2464

static nodes_iterator nodes_end(const PGOUseFunc *G)

Definition PGOInstrumentation.cpp:2474

const BasicBlock * NodeRef

Definition PGOInstrumentation.cpp:2456

static nodes_iterator nodes_begin(const PGOUseFunc *G)

Definition PGOInstrumentation.cpp:2470

pointer_iterator< Function::const_iterator > nodes_iterator

Definition PGOInstrumentation.cpp:2458

const_succ_iterator ChildIteratorType

Definition PGOInstrumentation.cpp:2457

std::vector< uint64_t > Counts

CountPseudoKind getCountPseudoKind() const

uint32_t getNumValueSites(uint32_t ValueKind) const

Return the number of instrumented sites for ValueKind.

static void setCSFlagInHash(uint64_t &FuncHash)

static constexpr uint64_t FUNC_HASH_MASK

Instruction * AnnotatedInst