LLVM: include/llvm/ProfileData/SampleProf.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14#ifndef LLVM_PROFILEDATA_SAMPLEPROF_H

15#define LLVM_PROFILEDATA_SAMPLEPROF_H

16

29#include

30#include

31#include

32#include

33#include

34#include

35#include

36#include <system_error>

37#include <unordered_map>

38#include

39

40namespace llvm {

41

42class DILocation;

43class raw_ostream;

44

46

63};

64

67}

68

71

72

77}

78

79}

80

81namespace std {

82

83template <>

84struct is_error_code_enum<llvm::sampleprof_error> : std::true_type {};

85

86}

87

88namespace llvm {

89namespace sampleprof {

90

99

104};

105

107 return uint64_t('S') << (64 - 8) | uint64_t('P') << (64 - 16) |

111}

112

114

115

116

117

126

130

132 switch (static_cast<int>(Type)) {

134 return "InvalidSection";

136 return "ProfileSummarySection";

138 return "NameTableSection";

140 return "ProfileSymbolListSection";

142 return "FuncOffsetTableSection";

144 return "FunctionMetadata";

146 return "CSNameTableSection";

148 return "LBRProfileSection";

149 default:

150 return "UnknownSection";

151 }

152}

153

154

155

161

162

164};

165

166

167

168

172

174};

175

176

177

178

182

183

185

186

188};

191

192

193

195

196

198

199

201

202

204};

205

210};

211

214

215

217};

218

219

220template

222

223 if (std::is_same<SecCommonFlags, SecFlagType>())

224 return;

225

226

227 bool IsFlagLegal = false;

228 switch (Type) {

230 IsFlagLegal = std::is_same<SecNameTableFlags, SecFlagType>();

231 break;

233 IsFlagLegal = std::is_same<SecProfSummaryFlags, SecFlagType>();

234 break;

236 IsFlagLegal = std::is_same<SecFuncMetadataFlags, SecFlagType>();

237 break;

238 default:

240 IsFlagLegal = std::is_same<SecFuncOffsetFlags, SecFlagType>();

241 break;

242 }

243 if (!IsFlagLegal)

244 llvm_unreachable("Misuse of a flag in an incompatible section");

245}

246

247template

250 auto FVal = static_cast<uint64_t>(Flag);

251 bool IsCommon = std::is_same<SecCommonFlags, SecFlagType>();

252 Entry.Flags |= IsCommon ? FVal : (FVal << 32);

253}

254

255template

258 auto FVal = static_cast<uint64_t>(Flag);

259 bool IsCommon = std::is_same<SecCommonFlags, SecFlagType>();

260 Entry.Flags &= ~(IsCommon ? FVal : (FVal << 32));

261}

262

263template

266 auto FVal = static_cast<uint64_t>(Flag);

267 bool IsCommon = std::is_same<SecCommonFlags, SecFlagType>();

268 return Entry.Flags & (IsCommon ? FVal : (FVal << 32));

269}

270

271

272

273

274

275

276

277

278

279

282

284 void dump() const;

285

289 }

290

293 }

294

297 }

298

301 }

302

305};

306

310 }

311};

312

314

315

316

317

318

319

320

321

322

323

324

326public:

327 using CallTarget = std::pair<FunctionId, uint64_t>;

330 if (LHS.second != RHS.second)

331 return LHS.second > RHS.second;

332

333 return LHS.first < RHS.first;

334 }

335 };

336

338 using CallTargetMap = std::unordered_map<FunctionId, uint64_t>;

340

341

342

343

344

345

347 bool Overflowed;

351 }

352

353

354

356 if (S > NumSamples)

357 S = NumSamples;

358 NumSamples -= S;

359 return S;

360 }

361

362

363

364

365

366

369 uint64_t &TargetSamples = CallTargets[F];

370 bool Overflowed;

371 TargetSamples =

375 }

376

377

378

381 auto I = CallTargets.find(F);

382 if (I != CallTargets.end()) {

383 Count = I->second;

384 CallTargets.erase(I);

385 }

386 return Count;

387 }

388

389

390 bool hasCalls() const { return !CallTargets.empty(); }

391

396 }

397

400 for (const auto &I : CallTargets)

401 Sum += I.second;

402 return Sum;

403 }

404

405

409 for (const auto &[Target, Frequency] : Targets) {

410 SortedTargets.emplace(Target, Frequency);

411 }

412 return SortedTargets;

413 }

414

415

417 float DistributionFactor) {

419 for (const auto &[Target, Frequency] : Targets) {

420 AdjustedTargets[Target] = Frequency * DistributionFactor;

421 }

422 return AdjustedTargets;

423 }

424

425

426

429 void dump() const;

430

432 return NumSamples == Other.NumSamples && CallTargets == Other.CallTargets;

433 }

434

436 return !(*this == Other);

437 }

438

439private:

442};

443

445

446

449 RawContext = 0x1,

450 SyntheticContext = 0x2,

451 InlinedContext = 0x4,

452 MergedContext = 0x8

454

455

461 0x4,

462};

463

464

468

470

473

476 }

477

479 return !(*this == That);

480 }

481

482 std::string toString(bool OutputLineLocation) const {

483 std::ostringstream OContextStr;

484 OContextStr << Func.str();

485 if (OutputLineLocation) {

489 }

490 return OContextStr.str();

491 }

492

496 return NameHash + (LocId << 5) + LocId;

497 }

498};

499

502}

503

506

510 }

511};

512

513

514

515

516

517

518

519

520

521

522

524public:

526

529 assert(Name.empty() && "Name is empty");

530 }

531

534

538 assert(!Context.empty() && "Context is empty");

540 }

541

542

543

544

546 std::list &CSNameTable,

550

551

552 bool HasContext = ContextStr.starts_with("[");

553 if (!HasContext) {

556 } else {

557 CSNameTable.emplace_back();

561 }

562 }

563

564

565

568

569 ContextStr = ContextStr.substr(1, ContextStr.size() - 2);

570 StringRef ContextRemain = ContextStr;

573 while (!ContextRemain.empty()) {

574 auto ContextSplit = ContextRemain.split(" @ ");

575 ChildContext = ContextSplit.first;

576 ContextRemain = ContextSplit.second;

580 }

581 }

582

583

584

588

589 auto EntrySplit = ContextStr.split(':');

591

592 LineLoc = {0, 0};

593 if (!EntrySplit.second.empty()) {

594

595

596 int LineOffset = 0;

597 auto LocSplit = EntrySplit.second.split('.');

598 LocSplit.first.getAsInteger(10, LineOffset);

600

601

602 if (!LocSplit.second.empty())

603 LocSplit.second.getAsInteger(10, LineLoc.Discriminator);

604 }

605 }

606

619

621 bool IncludeLeafLineLocation = false) {

622 std::ostringstream OContextStr;

624 if (OContextStr.str().size()) {

625 OContextStr << " @ ";

626 }

627 OContextStr << Context[I].toString(I != Context.size() - 1 ||

628 IncludeLeafLineLocation);

629 }

630 return OContextStr.str();

631 }

632

635 return Func.str();

637 }

638

643 }

644

645

647 Func = NewFunctionID;

650 }

651

655 FullContext = Context;

657 State = CState;

658 }

659

661 return State == That.State && Func == That.Func &&

662 FullContext == That.FullContext;

663 }

664

666

668 if (State != That.State)

669 return State < That.State;

670

672 return Func < That.Func;

673 }

674

676 while (I < std::min(FullContext.size(), That.FullContext.size())) {

677 auto &Context1 = FullContext[I];

678 auto &Context2 = That.FullContext[I];

679 auto V = Context1.Func.compare(Context2.Func);

680 if (V)

681 return V < 0;

682 if (Context1.Location != Context2.Location)

683 return Context1.Location < Context2.Location;

684 I++;

685 }

686

687 return FullContext.size() < That.FullContext.size();

688 }

689

693 }

694 };

695

697 auto ThisContext = FullContext;

698 auto ThatContext = That.FullContext;

699 if (ThatContext.size() < ThisContext.size())

700 return false;

701 ThatContext = ThatContext.take_front(ThisContext.size());

702

703 if (ThisContext.back().Func != ThatContext.back().Func)

704 return false;

705

707 }

708

709private:

710

711

713

715

717

719};

720

723}

724

727}

728

731

733

734

738 std::unordered_map<LineLocation, LineLocation, LineLocationHash>;

739

740

741

742

743

744

746public:

748

750 void dump() const;

751

753 bool Overflowed;

754 TotalSamples =

758 }

759

761 if (TotalSamples < Num)

762 TotalSamples = 0;

763 else

764 TotalSamples -= Num;

765 }

766

768

770

772 bool Overflowed;

773 TotalHeadSamples =

777 }

778

781 return BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(

782 Num, Weight);

783 }

784

790 return BodySamples[LineLocation(LineOffset, Discriminator)].addCalledTarget(

791 Func, Num, Weight);

792 }

793

797 return BodySamples[Location].merge(SampleRecord, Weight);

798 }

799

800

801

806 auto I = BodySamples.find(LineLocation(LineOffset, Discriminator));

807 if (I != BodySamples.end()) {

808 Count = I->second.removeCalledTarget(Func);

809 Count = I->second.removeSamples(Count);

810 if (I->second.getSamples())

811 BodySamples.erase(I);

812 }

813 return Count;

814 }

815

816

817

819 CallsiteSamples.clear();

820 }

821

822

824 for (auto &I : BodySamples) {

825 uint64_t TargetSamples = I.second.getCallTargetSum();

826

827

828

829

830 if (TargetSamples > I.second.getSamples())

831 I.second.addSamples(TargetSamples - I.second.getSamples());

832 }

833 }

834

835

838 for (const auto &I : BodySamples)

840

841 for (auto &I : CallsiteSamples) {

842 for (auto &CS : I.second) {

843 CS.second.updateTotalSamples();

845 }

846 }

847 }

848

849

852 for (auto &I : CallsiteSamples) {

853 for (auto &CS : I.second) {

854 CS.second.setContextSynthetic();

855 }

856 }

857 }

858

859

861

862

863 if (!IRToProfileLocationMap)

864 return IRLoc;

865 const auto &ProfileLoc = IRToProfileLocationMap->find(IRLoc);

866 if (ProfileLoc != IRToProfileLocationMap->end())

867 return ProfileLoc->second;

868 return IRLoc;

869 }

870

871

872

873

875 uint32_t Discriminator) const {

876 const auto &Ret = BodySamples.find(

878 if (Ret == BodySamples.end())

879 return std::error_code();

880 return Ret->second.getSamples();

881 }

882

883

884

885

888 const auto &Ret = BodySamples.find(

890 if (Ret == BodySamples.end())

891 return std::error_code();

892 return Ret->second.getCallTargets();

893 }

894

895

896

900 if (Ret == BodySamples.end())

901 return std::error_code();

902 return Ret->second.getCallTargets();

903 }

904

905

908 }

909

910

914 if (Iter == CallsiteSamples.end())

915 return nullptr;

916 return &Iter->second;

917 }

918

919

920

921

922

923

924

929 *FuncNameToProfNameMap = nullptr) const;

930

931 bool empty() const { return TotalSamples == 0; }

932

933

935

936

937

938

939

940

941

943

944

945

946

947

948

951

952

954 }

956

957

958 if (!BodySamples.empty() &&

959 (CallsiteSamples.empty() ||

960 BodySamples.begin()->first < CallsiteSamples.begin()->first))

961 Count = BodySamples.begin()->second.getSamples();

962 else if (!CallsiteSamples.empty()) {

963

964

965 for (const auto &FuncSamples : CallsiteSamples.begin()->second)

966 Count += FuncSamples.second.getHeadSamplesEstimate();

967 }

968

969 return Count ? Count : TotalSamples > 0;

970 }

971

972

974

975

977 return CallsiteSamples;

978 }

979

980

981

982

983

987 MaxCount = std::max(MaxCount, L.second.getSamples());

988 if (SkipCallSite)

989 return MaxCount;

991 for (const FunctionSamplesMap::value_type &F : C.second)

992 MaxCount = std::max(MaxCount, F.second.getMaxCountInside());

993 return MaxCount;

994 }

995

996

997

1003 Context = Other.getContext();

1004 if (FunctionHash == 0) {

1005

1006 FunctionHash = Other.getFunctionHash();

1007 } else if (FunctionHash != Other.getFunctionHash()) {

1008

1009

1010

1011

1012

1013

1014

1016 }

1017

1022 for (const auto &I : Other.getBodySamples()) {

1026 }

1027 for (const auto &I : Other.getCallsiteSamples()) {

1030 for (const auto &Rec : I.second)

1032 FSMap[Rec.first].merge(Rec.second, Weight));

1033 }

1034 return Result;

1035 }

1036

1037

1038

1039

1040

1045 if (TotalSamples <= Threshold)

1046 return;

1047 auto IsDeclaration = [](const Function *F) {

1048 return F || F->isDeclaration();

1049 };

1051

1053 }

1054

1055

1056 for (const auto &BS : BodySamples)

1057 for (const auto &TS : BS.second.getCallTargets())

1058 if (TS.second > Threshold) {

1059 const Function *Callee = SymbolMap.lookup(TS.first);

1060 if (IsDeclaration(Callee))

1061 S.insert(TS.first.getHashCode());

1062 }

1063 for (const auto &CS : CallsiteSamples)

1064 for (const auto &NameFS : CS.second)

1065 NameFS.second.findInlinedFunctions(S, SymbolMap, Threshold);

1066 }

1067

1068

1071 }

1072

1073

1075

1076

1078

1080

1082

1084 assert(IRToProfileLocationMap == nullptr && "this should be set only once");

1085 IRToProfileLocationMap = LTLM;

1086 }

1087

1088

1089

1091 const char *AttrName = "sample-profile-suffix-elision-policy";

1092 auto Attr = F.getFnAttribute(AttrName).getValueAsString();

1094 }

1095

1096

1097

1100 static constexpr const char *UniqSuffix = ".__uniq.";

1101

1104

1105

1106

1108 if (Attr == "" || Attr == "all")

1109 return FnName.split('.').first;

1110 if (Attr == "selected") {

1112 for (const auto &Suf : KnownSuffixes) {

1114

1115

1117 continue;

1118 auto It = Cand.rfind(Suffix);

1120 continue;

1121 auto Dit = Cand.rfind('.');

1122 if (Dit == It + Suffix.size() - 1)

1123 Cand = Cand.substr(0, It);

1124 }

1125 return Cand;

1126 }

1127 if (Attr == "none")

1128 return FnName;

1129 assert(false && "internal error: unknown suffix elision policy");

1130 return FnName;

1131 }

1132

1133

1134

1135

1136

1137

1138

1139

1142 return Func.stringRef();

1143

1146 }

1147

1148

1149

1151

1152

1153

1154

1155

1158

1159

1160

1161

1162

1166 }

1167

1168

1169

1170

1171

1172

1173

1174

1175

1176

1177

1178

1179

1184 *FuncNameToProfNameMap = nullptr) const;

1185

1187

1189

1191

1193

1195

1196

1198

1199

1201

1202

1204

1205

1206

1208

1209

1210

1213 }

1214

1215

1216

1218

1223 FunctionHash == Other.FunctionHash && Context == Other.Context &&

1224 TotalSamples == Other.TotalSamples &&

1225 TotalHeadSamples == Other.TotalHeadSamples &&

1226 BodySamples == Other.BodySamples &&

1227 CallsiteSamples == Other.CallsiteSamples;

1228 }

1229

1231 return !(*this == Other);

1232 }

1233

1234private:

1235

1237

1238

1240

1241

1242

1243

1244

1246

1247

1248

1249

1250 uint64_t TotalHeadSamples = 0;

1251

1252

1253

1254

1255

1256

1258

1259

1260

1261

1262

1263

1264

1265

1266

1267

1268

1269

1270

1271

1272

1273

1274

1276

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294 const LocToLocMap *IRToProfileLocationMap = nullptr;

1295};

1296

1297

1298

1303}

1304

1306

1307

1308

1309

1310

1311

1313 : public HashKeyMap<std::unordered_map, SampleContext, FunctionSamples> {

1314public:

1315

1316

1319 if (Ret.second)

1320 Ret.first->second.setContext(Ctx);

1321 return Ret.first->second;

1322 }

1323

1326 Ctx);

1327 }

1328

1331 Ctx);

1332 }

1333

1337 }

1338

1339 size_t erase(const key_type &Key) { return base_type::erase(Key); }

1340

1342};

1343

1345

1347 std::vector &SortedProfiles);

1348

1349

1350

1351

1352

1353template <class LocationT, class SampleT> class SampleSorter {

1354public:

1357

1359 for (const auto &I : Samples)

1362 return A->first < B->first;

1363 });

1364 }

1365

1367

1368private:

1370};

1371

1372

1373

1374

1376public:

1378

1379

1380

1381

1382

1383

1384

1386 bool TrimColdContext,

1387 bool MergeColdContext,

1388 uint32_t ColdContextFrameLength,

1389 bool TrimBaseProfileOnly);

1390

1391private:

1393};

1394

1395

1396

1397

1398

1400public:

1402

1403

1410

1411

1413

1415

1417

1419

1422 };

1423

1425 bool ProfileIsCS = false) {

1427 flattenProfile(ProfileMap, TmpProfiles, ProfileIsCS);

1428 ProfileMap = std::move(TmpProfiles);

1429 }

1430

1433 bool ProfileIsCS = false) {

1434 if (ProfileIsCS) {

1435 for (const auto &I : InputProfiles) {

1436

1437

1439 FS.merge(I.second);

1440 }

1441 } else {

1442 for (const auto &I : InputProfiles)

1443 flattenNestedProfile(OutputProfiles, I.second);

1444 }

1445 }

1446

1447private:

1448 static void flattenNestedProfile(SampleProfileMap &OutputProfiles,

1450

1451

1453 auto Ret = OutputProfiles.try_emplace(Context, FS);

1455 if (Ret.second) {

1456

1457

1458 Profile.removeAllCallsiteSamples();

1459

1460 Profile.setTotalSamples(0);

1461 } else {

1464 }

1465 }

1466

1468 "There should be no inlinees' profiles after flattening.");

1469

1470

1471

1472

1473

1474 uint64_t TotalSamples = FS.getTotalSamples();

1475

1476 for (const auto &I : FS.getCallsiteSamples()) {

1477 for (const auto &Callee : I.second) {

1478 const auto &CalleeProfile = Callee.second;

1479

1480 Profile.addBodySamples(I.first.LineOffset, I.first.Discriminator,

1481 CalleeProfile.getHeadSamplesEstimate());

1482

1483 Profile.addCalledTargetSamples(

1484 I.first.LineOffset, I.first.Discriminator,

1485 CalleeProfile.getFunction(),

1486 CalleeProfile.getHeadSamplesEstimate());

1487

1488 TotalSamples = TotalSamples >= CalleeProfile.getTotalSamples()

1489 ? TotalSamples - CalleeProfile.getTotalSamples()

1490 : 0;

1491 TotalSamples += CalleeProfile.getHeadSamplesEstimate();

1492

1493 flattenNestedProfile(OutputProfiles, CalleeProfile);

1494 }

1495 }

1496 Profile.addTotalSamples(TotalSamples);

1497

1498 Profile.setHeadSamples(Profile.getHeadSamplesEstimate());

1499 }

1500

1501

1503 FrameNode *getOrCreateContextPath(const SampleContext &Context);

1504

1505 SampleProfileMap &ProfileMap;

1506 FrameNode RootFrame;

1507};

1508

1509

1510

1511

1512

1514public:

1515

1516

1518 if (!Copy) {

1519 Syms.insert(Name);

1520 return;

1521 }

1522 Syms.insert(Name.copy(Allocator));

1523 }

1524

1526

1528 for (auto Sym : List.Syms)

1530 }

1531

1532 unsigned size() { return Syms.size(); }

1533

1536

1540

1541private:

1542

1543

1544

1545 bool ToCompress = false;

1548};

1549

1550}

1551

1552using namespace sampleprof;

1553

1556

1559 }

1560

1563 }

1564

1567 }

1568};

1569

1570

1571

1572

1573

1574

1582

1583

1584 llvm::APInt IntHash(128, Str.str(), 16);

1585 return toString(IntHash, 10, false)

1587}

1588

1589}

1590

1591#endif

This file defines the BumpPtrAllocator interface.

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

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

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

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

This file defines the DenseSet and SmallDenseSet classes.

Provides ErrorOr smart pointer.

Defines HashKeyMap template.

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)

Defines FunctionId class.

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

This file defines the SmallVector class.

Class for arbitrary precision integers.

const T & back() const

back - Get the last element.

ArrayRef< T > take_front(size_t N=1) const

Return a copy of *this with only the first N elements.

size_t size() const

size - Get the array size.

ArrayRef< T > drop_back(size_t N=1) const

Drop the last N elements of the array.

bool empty() const

empty - Check if the array is empty.

Allocate memory in an ever growing pool, as if by bump-pointer.

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

Implements a dense probed hash-table based set.

Represents either an error or a value T.

GUID getGUID() const

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

void update(ArrayRef< uint8_t > Data)

Updates the hash for the byte stream provided.

static void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)

Translates the bytes in Res to a hex string that is deposited into Str.

void final(MD5Result &Result)

Finishes off the hash and puts the result in result.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

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.

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

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

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.

constexpr size_t size() const

size - Get the string size.

size_t rfind(char C, size_t From=npos) const

Search for the last character C in the string.

static constexpr size_t npos

Target - Wrapper for Target specific information.

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

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

An opaque object representing a hash code.

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

This class represents a function that is read from a sample profile.

uint64_t getHashCode() const

Get hash code of this object.

std::string str() const

Convert to a string, usually for output purpose.

Representation of the samples collected for a function.

void setTotalSamples(uint64_t Num)

static bool ProfileIsPreInlined

void findInlinedFunctions(DenseSet< GlobalValue::GUID > &S, const HashKeyMap< std::unordered_map, FunctionId, Function * > &SymbolMap, uint64_t Threshold) const

Recursively traverses all children, if the total sample count of the corresponding function is no les...

bool operator!=(const FunctionSamples &Other) const

void updateTotalSamples()

void setHeadSamples(uint64_t Num)

const FunctionSamples * findFunctionSamplesAt(const LineLocation &Loc, StringRef CalleeName, SampleProfileReaderItaniumRemapper *Remapper, const HashKeyMap< std::unordered_map, FunctionId, FunctionId > *FuncNameToProfNameMap=nullptr) const

Returns a pointer to FunctionSamples at the given callsite location Loc with callee CalleeName.

sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)

static constexpr const char * UniqSuffix

void updateCallsiteSamples()

static StringRef getCanonicalFnName(StringRef FnName, StringRef Attr="selected")

bool operator==(const FunctionSamples &Other) const

static constexpr const char * PartSuffix

static uint64_t getCallSiteHash(FunctionId Callee, const LineLocation &Callsite)

Returns a unique hash code for a combination of a callsite location and the callee function name.

const FunctionSamplesMap * findFunctionSamplesMapAt(const LineLocation &Loc) const

Returns the FunctionSamplesMap at the given Loc.

void removeAllCallsiteSamples()

uint64_t getMaxCountInside(bool SkipCallSite=false) const

Return the maximum of sample counts in a function body.

void removeTotalSamples(uint64_t Num)

uint64_t getHeadSamples() const

For top-level functions, return the total number of branch samples that have the function as the bran...

void setFunction(FunctionId NewFunctionID)

Set the name of the function.

ErrorOr< uint64_t > findSamplesAt(uint32_t LineOffset, uint32_t Discriminator) const

Return the number of samples collected at the given location.

ErrorOr< const SampleRecord::CallTargetMap & > findCallTargetMapAt(const LineLocation &CallSite) const

Returns the call target map collected at a given location specified by CallSite.

const LineLocation & mapIRLocToProfileLoc(const LineLocation &IRLoc) const

FunctionId getFunction() const

Return the function name.

uint64_t getFunctionHash() const

static constexpr const char * LLVMSuffix

Name suffixes which canonicalization should handle to avoid profile mismatch.

StringRef getFuncName(FunctionId Func) const

Translate Func into its original name.

sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)

sampleprof_error addSampleRecord(LineLocation Location, const SampleRecord &SampleRecord, uint64_t Weight=1)

uint64_t removeCalledTargetAndBodySample(uint32_t LineOffset, uint32_t Discriminator, FunctionId Func)

DenseMap< uint64_t, StringRef > * GUIDToFuncNameMap

GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for all the function symbols define...

sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, FunctionId Func, uint64_t Num, uint64_t Weight=1)

FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)

Return the function samples at the given callsite location.

const FunctionSamples * findFunctionSamples(const DILocation *DIL, SampleProfileReaderItaniumRemapper *Remapper=nullptr, const HashKeyMap< std::unordered_map, FunctionId, FunctionId > *FuncNameToProfNameMap=nullptr) const

Get the FunctionSamples of the inline instance where DIL originates from.

static bool ProfileIsProbeBased

void setIRToProfileLocationMap(const LocToLocMap *LTLM)

static StringRef getCanonicalFnName(const Function &F)

Return the canonical name for a function, taking into account suffix elision policy attributes.

StringRef getFuncName() const

Return the original function name.

void findAllNames(DenseSet< FunctionId > &NameSet) const

sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)

static unsigned getOffset(const DILocation *DIL)

Returns the line offset to the start line of the subprogram.

void setContextSynthetic()

void setFunctionHash(uint64_t Hash)

static bool ProfileIsFS

If this profile uses flow sensitive discriminators.

ErrorOr< const SampleRecord::CallTargetMap & > findCallTargetMapAt(uint32_t LineOffset, uint32_t Discriminator) const

Returns the call target map collected at a given location.

SampleContext & getContext() const

static bool HasUniqSuffix

Whether the profile contains any ".__uniq." suffix in a name.

uint64_t getTotalSamples() const

Return the total number of samples collected inside the function.

void print(raw_ostream &OS=dbgs(), unsigned Indent=0) const

Print the samples collected for a function on stream OS.

sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight=1)

Merge the samples in Other into this one.

FunctionSamples()=default

const CallsiteSampleMap & getCallsiteSamples() const

Return all the callsite samples collected in the body of the function.

void setContext(const SampleContext &FContext)

static LineLocation getCallSiteIdentifier(const DILocation *DIL, bool ProfileIsFS=false)

Returns a unique call site identifier for a given debug location of a call instruction.

uint64_t getHeadSamplesEstimate() const

Return an estimate of the sample count of the function entry basic block.

uint64_t getGUID() const

Return the GUID of the context's name.

const BodySampleMap & getBodySamples() const

Return all the samples collected in the body of the function.

static bool UseMD5

Whether the profile uses MD5 to represent string.

This class is a wrapper to associative container MapT<KeyT, ValueT> using the hash value of the origi...

std::pair< iterator, bool > try_emplace(const key_type &Hash, const original_key_type &Key, Ts &&...Args)

typename base_type::iterator iterator

decltype(hash_value(SampleContext())) key_type

size_t erase(const original_key_type &Ctx)

iterator find(const original_key_type &Key)

typename base_type::const_iterator const_iterator

Helper class for profile conversion.

static void flattenProfile(SampleProfileMap &ProfileMap, bool ProfileIsCS=false)

static void flattenProfile(const SampleProfileMap &InputProfiles, SampleProfileMap &OutputProfiles, bool ProfileIsCS=false)

ProfileSymbolList records the list of function symbols shown up in the binary used to generate the pr...

void setToCompress(bool TC)

void add(StringRef Name, bool Copy=false)

copy indicates whether we need to copy the underlying memory for the input Name.

std::error_code write(raw_ostream &OS)

void dump(raw_ostream &OS=dbgs()) const

void merge(const ProfileSymbolList &List)

bool contains(StringRef Name)

std::error_code read(const uint8_t *Data, uint64_t ListSize)

SampleContextTrimmer impelements helper functions to trim, merge cold context profiles.

SampleContextTrimmer(SampleProfileMap &Profiles)

void trimAndMergeColdContextProfiles(uint64_t ColdCountThreshold, bool TrimColdContext, bool MergeColdContext, uint32_t ColdContextFrameLength, bool TrimBaseProfileOnly)

static void createCtxVectorFromStr(StringRef ContextStr, SampleContextFrameVector &Context)

Create a context vector from a given context string and save it in Context.

bool operator==(const SampleContext &That) const

void setFunction(FunctionId NewFunctionID)

Set the name of the function and clear the current context.

SampleContext(SampleContextFrames Context, ContextStateMask CState=RawContext)

bool operator<(const SampleContext &That) const

SampleContext(StringRef ContextStr, std::list< SampleContextFrameVector > &CSNameTable, ContextStateMask CState=RawContext)

bool hasState(ContextStateMask S)

void clearState(ContextStateMask S)

SampleContextFrames getContextFrames() const

SampleContext(FunctionId Func)

bool isBaseContext() const

static void decodeContextString(StringRef ContextStr, FunctionId &Func, LineLocation &LineLoc)

static std::string getContextString(SampleContextFrames Context, bool IncludeLeafLineLocation=false)

bool operator!=(const SampleContext &That) const

void setState(ContextStateMask S)

void setAllAttributes(uint32_t A)

uint64_t getHashCode() const

void setContext(SampleContextFrames Context, ContextStateMask CState=RawContext)

FunctionId getFunction() const

uint32_t getAllAttributes()

void setAttribute(ContextAttributeMask A)

bool hasAttribute(ContextAttributeMask A)

std::string toString() const

SampleContext(StringRef Name)

bool isPrefixOf(const SampleContext &That) const

This class provides operator overloads to the map container using MD5 as the key type,...

iterator find(const SampleContext &Ctx)

mapped_type & create(const SampleContext &Ctx)

iterator erase(iterator It)

size_t erase(const key_type &Key)

const_iterator find(const SampleContext &Ctx) const

size_t erase(const SampleContext &Ctx)

SampleProfileReaderItaniumRemapper remaps the profile data from a sample profile data reader,...

Representation of a single sample record.

std::unordered_map< FunctionId, uint64_t > CallTargetMap

bool hasCalls() const

Return true if this sample record contains function calls.

sampleprof_error merge(const SampleRecord &Other, uint64_t Weight=1)

Merge the samples in Other into this record.

static const SortedCallTargetSet sortCallTargets(const CallTargetMap &Targets)

Sort call targets in descending order of call frequency.

const CallTargetMap & getCallTargets() const

std::set< CallTarget, CallTargetComparator > SortedCallTargetSet

uint64_t getSamples() const

uint64_t getCallTargetSum() const

uint64_t removeSamples(uint64_t S)

Decrease the number of samples for this record by S.

sampleprof_error addSamples(uint64_t S, uint64_t Weight=1)

Increment the number of samples for this record by S.

uint64_t removeCalledTarget(FunctionId F)

Remove called function from the call target map.

const SortedCallTargetSet getSortedCallTargets() const

static const CallTargetMap adjustCallTargets(const CallTargetMap &Targets, float DistributionFactor)

Prorate call targets by a distribution factor.

std::pair< FunctionId, uint64_t > CallTarget

bool operator!=(const SampleRecord &Other) const

bool operator==(const SampleRecord &Other) const

void print(raw_ostream &OS, unsigned Indent) const

Print the sample record to the stream OS indented by Indent.

sampleprof_error addCalledTarget(FunctionId F, uint64_t S, uint64_t Weight=1)

Add called function F with samples S.

Sort a LocationT->SampleT map by LocationT.

std::pair< const LocationT, SampleT > SamplesWithLoc

SampleSorter(const std::map< LocationT, SampleT > &Samples)

const SamplesWithLocList & get() const

SmallVector< const SamplesWithLoc *, 20 > SamplesWithLocList

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

static FunctionId getRepInFormat(StringRef Name)

Get the proper representation of a string according to whether the current Format uses MD5 to represe...

static void verifySecFlag(SecType Type, SecFlagType Flag)

ArrayRef< SampleContextFrame > SampleContextFrames

void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)

static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)

std::unordered_map< LineLocation, LineLocation, LineLocationHash > LocToLocMap

std::pair< hash_code, const FunctionSamples * > NameFunctionSamples

static void addSecFlag(SecHdrTableEntry &Entry, SecFlagType Flag)

static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)

std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap

@ ContextDuplicatedIntoBase

std::map< LineLocation, SampleRecord > BodySampleMap

@ SecFlagIsPreInlined

SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...

@ SecFlagPartial

SecFlagPartial means the profile is for common/shared code.

@ SecFlagFSDiscriminator

SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.

@ SecFlagFullContext

SecFlagContext means this is context-sensitive flat profile for CSSPGO.

static void removeSecFlag(SecHdrTableEntry &Entry, SecFlagType Flag)

std::map< FunctionId, FunctionSamples > FunctionSamplesMap

raw_ostream & operator<<(raw_ostream &OS, const FunctionId &Obj)

static std::string getSecName(SecType Type)

uint64_t hash_value(const FunctionId &Obj)

static uint64_t SPVersion()

This is an optimization pass for GlobalISel generic memory operations.

void stable_sort(R &&Range)

std::error_code make_error_code(BitcodeError E)

sampleprof_error mergeSampleProfErrors(sampleprof_error &Accumulator, sampleprof_error Result)

@ unsupported_writing_format

@ ostream_seek_unsupported

raw_ostream & dbgs()

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

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.

const std::error_category & sampleprof_category()

std::string getUniqueInternalLinkagePostfix(const StringRef &FName)

const char * toString(DWARFSectionKind Kind)

hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)

Compute a hash_code for a sequence of values.

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

static unsigned getHashValue(const SampleContext &Val)

static SampleContext getTombstoneKey()

static SampleContext getEmptyKey()

static bool isEqual(const SampleContext &LHS, const SampleContext &RHS)

An information struct used to provide DenseMap with the various necessary components for a given valu...

uint64_t operator()(const LineLocation &Loc) const

Represents the relative location of an instruction.

void print(raw_ostream &OS) const

LineLocation(uint32_t L, uint32_t D)

bool operator!=(const LineLocation &O) const

bool operator<(const LineLocation &O) const

uint64_t getHashCode() const

bool operator==(const LineLocation &O) const

FunctionSamples * FuncSamples

FrameNode(FunctionId FName=FunctionId(), FunctionSamples *FSamples=nullptr, LineLocation CallLoc={0, 0})

FrameNode * getOrCreateChildFrame(const LineLocation &CallSite, FunctionId CalleeName)

std::map< uint64_t, FrameNode > AllChildFrames

uint64_t operator()(const SampleContextFrameVector &S) const

bool operator==(const SampleContextFrame &That) const

SampleContextFrame(FunctionId Func, LineLocation Location)

bool operator!=(const SampleContextFrame &That) const

std::string toString(bool OutputLineLocation) const

uint64_t getHashCode() const

uint64_t operator()(const SampleContext &Context) const

bool operator()(const CallTarget &LHS, const CallTarget &RHS) const