[PGO] Fix deserialize bug

Raw function pointer collected by value
profile data may be from external functions
that are not instrumented. They won't have
mapping data to be used by the deserializer.
Force the value to be 0 in this case.

llvm-svn: 265890
This commit is contained in:
Xinliang David Li 2016-04-10 03:32:02 +00:00
parent cb12255442
commit 284644838f
2 changed files with 43 additions and 1 deletions

View File

@ -398,8 +398,10 @@ uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind,
std::lower_bound(ValueMap->begin(), ValueMap->end(), Value,
[](const std::pair<uint64_t, uint64_t> &LHS,
uint64_t RHS) { return LHS.first < RHS; });
if (Result != ValueMap->end())
if (Result != ValueMap->end() && Result->first == Value)
Value = (uint64_t)Result->second;
else
Value = 0;
break;
}
}

View File

@ -752,6 +752,46 @@ TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write) {
free(VPData);
}
static uint16_t NumValueSites2[IPVK_Last + 1] = {1};
TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write_mapping) {
ValueProfRuntimeRecord RTRecord;
initializeValueProfRuntimeRecord(&RTRecord, &NumValueSites2[0],
&ValueProfNodes[0]);
ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr);
InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2});
InstrProfSymtab Symtab;
Symtab.mapAddress(uint64_t(callee1), 0x1000ULL);
Symtab.mapAddress(uint64_t(callee2), 0x2000ULL);
Symtab.mapAddress(uint64_t(callee3), 0x3000ULL);
Symtab.mapAddress(uint64_t(callee4), 0x4000ULL);
// Missing mapping for callee5
Symtab.finalizeSymtab();
VPData->deserializeTo(Record, &Symtab.getAddrHashMap());
// Now read data from Record and sanity check the data
ASSERT_EQ(1U, Record.getNumValueSites(IPVK_IndirectCallTarget));
ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) {
return VD1.Count > VD2.Count;
};
std::unique_ptr<InstrProfValueData[]> VD_0(
Record.getValueForSite(IPVK_IndirectCallTarget, 0));
std::sort(&VD_0[0], &VD_0[5], Cmp);
ASSERT_EQ(VD_0[0].Value, 0x2000ULL);
ASSERT_EQ(1000U, VD_0[0].Count);
ASSERT_EQ(VD_0[1].Value, 0x3000ULL);
ASSERT_EQ(500U, VD_0[1].Count);
ASSERT_EQ(VD_0[2].Value, 0x1000ULL);
ASSERT_EQ(400U, VD_0[2].Count);
// callee5 does not have a mapped value -- default to 0.
ASSERT_EQ(VD_0[4].Value, 0ULL);
}
TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {
InstrProfRecord Record1("foo", 0x1234, {1ULL << 31, 2});
InstrProfRecord Record2("bar", 0, {1ULL << 63});