LLVM: lib/ProfileData/InstrProf.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

19#include "llvm/Config/config.h"

46#include

47#include

48#include

49#include

50#include

51#include

52#include

53#include <system_error>

54#include <type_traits>

55#include

56#include

57

58using namespace llvm;

59

60#define DEBUG_TYPE "instrprof"

61

64 cl::desc("Use full module build paths in the profile counter names for "

65 "static functions."));

66

67

68

69

70

71

72

73

74

77 cl::desc("Strip specified level of directory name from source path in "

78 "the profile counter name for static functions."));

79

81 const std::string &ErrMsg = "") {

82 std::string Msg;

84

85 switch (Err) {

86 case instrprof_error::success:

87 OS << "success";

88 break;

89 case instrprof_error::eof:

90 OS << "end of File";

91 break;

92 case instrprof_error::unrecognized_format:

93 OS << "unrecognized instrumentation profile encoding format";

94 break;

95 case instrprof_error::bad_magic:

96 OS << "invalid instrumentation profile data (bad magic)";

97 break;

98 case instrprof_error::bad_header:

99 OS << "invalid instrumentation profile data (file header is corrupt)";

100 break;

101 case instrprof_error::unsupported_version:

102 OS << "unsupported instrumentation profile format version";

103 break;

104 case instrprof_error::unsupported_hash_type:

105 OS << "unsupported instrumentation profile hash type";

106 break;

107 case instrprof_error::too_large:

108 OS << "too much profile data";

109 break;

110 case instrprof_error::truncated:

111 OS << "truncated profile data";

112 break;

113 case instrprof_error::malformed:

114 OS << "malformed instrumentation profile data";

115 break;

116 case instrprof_error::missing_correlation_info:

117 OS << "debug info/binary for correlation is required";

118 break;

119 case instrprof_error::unexpected_correlation_info:

120 OS << "debug info/binary for correlation is not necessary";

121 break;

122 case instrprof_error::unable_to_correlate_profile:

123 OS << "unable to correlate profile";

124 break;

125 case instrprof_error::invalid_prof:

126 OS << "invalid profile created. Please file a bug "

127 "at: " BUG_REPORT_URL

128 " and include the profraw files that caused this error.";

129 break;

130 case instrprof_error::unknown_function:

131 OS << "no profile data available for function";

132 break;

133 case instrprof_error::hash_mismatch:

134 OS << "function control flow change detected (hash mismatch)";

135 break;

136 case instrprof_error::count_mismatch:

137 OS << "function basic block count change detected (counter mismatch)";

138 break;

139 case instrprof_error::bitmap_mismatch:

140 OS << "function bitmap size change detected (bitmap size mismatch)";

141 break;

142 case instrprof_error::counter_overflow:

143 OS << "counter overflow";

144 break;

145 case instrprof_error::value_site_count_mismatch:

146 OS << "function value site count change detected (counter mismatch)";

147 break;

148 case instrprof_error::compress_failed:

149 OS << "failed to compress data (zlib)";

150 break;

151 case instrprof_error::uncompress_failed:

152 OS << "failed to uncompress data (zlib)";

153 break;

154 case instrprof_error::empty_raw_profile:

155 OS << "empty raw profile file";

156 break;

157 case instrprof_error::zlib_unavailable:

158 OS << "profile uses zlib compression but the profile reader was built "

159 "without zlib support";

160 break;

161 case instrprof_error::raw_profile_version_mismatch:

162 OS << "raw profile version mismatch";

163 break;

164 case instrprof_error::counter_value_too_large:

165 OS << "excessively large counter value suggests corrupted profile data";

166 break;

167 }

168

169

170 if (!ErrMsg.empty())

171 OS << ": " << ErrMsg;

172

173 return OS.str();

174}

175

176namespace {

177

178

179

180

181class InstrProfErrorCategoryType : public std::error_category {

182 const char *name() const noexcept override { return "llvm.instrprof"; }

183

184 std::string message(int IE) const override {

186 }

187};

188

189}

190

192 static InstrProfErrorCategoryType ErrorCategory;

193 return ErrorCategory;

194}

195

196namespace {

197

198const char *InstrProfSectNameCommon[] = {

199#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \

200 SectNameCommon,

202};

203

204const char *InstrProfSectNameCoff[] = {

205#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \

206 SectNameCoff,

208};

209

210const char *InstrProfSectNamePrefix[] = {

211#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \

212 Prefix,

214};

215

216}

217

218namespace llvm {

219

221 "enable-name-compression",

222 cl::desc("Enable name/filename string compression"), cl::init(true));

223

225 "enable-vtable-value-profiling", cl::init(false),

226 cl::desc("If true, the virtual table address will be instrumented to know "

227 "the types of a C++ pointer. The information is used in indirect "

228 "call promotion to do selective vtable-based comparison."));

229

231 "enable-vtable-profile-use", cl::init(false),

232 cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable "

233 "profiles will be used by ICP pass for more efficient indirect "

234 "call sequence. If false, type profiles won't be used."));

235

238 bool AddSegmentInfo) {

239 std::string SectName;

240

242 SectName = InstrProfSectNamePrefix[IPSK];

243

245 SectName += InstrProfSectNameCoff[IPSK];

246 else

247 SectName += InstrProfSectNameCommon[IPSK];

248

249 if (OF == Triple::MachO && IPSK == IPSK_data && AddSegmentInfo)

250 SectName += ",regular,live_support";

251

252 return SectName;

253}

254

257}

258

260

264

265

266

267 if (Name[0] == '\1')

269

270 std::string NewName = std::string(Name);

272

273

274

275

276 if (FileName.empty())

277 NewName = NewName.insert(0, ":");

278 else

279 NewName = NewName.insert(0, FileName.str() + ":");

280 }

281 return NewName;

282}

283

284

285

286

289 uint32_t Pos = 0, LastPos = 0;

290 for (const auto &CI : PathNameStr) {

291 ++Pos;

293 LastPos = Pos;

294 --Count;

295 }

296 if (Count == 0)

297 break;

298 }

299 return PathNameStr.substr(LastPos);

300}

301

307 if (StripLevel)

309 return FileName;

310}

311

312

313

314

315

316

317

318

319

320

321static std::string

326}

327

329 if (MD != nullptr) {

331 return S.str();

332 }

333 return {};

334}

335

336

337

338

339

340

341

342

343

344

345

346

347

348

350 MDNode *PGONameMetadata) {

351 if (!InLTO) {

354 }

355

356

358 return *IRPGOFuncName;

359

360

361

362

364}

365

366

367

370}

371

372

373

374

375

376

377

378

380 if (!InLTO) {

383 }

384

385

387 return *PGOFuncName;

388

389

390

391

393}

394

396

397

398

400}

401

402

405 if (MangledName.empty())

406 return std::make_pair(StringRef(), IRPGOName);

407 return std::make_pair(FileName, MangledName);

408}

409

411 if (FileName.empty())

412 return PGOFuncName;

413

414

416 PGOFuncName = PGOFuncName.drop_front(FileName.size() + 1);

417 return PGOFuncName;

418}

419

420

421

425 VarName += FuncName;

426

428 return VarName;

429

430

431 const char InvalidChars[] = "-:;<>/\"'";

432 size_t FoundPos = VarName.find_first_of(InvalidChars);

433 while (FoundPos != std:🧵:npos) {

434 VarName[FoundPos] = '_';

435 FoundPos = VarName.find_first_of(InvalidChars, FoundPos + 1);

436 }

437 return VarName;

438}

439

441 const auto &T = Triple(M.getTargetTriple());

442 return T.isAMDGPU() || T.isNVPTX();

443}

444

446

447

450

453}

454

458

461

462

463

471

474 auto *FuncNameVar =

477

479 return FuncNameVar;

480}

481

484}

485

488

489

490 if (F.hasName())

491 continue;

493 return E;

494

496 return E;

497 }

498

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

502 continue;

504 return E;

505 }

506

507 Sorted = false;

508 finalizeSymtab();

510}

511

516 return E;

517

518 bool Inserted = true;

519 std::tie(std::ignore, Inserted) =

521 if (!Inserted)

522 LLVM_DEBUG(dbgs() << "GUID conflict within one module");

524 };

525 if (Error E = NameToGUIDMap(VTablePGOName))

526 return E;

527

528 StringRef CanonicalName = getCanonicalName(VTablePGOName);

529 if (CanonicalName != VTablePGOName)

530 return NameToGUIDMap(CanonicalName);

531

533}

534

535

536

537

543 while (P < EndP) {

546 P += N;

548 P += N;

549 const bool IsCompressed = (CompressedSize != 0);

552 if (IsCompressed) {

555

557 UncompressedNameStrings,

558 UncompressedSize)) {

561 }

562 P += CompressedSize;

563 NameStrings = toStringRef(UncompressedNameStrings);

564 } else {

565 NameStrings =

566 StringRef(reinterpret_cast<const char *>(P), UncompressedSize);

567 P += UncompressedSize;

568 }

569

573 if (Error E = NameCallback(Name))

574 return E;

575

576 while (P < EndP && *P == 0)

577 P++;

578 }

580}

581

584 NameStrings,

586}

587

592 this, std::placeholders::_1)))

593 return E;

594

596 VTableNameStrings,

598}

599

601 StringRef CompressedVTableStrings) {

603 CompressedVTableStrings,

605}

606

608

609

610

611

612

613

614

615

616

617 const std::string UniqSuffix = ".__uniq.";

618 size_t Pos = PGOName.find(UniqSuffix);

620 Pos += UniqSuffix.length();

621 else

622 Pos = 0;

623

624

625

626 Pos = PGOName.find('.', Pos);

628 return PGOName.substr(0, Pos);

629

630 return PGOName;

631}

632

634 bool AddCanonical) {

637 return E;

640 };

641 if (Error E = NameToGUIDMap(PGOFuncName))

642 return E;

643

644 if (!AddCanonical)

646

647 StringRef CanonicalFuncName = getCanonicalName(PGOFuncName);

648 if (CanonicalFuncName != PGOFuncName)

649 return NameToGUIDMap(CanonicalFuncName);

650

652}

653

655

656

658}

659

661 finalizeSymtab();

662 auto It = partition_point(AddrToMD5Map, [=](std::pair<uint64_t, uint64_t> A) {

664 });

665

666

667

668

669 if (It != AddrToMD5Map.end() && It->first == Address)

671 return 0;

672}

673

678 OS << S << '\n';

679}

680

682 bool DoCompression, std::string &Result) {

683 assert(!NameStrs.empty() && "No name data to emit");

684

685 uint8_t Header[20], *P = Header;

686 std::string UncompressedNameStrings =

688

691 "PGO name is invalid (contains separator token)");

692

693 unsigned EncLen = encodeULEB128(UncompressedNameStrings.length(), P);

694 P += EncLen;

695

696 auto WriteStringToResult = [&](size_t CompressedLen, StringRef InputStr) {

698 P += EncLen;

699 char *HeaderStr = reinterpret_cast<char *>(&Header[0]);

700 unsigned HeaderLen = P - &Header[0];

701 Result.append(HeaderStr, HeaderLen);

702 Result += InputStr;

704 };

705

706 if (!DoCompression) {

707 return WriteStringToResult(0, UncompressedNameStrings);

708 }

709

712 CompressedNameStrings,

714

715 return WriteStringToResult(CompressedNameStrings.size(),

716 toStringRef(CompressedNameStrings));

717}

718

720 auto *Arr = cast(NameVar->getInitializer());

722 Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();

723 return NameStr;

724}

725

727 std::string &Result, bool DoCompression) {

728 std::vectorstd::string NameStrs;

729 for (auto *NameVar : NameVars) {

731 }

734}

735

737 std::string &Result, bool DoCompression) {

738 std::vectorstd::string VTableNameStrs;

739 for (auto *VTable : VTables)

740 VTableNameStrs.push_back(getPGOName(*VTable));

743 Result);

744}

745

750 FuncSum += Count;

752

753 for (uint32_t VK = IPVK_First; VK <= IPVK_Last; ++VK) {

756 for (size_t I = 0; I < NumValueSites; ++I) {

758 KindSum += V.Count;

759 }

761 }

762}

763

770 double Score = 0.0f, FuncLevelScore = 0.0f;

773 auto J = Input.ValueData.begin();

775 while (I != IE && J != JE) {

776 if (I->Value == J->Value) {

781 I->Count, J->Count, FuncLevelOverlap.Base.ValueCounts[ValueKind],

783 ++I;

784 } else if (I->Value < J->Value) {

785 ++I;

786 continue;

787 }

788 ++J;

789 }

792}

793

794

800 assert(ThisNumValueSites == Other.getNumValueSites(ValueKind));

801 if (!ThisNumValueSites)

802 return;

803

804 std::vector &ThisSiteRecords =

805 getOrCreateValueSitesForKind(ValueKind);

807 Other.getValueSitesForKind(ValueKind);

808 for (uint32_t I = 0; I < ThisNumValueSites; I++)

809 ThisSiteRecords[I].overlap(OtherSiteRecords[I], ValueKind, Overlap,

810 FuncLevelOverlap);

811}

812

816

819 bool Mismatch = (Counts.size() != Other.Counts.size());

820

821

822 if (!Mismatch) {

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

825 uint32_t OtherNumValueSites = Other.getNumValueSites(Kind);

826 if (ThisNumValueSites != OtherNumValueSites) {

827 Mismatch = true;

828 break;

829 }

830 }

831 }

832 if (Mismatch) {

834 return;

835 }

836

837

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

840

841 double Score = 0.0;

843

844 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {

847 MaxCount = std::max(Other.Counts[I], MaxCount);

848 }

851

852 if (MaxCount >= ValueCutoff) {

853 double FuncScore = 0.0;

854 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I)

860 FuncLevelOverlap.Valid = true;

861 }

862}

863

871 std::vector Merged;

873 for (const InstrProfValueData &J : Input.ValueData) {

874 while (I != IE && I->Value < J.Value) {

875 Merged.push_back(*I);

876 ++I;

877 }

878 if (I != IE && I->Value == J.Value) {

879 bool Overflowed;

881 if (Overflowed)

883 Merged.push_back(*I);

884 ++I;

885 continue;

886 }

887 Merged.push_back(J);

888 }

889 Merged.insert(Merged.end(), I, IE);

891}

892

895 for (InstrProfValueData &I : ValueData) {

896 bool Overflowed;

898 if (Overflowed)

900 }

901}

902

903

904

905void InstrProfRecord::mergeValueProfData(

909 uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);

910 if (ThisNumValueSites != OtherNumValueSites) {

912 return;

913 }

914 if (!ThisNumValueSites)

915 return;

916 std::vector &ThisSiteRecords =

917 getOrCreateValueSitesForKind(ValueKind);

919 Src.getValueSitesForKind(ValueKind);

920 for (uint32_t I = 0; I < ThisNumValueSites; I++)

921 ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight, Warn);

922}

923

926

927

928 if (Counts.size() != Other.Counts.size()) {

930 return;

931 }

932

933

937

938

939

942 return;

943 }

946 else

948 return;

949 }

950

951 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {

952 bool Overflowed;

957 Overflowed = true;

958 }

960 if (Overflowed)

962 }

963

964

965

968 return;

969 }

970

971

972 for (size_t I = 0, E = Other.BitmapBytes.size(); I < E; ++I) {

974 }

975

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

977 mergeValueProfData(Kind, Other, Weight, Warn);

978}

979

980void InstrProfRecord::scaleValueProfData(

983 for (auto &R : getValueSitesForKind(ValueKind))

984 R.scale(N, D, Warn);

985}

986

989 assert(D != 0 && "D cannot be 0");

990 for (auto &Count : this->Counts) {

991 bool Overflowed;

995 Overflowed = true;

996 }

997 if (Overflowed)

999 }

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

1001 scaleValueProfData(Kind, N, D, Warn);

1002}

1003

1004

1007 if (!SymTab)

1009

1010 if (ValueKind == IPVK_IndirectCallTarget)

1012

1013 if (ValueKind == IPVK_VTableTarget)

1015

1017}

1018

1022

1023 std::vector RemappedVD;

1024 RemappedVD.reserve(VData.size());

1025 for (const auto &V : VData) {

1026 uint64_t NewValue = remapValue(V.Value, ValueKind, ValueMap);

1027 RemappedVD.push_back({NewValue, V.Count});

1028 }

1029

1030 std::vector &ValueSites =

1031 getOrCreateValueSitesForKind(ValueKind);

1032 assert(ValueSites.size() == Site);

1033

1034

1035 ValueSites.emplace_back(std::move(RemappedVD));

1036}

1037

1040 bool RemoveOutlierUNs) {

1043 UtilityNodeT MaxUN = 0;

1047

1048

1049 for (auto &Trace : Traces) {

1050 size_t CutoffTimestamp = 1;

1055 if (!WasInserted)

1056 It->getSecond() = std::min<size_t>(It->getSecond(), Timestamp);

1057 if (Timestamp >= CutoffTimestamp) {

1058 ++MaxUN;

1059 CutoffTimestamp = 2 * Timestamp;

1060 }

1062 }

1063 for (auto &[Id, FirstUN] : IdToFirstUN)

1064 for (auto UN = FirstUN; UN <= MaxUN; ++UN)

1065 IdToUNs[Id].push_back(UN);

1066 ++MaxUN;

1067 IdToFirstUN.clear();

1068 }

1069

1070 if (RemoveOutlierUNs) {

1072 for (auto &[Id, UNs] : IdToUNs)

1073 for (auto &UN : UNs)

1074 ++UNFrequency[UN];

1075

1076

1077 for (auto &[Id, UNs] : IdToUNs)

1079 return UNFrequency[UN] <= 1 || 2 * UNFrequency[UN] > IdToUNs.size();

1080 });

1081 }

1082

1083 for (auto &[Id, UNs] : IdToUNs)

1084 Nodes.emplace_back(Id, UNs);

1085

1086

1087

1088 llvm::sort(Nodes, [&](auto &L, auto &R) {

1089 return std::make_pair(IdToFirstTimestamp[L.Id], L.Id) <

1090 std::make_pair(IdToFirstTimestamp[R.Id], R.Id);

1091 });

1092}

1093

1094#define INSTR_PROF_COMMON_API_IMPL

1096

1097

1098

1099

1100

1101

1104}

1105

1108 ->getNumValueSites(VKind);

1109}

1110

1113 ->getNumValueData(VKind);

1114}

1115

1118 const auto *IPR = reinterpret_cast<const InstrProfRecord *>(R);

1120}

1121

1124 const auto *IPR = reinterpret_cast<const InstrProfRecord *>(R);

1125 llvm::copy(IPR->getValueArrayForSite(K, S), Dst);

1126}

1127

1129 ValueProfData *VD =

1130 (ValueProfData *)(new (::operator new(TotalSizeInBytes)) ValueProfData());

1131 memset(VD, 0, TotalSizeInBytes);

1132 return VD;

1133}

1134

1136 nullptr,

1141 nullptr,

1144

1145

1148 Closure.Record = &Record;

1149 return getValueProfDataSize(&Closure);

1150}

1151

1152

1153std::unique_ptr

1156

1157 std::unique_ptr VPD(

1159 return VPD;

1160}

1161

1164 Record.reserveSites(Kind, NumValueSites);

1165

1166 InstrProfValueData *ValueData = getValueProfRecordValueData(this);

1167 for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) {

1168 uint8_t ValueDataCount = this->SiteCountArray[VSite];

1170 Record.addValueData(Kind, VSite, VDs, SymTab);

1171 ValueData += ValueDataCount;

1172 }

1173}

1174

1175

1176

1177

1179 using namespace support;

1180

1181 if (Old == New)

1182 return;

1183

1185 sys::swapByteOrder<uint32_t>(NumValueSites);

1186 sys::swapByteOrder<uint32_t>(Kind);

1187 }

1188 uint32_t ND = getValueProfRecordNumValueData(this);

1189 InstrProfValueData *VD = getValueProfRecordValueData(this);

1190

1191

1193 sys::swapByteOrder<uint64_t>(VD[I].Value);

1194 sys::swapByteOrder<uint64_t>(VD[I].Count);

1195 }

1197 sys::swapByteOrder<uint32_t>(NumValueSites);

1198 sys::swapByteOrder<uint32_t>(Kind);

1199 }

1200}

1201

1204 if (NumValueKinds == 0)

1205 return;

1206

1207 ValueProfRecord *VR = getFirstValueProfRecord(this);

1208 for (uint32_t K = 0; K < NumValueKinds; K++) {

1209 VR->deserializeTo(Record, SymTab);

1210 VR = getValueProfRecordNext(VR);

1211 }

1212}

1213

1215 return std::unique_ptr(new (::operator new(TotalSize))

1216 ValueProfData());

1217}

1218

1219Error ValueProfData::checkIntegrity() {

1220 if (NumValueKinds > IPVK_Last + 1)

1221 return make_error(

1223

1224 if (TotalSize % sizeof(uint64_t))

1225 return make_error(

1227

1228 ValueProfRecord *VR = getFirstValueProfRecord(this);

1229 for (uint32_t K = 0; K < this->NumValueKinds; K++) {

1230 if (VR->Kind > IPVK_Last)

1232 "value kind is invalid");

1233 VR = getValueProfRecordNext(VR);

1234 if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize)

1235 return make_error(

1237 "value profile address is greater than total size");

1238 }

1240}

1241

1243ValueProfData::getValueProfData(const unsigned char *D,

1244 const unsigned char *const BufferEnd,

1246 using namespace support;

1247

1248 if (D + sizeof(ValueProfData) > BufferEnd)

1250

1251 const unsigned char *Header = D;

1252 uint32_t TotalSize = endian::readNext<uint32_t>(Header, Endianness);

1253

1254 if (D + TotalSize > BufferEnd)

1256

1258 memcpy(VPD.get(), D, TotalSize);

1259

1260 VPD->swapBytesToHost(Endianness);

1261

1262 Error E = VPD->checkIntegrity();

1263 if (E)

1264 return std::move(E);

1265

1266 return std::move(VPD);

1267}

1268

1269void ValueProfData::swapBytesToHost(llvm::endianness Endianness) {

1270 using namespace support;

1271

1273 return;

1274

1275 sys::swapByteOrder<uint32_t>(TotalSize);

1276 sys::swapByteOrder<uint32_t>(NumValueKinds);

1277

1278 ValueProfRecord *VR = getFirstValueProfRecord(this);

1279 for (uint32_t K = 0; K < NumValueKinds; K++) {

1281 VR = getValueProfRecordNext(VR);

1282 }

1283}

1284

1285void ValueProfData::swapBytesFromHost(llvm::endianness Endianness) {

1286 using namespace support;

1287

1289 return;

1290

1291 ValueProfRecord *VR = getFirstValueProfRecord(this);

1292 for (uint32_t K = 0; K < NumValueKinds; K++) {

1293 ValueProfRecord *NVR = getValueProfRecordNext(VR);

1295 VR = NVR;

1296 }

1297 sys::swapByteOrder<uint32_t>(TotalSize);

1298 sys::swapByteOrder<uint32_t>(NumValueKinds);

1299}

1300

1306 if (VDs.empty())

1307 return;

1309 for (const InstrProfValueData &V : VDs)

1312}

1313

1318 if (VDs.empty())

1319 return;

1323

1325

1328

1331

1332

1333 uint32_t MDCount = MaxMDCount;

1334 for (const auto &VD : VDs) {

1339 if (--MDCount == 0)

1340 break;

1341 }

1343}

1344

1348 if (!MD)

1349 return nullptr;

1350

1352 return nullptr;

1353

1355 if (Tag || Tag->getString() != "VP")

1356 return nullptr;

1357

1358

1360 if (!KindInt)

1361 return nullptr;

1363 return nullptr;

1364

1365 return MD;

1366}

1367

1371 bool GetNoICPValue) {

1372

1373

1376 if (!MD)

1377 return ValueData;

1379

1381 if (!TotalCInt)

1382 return ValueData;

1384

1385 ValueData.reserve((NOps - 3) / 2);

1386 for (unsigned I = 3; I < NOps; I += 2) {

1387 if (ValueData.size() >= MaxNumValueData)

1388 break;

1391 mdconst::dyn_extract(MD->getOperand(I + 1));

1392 if (Value || !Count) {

1393 ValueData.clear();

1394 return ValueData;

1395 }

1398 continue;

1399 InstrProfValueData V;

1400 V.Value = Value->getZExtValue();

1401 V.Count = CntValue;

1403 }

1404 return ValueData;

1405}

1406

1409}

1410

1413

1414

1415 if (GO.getName() == PGOName)

1416 return;

1417

1418

1420 return;

1421

1425}

1426

1429}

1430

1433}

1434

1437 return true;

1438

1440 return false;

1441

1442

1443

1444

1445

1446

1447

1448

1449

1450

1451

1455 return false;

1456

1457 return true;

1458}

1459

1460

1463 M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));

1465 return false;

1466

1467

1468

1470 return true;

1471

1472

1474 return false;

1475

1476 auto *InitVal = dyn_cast_or_null(IRInstrVar->getInitializer());

1477 if (!InitVal)

1478 return false;

1479 return (InitVal->getZExtValue() & VARIANT_MASK_IR_PROF) != 0;

1480}

1481

1482

1484 if (F.getName().empty())

1485 return false;

1487 return false;

1488

1489

1490 if (CheckAddressTaken && F.hasAddressTaken())

1491 return false;

1492

1493

1495 return false;

1496

1497

1498 if (F.hasComdat()) {

1500 return true;

1501 }

1502 return true;

1503}

1504

1505

1507 if (InstrProfileOutput.empty())

1508 return;

1509 Constant *ProfileNameConst =

1513 ProfileNameConst, INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR));

1515 Triple TT(M.getTargetTriple());

1516 if (TT.supportsCOMDAT()) {

1518 ProfileNameVar->setComdat(M.getOrInsertComdat(

1519 StringRef(INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR))));

1520 }

1521}

1522

1524 const std::string &TestFilename,

1525 bool IsCS) {

1526 auto GetProfileSum = [IsCS](const std::string &Filename,

1528

1529

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

1533 return E;

1534 }

1535 auto Reader = std::move(ReaderOrErr.get());

1536 Reader->accumulateCounts(Sum, IsCS);

1538 };

1540 if (Ret)

1541 return Ret;

1543 if (Ret)

1544 return Ret;

1549}

1550

1554 for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) {

1558 }

1559}

1560

1564 for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) {

1567 }

1568}

1569

1572 return;

1573

1574 const char *EntryName =

1575 (Level == ProgramLevel ? "functions" : "edge counters");

1577 OS << "Profile overlap infomation for base_profile: " << *BaseFilename

1578 << " and test_profile: " << *TestFilename << "\nProgram level:\n";

1579 } else {

1580 OS << "Function level:\n"

1581 << " Function: " << FuncName << " (Hash=" << FuncHash << ")\n";

1582 }

1583

1584 OS << " # of " << EntryName << " overlap: " << Overlap.NumEntries << "\n";

1587 << "\n";

1589 OS << " # of " << EntryName

1591

1593 << "\n";

1595 OS << " Mismatched count percentage (Edge): "

1598 OS << " Percentage of Edge profile only in test_profile: "

1601 << "\n"

1602 << " Edge profile test count sum: " << format("%.0f", Test.CountSum)

1603 << "\n";

1604

1605 for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) {

1607 continue;

1608 char ProfileKindName[20] = {0};

1609 switch (I) {

1610 case IPVK_IndirectCallTarget:

1611 strncpy(ProfileKindName, "IndirectCall", 19);

1612 break;

1613 case IPVK_MemOPSize:

1614 strncpy(ProfileKindName, "MemOP", 19);

1615 break;

1616 case IPVK_VTableTarget:

1617 strncpy(ProfileKindName, "VTable", 19);

1618 break;

1619 default:

1620 snprintf(ProfileKindName, 19, "VP[%d]", I);

1621 break;

1622 }

1623 OS << " " << ProfileKindName

1625 << "\n";

1627 OS << " Mismatched count percentage (" << ProfileKindName

1630 OS << " Percentage of " << ProfileKindName

1631 << " profile only in test_profile: "

1633 OS << " " << ProfileKindName

1635 << "\n"

1636 << " " << ProfileKindName

1638 << "\n";

1639 }

1640}

1641

1642namespace IndexedInstrProf {

1644 using namespace support;

1645 static_assert(std::is_standard_layout_v

,

1646 "Use standard layout for Header for simplicity");

1648

1649 H.Magic = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1650

1653

1654

1655 H.Version = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1656 if (H.getIndexedProfileVersion() >

1659

1661 "Please update the reader as needed when a new field is added "

1662 "or when indexed profile version gets bumped.");

1663

1664 Buffer += sizeof(uint64_t);

1665 H.HashType = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1666 H.HashOffset = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1667 if (H.getIndexedProfileVersion() >= 8)

1668 H.MemProfOffset =

1669 endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1670 if (H.getIndexedProfileVersion() >= 9)

1671 H.BinaryIdOffset =

1672 endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1673

1674 if (H.getIndexedProfileVersion() >= 10)

1675 H.TemporalProfTracesOffset =

1676 endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1677 if (H.getIndexedProfileVersion() >= 12)

1678 H.VTableNamesOffset =

1679 endian::readNext<uint64_t, llvm::endianness::little>(Buffer);

1680 return H;

1681}

1682

1684 return GET_VERSION(Version);

1685}

1686

1689

1690

1691

1692 static_assert(

1694 "Please update the size computation below if a new field has "

1695 "been added to the header; for a version bump without new "

1696 "fields, add a case statement to fall through to the latest version.");

1697 case 12ull:

1698 return 72;

1699 case 11ull:

1700 [[fallthrough]];

1701 case 10ull:

1702 return 64;

1703 case 9ull:

1704 return 56;

1705 case 8ull:

1706 return 48;

1707 default:

1708 return 40;

1709 }

1710}

1711

1712}

1713

1714}

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

#define LLVM_ATTRIBUTE_UNUSED

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

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

static cl::opt< bool > StaticFuncFullModulePrefix("static-func-full-module-prefix", cl::init(true), cl::Hidden, cl::desc("Use full module build paths in the profile counter names for " "static functions."))

static cl::opt< unsigned > StaticFuncStripDirNamePrefix("static-func-strip-dirname-prefix", cl::init(0), cl::Hidden, cl::desc("Strip specified level of directory name from source path in " "the profile counter name for static functions."))

static std::string getInstrProfErrString(instrprof_error Err, const std::string &ErrMsg="")

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallVector class.

Defines the virtual file system interface vfs::FileSystem.

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

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)

This method constructs a CDS and initializes it with a text string.

This is the shared class of boolean and integer constants.

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

This is an important base class in LLVM.

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

void setMetadata(unsigned KindID, MDNode *Node)

Set a particular kind of metadata attachment.

void setComdat(Comdat *C)

MDNode * getMetadata(unsigned KindID) const

Get the current metadata attachments for the given kind, if any.

static bool isLocalLinkage(LinkageTypes Linkage)

bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

LinkageTypes getLinkage() const

bool hasLocalLinkage() const

void setLinkage(LinkageTypes LT)

GUID getGUID() const

Return a 64-bit global unique ID constructed from global value name (i.e.

Module * getParent()

Get the module that this global value is contained inside of...

bool isDiscardableIfUnused() const

@ HiddenVisibility

The GV is hidden.

@ ProtectedVisibility

The GV is protected.

void setVisibility(VisibilityTypes V)

std::string getGlobalIdentifier() const

Return the modified name for this global value suitable to be used as the key for a global lookup (e....

LinkageTypes

An enumeration for the kinds of linkage for global values.

@ PrivateLinkage

Like Internal, but omit from symbol table.

@ InternalLinkage

Rename collisions when linking (static functions).

@ LinkOnceAnyLinkage

Keep one copy of function when linking (inline)

@ ExternalLinkage

Externally visible function.

@ WeakAnyLinkage

Keep one copy of named function when linking (weak)

@ AvailableExternallyLinkage

Available for inspection, not emission.

@ ExternalWeakLinkage

ExternalWeak linkage description.

@ LinkOnceODRLinkage

Same, but only replaced by something equivalent.

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

bool hasInitializer() const

Definitions have initializers, declarations don't.

std::string message() const override

Return the error message as a string.

static Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const InstrProfCorrelator *Correlator=nullptr, const object::BuildIDFetcher *BIDFetcher=nullptr, const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind=InstrProfCorrelator::ProfCorrelatorKind::NONE, std::function< void(Error)> Warn=nullptr)

Factory method to create an appropriately typed reader for the given instrprof file.

A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...

uint64_t getFunctionHashFromAddress(uint64_t Address)

Return a function's hash, or 0, if the function isn't in this SymTab.

Error addSymbolName(StringRef SymbolName)

uint64_t getVTableHashFromAddress(uint64_t Address)

Return a vtable's hash, or 0 if the vtable doesn't exist in this SymTab.

Error addVTableName(StringRef VTableName)

Adds VTableName as a known symbol, and inserts it to a map that tracks all vtable names.

void dumpNames(raw_ostream &OS) const

Dump the symbols in this table.

Error create(object::SectionRef &Section)

Create InstrProfSymtab from an object file section which contains function PGO names.

Error addFuncName(StringRef FuncName)

The method name is kept since there are many callers.

Error initVTableNamesFromCompressedStrings(StringRef CompressedVTableNames)

Initialize 'this' with the set of vtable names encoded in CompressedVTableNames.

MDNode * getMetadata(unsigned KindID) const

Get the metadata of given kind attached to this Instruction.

void setMetadata(unsigned KindID, MDNode *Node)

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

ValT lookup(KeyT x, ValT NotFound=ValT()) const

lookup - Return the mapped value at x or NotFound.

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

ConstantAsMetadata * createConstant(Constant *C)

Return the given constant as metadata.

MDString * createString(StringRef Str)

Return the given string as metadata.

const MDOperand & getOperand(unsigned I) const

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

unsigned getNumOperands() const

Return number of MDNode operands.

static MDString * get(LLVMContext &Context, StringRef Str)

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

const std::string & getSourceFileName() const

Get the module's original source file name.

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

void reserve(size_type N)

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_range< StringMapKeyIterator< ValueTy > > keys() const

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

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

std::string str() const

str - Get the contents as an std::string.

const unsigned char * bytes_end() const

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

constexpr size_t size() const

size - Get the string size.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

static constexpr size_t npos

const unsigned char * bytes_begin() const

Triple - Helper class for working with autoconf configuration names.

bool supportsCOMDAT() const

Tests whether the target supports comdat.

static IntegerType * getInt32Ty(LLVMContext &C)

static IntegerType * getInt64Ty(LLVMContext &C)

LLVM Value Representation.

Type * getType() const

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

LLVMContext & getContext() const

All values hold a context through their type.

StringRef getName() const

Return a constant reference to the value's name.

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

A raw_ostream that writes to a file descriptor.

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

@ C

The default llvm calling convention, compatible with C.

initializer< Ty > init(const Ty &Val)

void compress(ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &CompressedBuffer, int Level=DefaultCompression)

Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)

constexpr int BestSizeCompression

bool is_separator(char value, Style style=Style::native)

Check whether the given char is a path separator on the host OS.

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.

StringRef getInstrProfNameVarPrefix()

Return the name prefix of variables containing instrumented function names.

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

Please use getIRPGOFuncName for LLVM IR instrumentation.

void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName)

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

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

StringRef getPGOFuncNameMetadataName()

void getValueForSiteInstrProf(const void *R, InstrProfValueData *Dst, uint32_t K, uint32_t S)

cl::opt< bool > DoInstrProfNameCompression

StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName="")

Given a PGO function name, remove the filename prefix and return the original (static) function name.

auto partition_point(R &&Range, Predicate P)

Binary search for the first iterator in a range where a predicate is false.

uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)

Utility function to decode a ULEB128 value.

void createPGONameMetadata(GlobalObject &GO, StringRef PGOName)

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

std::pair< StringRef, StringRef > getParsedIRPGOName(StringRef IRPGOName)

MDNode * getPGOFuncNameMetadata(const Function &F)

Return the PGOFuncName meta data associated with a function.

static std::unique_ptr< ValueProfData > allocValueProfData(uint32_t TotalSize)

MDNode * mayHaveValueProfileOfKind(const Instruction &Inst, InstrProfValueKind ValueKind)

std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)

Return the name of the profile section corresponding to IPSK.

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."))

uint64_t getInstrMaxCountValue()

Return the max count value. We reserver a few large values for special use.

bool needsComdatForCounter(const GlobalObject &GV, const Module &M)

Check if we can use Comdat for profile variables.

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

GlobalVariable * createPGOFuncNameVar(Function &F, StringRef PGOFuncName)

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

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

Error collectPGOFuncNameStrings(ArrayRef< GlobalVariable * > NameVars, std::string &Result, bool doCompression=true)

Produce Result string with the same format described above.

void sort(IteratorTy Start, IteratorTy End)

raw_ostream & dbgs()

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

StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar)

Return the initializer in string of the PGO name var NameVar.

std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed=nullptr)

Multiply two unsigned integers, X and Y, and add the unsigned integer, A to the product.

StringRef getInstrProfNameSeparator()

Return the marker used to separate PGO names during serialization.

SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)

Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

static std::string getIRPGOObjectName(const GlobalObject &GO, bool InLTO, MDNode *PGONameMetadata)

@ value_site_count_mismatch

std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiply(T X, T Y, bool *ResultOverflowed=nullptr)

Multiply two unsigned integers, X and Y, of type T.

const std::error_category & instrprof_category()

Error collectVTableStrings(ArrayRef< GlobalVariable * > VTables, std::string &Result, bool doCompression)

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

static StringRef getStrippedSourceFileName(const GlobalObject &GO)

uint32_t getNumValueSitesInstrProf(const void *Record, uint32_t VKind)

OutputIt copy(R &&Range, OutputIt Out)

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

Check if we can safely rename this Comdat function.

void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput)

constexpr char GlobalIdentifierDelimiter

Error collectGlobalObjectNameStrings(ArrayRef< std::string > NameStrs, bool doCompression, std::string &Result)

Given a vector of strings (names of global objects like functions or, virtual tables) NameStrs,...

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

void setPGOFuncVisibility(Module &M, GlobalVariable *FuncNameVar)

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.

uint32_t getNumValueDataForSiteInstrProf(const void *R, uint32_t VK, uint32_t S)

static ValueProfRecordClosure InstrProfRecordClosure

static Error readAndDecodeStrings(StringRef NameStrings, std::function< Error(StringRef)> NameCallback)

NameStrings is a string composed of one of more possibly encoded sub-strings.

std::string getPGOFuncNameVarName(StringRef FuncName, GlobalValue::LinkageTypes Linkage)

Return the name of the global variable used to store a function name in PGO instrumentation.

static StringRef stripDirPrefix(StringRef PathNameStr, uint32_t NumPrefix)

static std::optional< std::string > lookupPGONameFromMetadata(MDNode *MD)

std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingAdd(T X, T Y, bool *ResultOverflowed=nullptr)

Add two unsigned integers, X and Y, of type T.

bool isGPUProfTarget(const Module &M)

Determines whether module targets a GPU eligable for PGO instrumentation.

bool isIRPGOFlagSet(const Module *M)

Check if INSTR_PROF_RAW_VERSION_VAR is defined.

StringRef getPGONameMetadataName()

void consumeError(Error Err)

Consume a Error without doing anything.

const uint64_t NOMORE_ICP_MAGICNUM

Magic number in the value profile metadata showing a target has been promoted for the instruction and...

uint32_t getNumValueKindsInstrProf(const void *Record)

ValueProfRecordClosure Interface implementation for InstrProfRecord class.

ValueProfData * allocValueProfDataInstrProf(size_t TotalSizeInBytes)

uint32_t getNumValueDataInstrProf(const void *Record, uint32_t VKind)

static std::string getIRPGONameForGlobalObject(const GlobalObject &GO, GlobalValue::LinkageTypes Linkage, StringRef FileName)

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."))

std::array< double, IPVK_Last - IPVK_First+1 > ValueCounts

Profiling information for a single function.

void overlapValueProfData(uint32_t ValueKind, InstrProfRecord &Src, OverlapStats &Overlap, OverlapStats &FuncLevelOverlap)

Compute the overlap of value profile counts.

std::vector< uint64_t > Counts

ArrayRef< InstrProfValueData > getValueArrayForSite(uint32_t ValueKind, uint32_t Site) const

Return the array of profiled values at Site.

CountPseudoKind getCountPseudoKind() const

void accumulateCounts(CountSumOrPercent &Sum) const

Compute the sums of all counts and store in Sum.

uint32_t getNumValueSites(uint32_t ValueKind) const

Return the number of instrumented sites for ValueKind.

void setPseudoCount(CountPseudoKind Kind)

void merge(InstrProfRecord &Other, uint64_t Weight, function_ref< void(instrprof_error)> Warn)

Merge the counts in Other into this one.

void addValueData(uint32_t ValueKind, uint32_t Site, ArrayRef< InstrProfValueData > VData, InstrProfSymtab *SymTab)

Add ValueData for ValueKind at value Site.

void overlap(InstrProfRecord &Other, OverlapStats &Overlap, OverlapStats &FuncLevelOverlap, uint64_t ValueCutoff)

Compute the overlap b/w this IntrprofRecord and Other.

std::vector< uint8_t > BitmapBytes

void scale(uint64_t N, uint64_t D, function_ref< void(instrprof_error)> Warn)

Scale up profile counts (including value profile data) by a factor of (N / D).

void sortByTargetValues()

Sort ValueData ascending by Value.

std::vector< InstrProfValueData > ValueData

Value profiling data pairs at a given value site.

void merge(InstrProfValueSiteRecord &Input, uint64_t Weight, function_ref< void(instrprof_error)> Warn)

Merge data from another InstrProfValueSiteRecord Optionally scale merged counts by Weight.

void overlap(InstrProfValueSiteRecord &Input, uint32_t ValueKind, OverlapStats &Overlap, OverlapStats &FuncLevelOverlap)

Compute the overlap b/w this record and Input record.

void scale(uint64_t N, uint64_t D, function_ref< void(instrprof_error)> Warn)

Scale up value profile data counts by N (Numerator) / D (Denominator).

void addOneMismatch(const CountSumOrPercent &MismatchFunc)

static double score(uint64_t Val1, uint64_t Val2, double Sum1, double Sum2)

Error accumulateCounts(const std::string &BaseFilename, const std::string &TestFilename, bool IsCS)

void dump(raw_fd_ostream &OS) const

CountSumOrPercent Overlap

void addOneUnique(const CountSumOrPercent &UniqueFunc)

const std::string * BaseFilename

const std::string * TestFilename

CountSumOrPercent Mismatch

static void createBPFunctionNodes(ArrayRef< TemporalProfTraceTy > Traces, std::vector< BPFunctionNode > &Nodes, bool RemoveOutlierUNs=true)

Use a set of temporal profile traces to create a list of balanced partitioning function nodes used by...