unsigned EncLen = encodeULEB128(UncompressedNameStrings.length(), P);
P += EncLen;
- if (!doCompression) {
- EncLen = encodeULEB128(0, P);
+
+ auto WriteStringToResult = [&](size_t CompressedLen,
+ const std::string &InputStr) {
+ EncLen = encodeULEB128(CompressedLen, P);
P += EncLen;
- Result.append(reinterpret_cast<char *>(&Header[0]), P - &Header[0]);
- Result += UncompressedNameStrings;
+ char *HeaderStr = reinterpret_cast<char *>(&Header[0]);
+ unsigned HeaderLen = P - &Header[0];
+ Result.append(HeaderStr, HeaderLen);
+ Result += InputStr;
return 0;
- }
+ };
+
+ if (!doCompression)
+ return WriteStringToResult(0, UncompressedNameStrings);
+
SmallVector<char, 128> CompressedNameStrings;
zlib::Status Success =
zlib::compress(StringRef(UncompressedNameStrings), CompressedNameStrings,
zlib::BestSizeCompression);
- assert(Success == zlib::StatusOK);
+
if (Success != zlib::StatusOK)
return 1;
- EncLen = encodeULEB128(CompressedNameStrings.size(), P);
- P += EncLen;
- Result.append(reinterpret_cast<char *>(&Header[0]), P - &Header[0]);
- Result +=
- std::string(CompressedNameStrings.data(), CompressedNameStrings.size());
- return 0;
+
+ return WriteStringToResult(
+ CompressedNameStrings.size(),
+ std::string(CompressedNameStrings.data(), CompressedNameStrings.size()));
}
StringRef getPGOFuncNameInitializer(GlobalVariable *NameVar) {
P += UncompressedSize;
}
// Now parse the name strings.
- size_t NameStart = 0;
- bool isLast = false;
- do {
- size_t NameStop = NameStrings.find(' ', NameStart);
- if (NameStop == StringRef::npos)
- NameStop = NameStrings.size();
- if (NameStop >= NameStrings.size() - 1)
- isLast = true;
- StringRef Name = NameStrings.substr(NameStart, NameStop - NameStart);
+ SmallVector<StringRef, 0> Names;
+ NameStrings.split(Names, ' ');
+ for (StringRef &Name : Names)
Symtab.addFuncName(Name);
- if (isLast)
- break;
- NameStart = NameStop + 1;
- } while (true);
while (P < EndP && *P == 0)
P++;
return 0;
}
-instrprof_error
-InstrProfValueSiteRecord::mergeValueData(InstrProfValueSiteRecord &Input,
- uint64_t Weight) {
+instrprof_error InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input,
+ uint64_t Weight) {
this->sortByTargetValues();
Input.sortByTargetValues();
auto I = ValueData.begin();
while (I != IE && I->Value < J->Value)
++I;
if (I != IE && I->Value == J->Value) {
- uint64_t JCount = J->Count;
bool Overflowed;
- if (Weight > 1) {
- JCount = SaturatingMultiply(JCount, Weight, &Overflowed);
- if (Overflowed)
- Result = instrprof_error::counter_overflow;
- }
- I->Count = SaturatingAdd(I->Count, JCount, &Overflowed);
+ I->Count = SaturatingMultiplyAdd(J->Count, Weight, I->Count, &Overflowed);
if (Overflowed)
Result = instrprof_error::counter_overflow;
++I;
return Result;
}
+instrprof_error InstrProfValueSiteRecord::scale(uint64_t Weight) {
+ instrprof_error Result = instrprof_error::success;
+ for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) {
+ bool Overflowed;
+ I->Count = SaturatingMultiply(I->Count, Weight, &Overflowed);
+ if (Overflowed)
+ Result = instrprof_error::counter_overflow;
+ }
+ return Result;
+}
+
// Merge Value Profile data from Src record to this record for ValueKind.
// Scale merged value counts by \p Weight.
instrprof_error InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
Src.getValueSitesForKind(ValueKind);
instrprof_error Result = instrprof_error::success;
for (uint32_t I = 0; I < ThisNumValueSites; I++)
- MergeResult(Result,
- ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I], Weight));
+ MergeResult(Result, ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight));
return Result;
}
for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
bool Overflowed;
- uint64_t OtherCount = Other.Counts[I];
- if (Weight > 1) {
- OtherCount = SaturatingMultiply(OtherCount, Weight, &Overflowed);
- if (Overflowed)
- Result = instrprof_error::counter_overflow;
- }
- Counts[I] = SaturatingAdd(Counts[I], OtherCount, &Overflowed);
+ Counts[I] =
+ SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed);
if (Overflowed)
Result = instrprof_error::counter_overflow;
}
return Result;
}
+instrprof_error InstrProfRecord::scaleValueProfData(uint32_t ValueKind,
+ uint64_t Weight) {
+ uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
+ std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
+ getValueSitesForKind(ValueKind);
+ instrprof_error Result = instrprof_error::success;
+ for (uint32_t I = 0; I < ThisNumValueSites; I++)
+ MergeResult(Result, ThisSiteRecords[I].scale(Weight));
+ return Result;
+}
+
+instrprof_error InstrProfRecord::scale(uint64_t Weight) {
+ instrprof_error Result = instrprof_error::success;
+ for (auto &Count : this->Counts) {
+ bool Overflowed;
+ Count = SaturatingMultiply(Count, Weight, &Overflowed);
+ if (Overflowed && Result == instrprof_error::success) {
+ Result = instrprof_error::counter_overflow;
+ }
+ }
+ for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
+ MergeResult(Result, scaleValueProfData(Kind, Weight));
+
+ return Result;
+}
+
// Map indirect call target name hash to name string.
uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind,
ValueMapType *ValueMap) {