Skip to content

Commit 88fbc4d

Browse files
[ThinLTO] Add tail call flag to call edges in summary (#74043)
This adds support for a HasTailCall flag on function call edges in the ThinLTO summary. It is intended for use in aiding discovery of missing frames from tail calls in profiled call stacks for MemProf of profiled binaries that did not disable tail call elimination. A follow on change will add the use of this new flag during MemProf context disambiguation. The new flag is encoded in the bitcode along with either the hotness flag from the profile, or the relative block frequency under the -write-relbf-to-summary flag when there is no profile data. Because we now will always have some additional call edge information, I have removed the non-profile function summary record format, and we simply encode the tail call flag along with a hotness type of none when there is no profile information or relative block frequency. The change of record format and name caused most of the test case changes. I have added explicit testing of generation of the new tail call flag into the bitcode and IR assembly format as part of the changes to llvm/test/Bitcode/thinlto-function-summary-refgraph.ll. I have also added round trip testing through assembly and bitcode to llvm/test/Assembler/thinlto-summary.ll.
1 parent 8186e15 commit 88fbc4d

27 files changed

+239
-194
lines changed

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ enum GlobalValueSummarySymtabCodes {
210210
FS_PERMODULE = 1,
211211
// PERMODULE_PROFILE: [valueid, flags, instcount, numrefs,
212212
// numrefs x valueid,
213-
// n x (valueid, hotness)]
213+
// n x (valueid, hotness+tailcall)]
214214
FS_PERMODULE_PROFILE = 2,
215215
// PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, n x valueid]
216216
FS_PERMODULE_GLOBALVAR_INIT_REFS = 3,
@@ -219,7 +219,7 @@ enum GlobalValueSummarySymtabCodes {
219219
FS_COMBINED = 4,
220220
// COMBINED_PROFILE: [valueid, modid, flags, instcount, numrefs,
221221
// numrefs x valueid,
222-
// n x (valueid, hotness)]
222+
// n x (valueid, hotness+tailcall)]
223223
FS_COMBINED_PROFILE = 5,
224224
// COMBINED_GLOBALVAR_INIT_REFS: [valueid, modid, flags, n x valueid]
225225
FS_COMBINED_GLOBALVAR_INIT_REFS = 6,
@@ -268,7 +268,7 @@ enum GlobalValueSummarySymtabCodes {
268268
// Per-module summary that also adds relative block frequency to callee info.
269269
// PERMODULE_RELBF: [valueid, flags, instcount, numrefs,
270270
// numrefs x valueid,
271-
// n x (valueid, relblockfreq)]
271+
// n x (valueid, relblockfreq+tailcall)]
272272
FS_PERMODULE_RELBF = 19,
273273
// Index-wide flags
274274
FS_FLAGS = 20,

llvm/include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,31 @@ struct CalleeInfo {
6868
// added to HotnessType enum.
6969
uint32_t Hotness : 3;
7070

71+
// True if at least one of the calls to the callee is a tail call.
72+
bool HasTailCall : 1;
73+
7174
/// The value stored in RelBlockFreq has to be interpreted as the digits of
7275
/// a scaled number with a scale of \p -ScaleShift.
73-
uint32_t RelBlockFreq : 29;
76+
static constexpr unsigned RelBlockFreqBits = 28;
77+
uint32_t RelBlockFreq : RelBlockFreqBits;
7478
static constexpr int32_t ScaleShift = 8;
75-
static constexpr uint64_t MaxRelBlockFreq = (1 << 29) - 1;
79+
static constexpr uint64_t MaxRelBlockFreq = (1 << RelBlockFreqBits) - 1;
7680

7781
CalleeInfo()
78-
: Hotness(static_cast<uint32_t>(HotnessType::Unknown)), RelBlockFreq(0) {}
79-
explicit CalleeInfo(HotnessType Hotness, uint64_t RelBF)
80-
: Hotness(static_cast<uint32_t>(Hotness)), RelBlockFreq(RelBF) {}
82+
: Hotness(static_cast<uint32_t>(HotnessType::Unknown)),
83+
HasTailCall(false), RelBlockFreq(0) {}
84+
explicit CalleeInfo(HotnessType Hotness, bool HasTC, uint64_t RelBF)
85+
: Hotness(static_cast<uint32_t>(Hotness)), HasTailCall(HasTC),
86+
RelBlockFreq(RelBF) {}
8187

8288
void updateHotness(const HotnessType OtherHotness) {
8389
Hotness = std::max(Hotness, static_cast<uint32_t>(OtherHotness));
8490
}
8591

92+
bool hasTailCall() const { return HasTailCall; }
93+
94+
void setHasTailCall(const bool HasTC) { HasTailCall = HasTC; }
95+
8696
HotnessType getHotness() const { return HotnessType(Hotness); }
8797

8898
/// Update \p RelBlockFreq from \p BlockFreq and \p EntryFreq

llvm/lib/Analysis/ModuleSummaryAnalysis.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ static void computeFunctionSummary(
409409
auto &ValueInfo = CallGraphEdges[Index.getOrInsertValueInfo(
410410
cast<GlobalValue>(CalledValue))];
411411
ValueInfo.updateHotness(Hotness);
412+
if (CB->isTailCall())
413+
ValueInfo.setHasTailCall(true);
412414
// Add the relative block frequency to CalleeInfo if there is no profile
413415
// information.
414416
if (BFI != nullptr && Hotness == CalleeInfo::HotnessType::Unknown) {

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9096,7 +9096,8 @@ bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
90969096
/// OptionalCalls
90979097
/// := 'calls' ':' '(' Call [',' Call]* ')'
90989098
/// Call ::= '(' 'callee' ':' GVReference
9099-
/// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]? ')'
9099+
/// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]?
9100+
/// [ ',' 'tail' ]? ')'
91009101
bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
91019102
assert(Lex.getKind() == lltok::kw_calls);
91029103
Lex.Lex();
@@ -9121,23 +9122,39 @@ bool LLParser::parseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls) {
91219122

91229123
CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
91239124
unsigned RelBF = 0;
9124-
if (EatIfPresent(lltok::comma)) {
9125-
// Expect either hotness or relbf
9126-
if (EatIfPresent(lltok::kw_hotness)) {
9125+
unsigned HasTailCall = false;
9126+
9127+
// parse optional fields
9128+
while (EatIfPresent(lltok::comma)) {
9129+
switch (Lex.getKind()) {
9130+
case lltok::kw_hotness:
9131+
Lex.Lex();
91279132
if (parseToken(lltok::colon, "expected ':'") || parseHotness(Hotness))
91289133
return true;
9129-
} else {
9130-
if (parseToken(lltok::kw_relbf, "expected relbf") ||
9131-
parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF))
9134+
break;
9135+
case lltok::kw_relbf:
9136+
Lex.Lex();
9137+
if (parseToken(lltok::colon, "expected ':'") || parseUInt32(RelBF))
9138+
return true;
9139+
break;
9140+
case lltok::kw_tail:
9141+
Lex.Lex();
9142+
if (parseToken(lltok::colon, "expected ':'") || parseFlag(HasTailCall))
91329143
return true;
9144+
break;
9145+
default:
9146+
return error(Lex.getLoc(), "expected hotness, relbf, or tail");
91339147
}
91349148
}
9149+
if (Hotness != CalleeInfo::HotnessType::Unknown && RelBF > 0)
9150+
return tokError("Expected only one of hotness or relbf");
91359151
// Keep track of the Call array index needing a forward reference.
91369152
// We will save the location of the ValueInfo needing an update, but
91379153
// can only do so once the std::vector is finalized.
91389154
if (VI.getRef() == FwdVIRef)
91399155
IdToIndexMap[GVId].push_back(std::make_pair(Calls.size(), Loc));
9140-
Calls.push_back(FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, RelBF)});
9156+
Calls.push_back(
9157+
FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, HasTailCall, RelBF)});
91419158

91429159
if (parseToken(lltok::rparen, "expected ')' in call"))
91439160
return true;

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,22 @@ static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) {
11171117
(GlobalObject::VCallVisibility)(RawFlags >> 3));
11181118
}
11191119

1120+
static std::pair<CalleeInfo::HotnessType, bool>
1121+
getDecodedHotnessCallEdgeInfo(uint64_t RawFlags) {
1122+
CalleeInfo::HotnessType Hotness =
1123+
static_cast<CalleeInfo::HotnessType>(RawFlags & 0x7); // 3 bits
1124+
bool HasTailCall = (RawFlags & 0x8); // 1 bit
1125+
return {Hotness, HasTailCall};
1126+
}
1127+
1128+
static void getDecodedRelBFCallEdgeInfo(uint64_t RawFlags, uint64_t &RelBF,
1129+
bool &HasTailCall) {
1130+
static constexpr uint64_t RelBlockFreqMask =
1131+
(1 << CalleeInfo::RelBlockFreqBits) - 1;
1132+
RelBF = RawFlags & RelBlockFreqMask; // RelBlockFreqBits bits
1133+
HasTailCall = (RawFlags & (1 << CalleeInfo::RelBlockFreqBits)); // 1 bit
1134+
}
1135+
11201136
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
11211137
switch (Val) {
11221138
default: // Map unknown visibilities to default.
@@ -7032,17 +7048,20 @@ ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record,
70327048
Ret.reserve(Record.size());
70337049
for (unsigned I = 0, E = Record.size(); I != E; ++I) {
70347050
CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
7051+
bool HasTailCall = false;
70357052
uint64_t RelBF = 0;
70367053
ValueInfo Callee = std::get<0>(getValueInfoFromValueId(Record[I]));
70377054
if (IsOldProfileFormat) {
70387055
I += 1; // Skip old callsitecount field
70397056
if (HasProfile)
70407057
I += 1; // Skip old profilecount field
70417058
} else if (HasProfile)
7042-
Hotness = static_cast<CalleeInfo::HotnessType>(Record[++I]);
7059+
std::tie(Hotness, HasTailCall) =
7060+
getDecodedHotnessCallEdgeInfo(Record[++I]);
70437061
else if (HasRelBF)
7044-
RelBF = Record[++I];
7045-
Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo(Hotness, RelBF)});
7062+
getDecodedRelBFCallEdgeInfo(Record[++I], RelBF, HasTailCall);
7063+
Ret.push_back(FunctionSummary::EdgeTy{
7064+
Callee, CalleeInfo(Hotness, HasTailCall, RelBF)});
70467065
}
70477066
return Ret;
70487067
}
@@ -7256,14 +7275,15 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
72567275
TheIndex.getOrInsertValueInfo(RefGUID), RefGUID, RefGUID);
72577276
break;
72587277
}
7278+
// FS_PERMODULE is legacy and does not have support for the tail call flag.
72597279
// FS_PERMODULE: [valueid, flags, instcount, fflags, numrefs,
72607280
// numrefs x valueid, n x (valueid)]
72617281
// FS_PERMODULE_PROFILE: [valueid, flags, instcount, fflags, numrefs,
72627282
// numrefs x valueid,
7263-
// n x (valueid, hotness)]
7283+
// n x (valueid, hotness+tailcall flags)]
72647284
// FS_PERMODULE_RELBF: [valueid, flags, instcount, fflags, numrefs,
72657285
// numrefs x valueid,
7266-
// n x (valueid, relblockfreq)]
7286+
// n x (valueid, relblockfreq+tailcall)]
72677287
case bitc::FS_PERMODULE:
72687288
case bitc::FS_PERMODULE_RELBF:
72697289
case bitc::FS_PERMODULE_PROFILE: {
@@ -7410,10 +7430,12 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
74107430
TheIndex.addGlobalValueSummary(std::get<0>(GUID), std::move(VS));
74117431
break;
74127432
}
7433+
// FS_COMBINED is legacy and does not have support for the tail call flag.
74137434
// FS_COMBINED: [valueid, modid, flags, instcount, fflags, numrefs,
74147435
// numrefs x valueid, n x (valueid)]
74157436
// FS_COMBINED_PROFILE: [valueid, modid, flags, instcount, fflags, numrefs,
7416-
// numrefs x valueid, n x (valueid, hotness)]
7437+
// numrefs x valueid,
7438+
// n x (valueid, hotness+tailcall flags)]
74177439
case bitc::FS_COMBINED:
74187440
case bitc::FS_COMBINED_PROFILE: {
74197441
unsigned ValueID = Record[0];

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,24 @@ static uint64_t getEncodedGVarFlags(GlobalVarSummary::GVarFlags Flags) {
11571157
return RawFlags;
11581158
}
11591159

1160+
static uint64_t getEncodedHotnessCallEdgeInfo(const CalleeInfo &CI) {
1161+
uint64_t RawFlags = 0;
1162+
1163+
RawFlags |= CI.Hotness; // 3 bits
1164+
RawFlags |= (CI.HasTailCall << 3); // 1 bit
1165+
1166+
return RawFlags;
1167+
}
1168+
1169+
static uint64_t getEncodedRelBFCallEdgeInfo(const CalleeInfo &CI) {
1170+
uint64_t RawFlags = 0;
1171+
1172+
RawFlags |= CI.RelBlockFreq; // CalleeInfo::RelBlockFreqBits bits
1173+
RawFlags |= (CI.HasTailCall << CalleeInfo::RelBlockFreqBits); // 1 bit
1174+
1175+
return RawFlags;
1176+
}
1177+
11601178
static unsigned getEncodedVisibility(const GlobalValue &GV) {
11611179
switch (GV.getVisibility()) {
11621180
case GlobalValue::DefaultVisibility: return 0;
@@ -4009,8 +4027,9 @@ static void writeFunctionHeapProfileRecords(
40094027
// Helper to emit a single function summary record.
40104028
void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
40114029
SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary,
4012-
unsigned ValueID, unsigned FSCallsAbbrev, unsigned FSCallsProfileAbbrev,
4013-
unsigned CallsiteAbbrev, unsigned AllocAbbrev, const Function &F) {
4030+
unsigned ValueID, unsigned FSCallsRelBFAbbrev,
4031+
unsigned FSCallsProfileAbbrev, unsigned CallsiteAbbrev,
4032+
unsigned AllocAbbrev, const Function &F) {
40144033
NameVals.push_back(ValueID);
40154034

40164035
FunctionSummary *FS = cast<FunctionSummary>(Summary);
@@ -4037,21 +4056,21 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord(
40374056
for (auto &RI : FS->refs())
40384057
NameVals.push_back(VE.getValueID(RI.getValue()));
40394058

4040-
bool HasProfileData =
4041-
F.hasProfileData() || ForceSummaryEdgesCold != FunctionSummary::FSHT_None;
4059+
const bool UseRelBFRecord =
4060+
WriteRelBFToSummary && !F.hasProfileData() &&
4061+
ForceSummaryEdgesCold == FunctionSummary::FSHT_None;
40424062
for (auto &ECI : FS->calls()) {
40434063
NameVals.push_back(getValueId(ECI.first));
4044-
if (HasProfileData)
4045-
NameVals.push_back(static_cast<uint8_t>(ECI.second.Hotness));
4046-
else if (WriteRelBFToSummary)
4047-
NameVals.push_back(ECI.second.RelBlockFreq);
4064+
if (UseRelBFRecord)
4065+
NameVals.push_back(getEncodedRelBFCallEdgeInfo(ECI.second));
4066+
else
4067+
NameVals.push_back(getEncodedHotnessCallEdgeInfo(ECI.second));
40484068
}
40494069

4050-
unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
4070+
unsigned FSAbbrev =
4071+
(UseRelBFRecord ? FSCallsRelBFAbbrev : FSCallsProfileAbbrev);
40514072
unsigned Code =
4052-
(HasProfileData ? bitc::FS_PERMODULE_PROFILE
4053-
: (WriteRelBFToSummary ? bitc::FS_PERMODULE_RELBF
4054-
: bitc::FS_PERMODULE));
4073+
(UseRelBFRecord ? bitc::FS_PERMODULE_RELBF : bitc::FS_PERMODULE_PROFILE);
40554074

40564075
// Emit the finished record.
40574076
Stream.EmitRecord(Code, NameVals, FSAbbrev);
@@ -4160,28 +4179,25 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
41604179
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
41614180
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // rorefcnt
41624181
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // worefcnt
4163-
// numrefs x valueid, n x (valueid, hotness)
4182+
// numrefs x valueid, n x (valueid, hotness+tailcall flags)
41644183
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
41654184
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
41664185
unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(std::move(Abbv));
41674186

4168-
// Abbrev for FS_PERMODULE or FS_PERMODULE_RELBF.
4187+
// Abbrev for FS_PERMODULE_RELBF.
41694188
Abbv = std::make_shared<BitCodeAbbrev>();
4170-
if (WriteRelBFToSummary)
4171-
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_RELBF));
4172-
else
4173-
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE));
4189+
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_RELBF));
41744190
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
41754191
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
41764192
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
41774193
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
41784194
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
41794195
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // rorefcnt
41804196
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // worefcnt
4181-
// numrefs x valueid, n x (valueid [, rel_block_freq])
4197+
// numrefs x valueid, n x (valueid, rel_block_freq+tailcall])
41824198
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
41834199
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
4184-
unsigned FSCallsAbbrev = Stream.EmitAbbrev(std::move(Abbv));
4200+
unsigned FSCallsRelBFAbbrev = Stream.EmitAbbrev(std::move(Abbv));
41854201

41864202
// Abbrev for FS_PERMODULE_GLOBALVAR_INIT_REFS.
41874203
Abbv = std::make_shared<BitCodeAbbrev>();
@@ -4253,9 +4269,9 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {
42534269
continue;
42544270
}
42554271
auto *Summary = VI.getSummaryList()[0].get();
4256-
writePerModuleFunctionSummaryRecord(NameVals, Summary, VE.getValueID(&F),
4257-
FSCallsAbbrev, FSCallsProfileAbbrev,
4258-
CallsiteAbbrev, AllocAbbrev, F);
4272+
writePerModuleFunctionSummaryRecord(
4273+
NameVals, Summary, VE.getValueID(&F), FSCallsRelBFAbbrev,
4274+
FSCallsProfileAbbrev, CallsiteAbbrev, AllocAbbrev, F);
42594275
}
42604276

42614277
// Capture references from GlobalVariable initializers, which are outside
@@ -4326,25 +4342,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
43264342
Stream.EmitRecord(bitc::FS_STACK_IDS, StackIds, StackIdAbbvId);
43274343
}
43284344

4329-
// Abbrev for FS_COMBINED.
4330-
auto Abbv = std::make_shared<BitCodeAbbrev>();
4331-
Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED));
4332-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
4333-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
4334-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // flags
4335-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // instcount
4336-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // fflags
4337-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // entrycount
4338-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
4339-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // rorefcnt
4340-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // worefcnt
4341-
// numrefs x valueid, n x (valueid)
4342-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
4343-
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
4344-
unsigned FSCallsAbbrev = Stream.EmitAbbrev(std::move(Abbv));
4345-
43464345
// Abbrev for FS_COMBINED_PROFILE.
4347-
Abbv = std::make_shared<BitCodeAbbrev>();
4346+
auto Abbv = std::make_shared<BitCodeAbbrev>();
43484347
Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_PROFILE));
43494348
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // valueid
43504349
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // modid
@@ -4355,7 +4354,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
43554354
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numrefs
43564355
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // rorefcnt
43574356
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // worefcnt
4358-
// numrefs x valueid, n x (valueid, hotness)
4357+
// numrefs x valueid, n x (valueid, hotness+tailcall flags)
43594358
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
43604359
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
43614360
unsigned FSCallsProfileAbbrev = Stream.EmitAbbrev(std::move(Abbv));
@@ -4535,31 +4534,19 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
45354534
NameVals[7] = RORefCnt;
45364535
NameVals[8] = WORefCnt;
45374536

4538-
bool HasProfileData = false;
4539-
for (auto &EI : FS->calls()) {
4540-
HasProfileData |=
4541-
EI.second.getHotness() != CalleeInfo::HotnessType::Unknown;
4542-
if (HasProfileData)
4543-
break;
4544-
}
4545-
45464537
for (auto &EI : FS->calls()) {
45474538
// If this GUID doesn't have a value id, it doesn't have a function
45484539
// summary and we don't need to record any calls to it.
45494540
std::optional<unsigned> CallValueId = GetValueId(EI.first);
45504541
if (!CallValueId)
45514542
continue;
45524543
NameVals.push_back(*CallValueId);
4553-
if (HasProfileData)
4554-
NameVals.push_back(static_cast<uint8_t>(EI.second.Hotness));
4544+
NameVals.push_back(getEncodedHotnessCallEdgeInfo(EI.second));
45554545
}
45564546

4557-
unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
4558-
unsigned Code =
4559-
(HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
4560-
45614547
// Emit the finished record.
4562-
Stream.EmitRecord(Code, NameVals, FSAbbrev);
4548+
Stream.EmitRecord(bitc::FS_COMBINED_PROFILE, NameVals,
4549+
FSCallsProfileAbbrev);
45634550
NameVals.clear();
45644551
MaybeEmitOriginalName(*S);
45654552
});

0 commit comments

Comments
 (0)