diff --git a/include/llvm/ProfileData/InstrProfData.inc b/include/llvm/ProfileData/InstrProfData.inc index 93a69c6640b..77d44f15bed 100644 --- a/include/llvm/ProfileData/InstrProfData.inc +++ b/include/llvm/ProfileData/InstrProfData.inc @@ -384,16 +384,6 @@ typedef struct ValueProfRuntimeRecord { ValueProfNode **NodesKind[IPVK_Last + 1]; } ValueProfRuntimeRecord; -/* Forward declarations of C interfaces. */ -int initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord, - const uint16_t *NumValueSites, - ValueProfNode **Nodes); -void finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord); -uint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record); -ValueProfData * -serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record, - ValueProfData *Dst); -uint32_t getNumValueKindsRT(const void *R); ValueProfRecord *getFirstValueProfRecord(ValueProfData *VPD); ValueProfRecord *getValueProfRecordNext(ValueProfRecord *VPR); InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *VPR); @@ -554,115 +544,6 @@ ValueProfData *serializeValueProfDataFrom(ValueProfRecordClosure *Closure, return VPD; } -/* - * The value profiler runtime library stores the value profile data - * for a given function in \c NumValueSites and \c Nodes structures. - * \c ValueProfRuntimeRecord class is used to encapsulate the runtime - * profile data and provides fast interfaces to retrieve the profile - * information. This interface is used to initialize the runtime record - * and pre-compute the information needed for efficient implementation - * of callbacks required by ValueProfRecordClosure class. - */ -int initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord, - const uint16_t *NumValueSites, - ValueProfNode **Nodes) { - unsigned I, S = 0, NumValueKinds = 0; - RuntimeRecord->NumValueSites = NumValueSites; - RuntimeRecord->Nodes = Nodes; - for (I = 0; I <= IPVK_Last; I++) { - uint16_t N = NumValueSites[I]; - if (!N) - continue; - NumValueKinds++; - - RuntimeRecord->NodesKind[I] = Nodes ? &Nodes[S] : INSTR_PROF_NULLPTR; - S += N; - } - RuntimeRecord->NumValueKinds = NumValueKinds; - return 0; -} - -void finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord) {} - -/* ValueProfRecordClosure Interface implementation for - * ValueProfDataRuntimeRecord. */ -uint32_t getNumValueKindsRT(const void *R) { - return ((const ValueProfRuntimeRecord *)R)->NumValueKinds; -} - -uint32_t getNumValueSitesRT(const void *R, uint32_t VK) { - return ((const ValueProfRuntimeRecord *)R)->NumValueSites[VK]; -} - -uint32_t getNumValueDataForSiteRT(const void *R, uint32_t VK, uint32_t S) { - uint32_t C = 0; - const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R; - ValueProfNode *Site = - Record->NodesKind[VK] ? Record->NodesKind[VK][S] : INSTR_PROF_NULLPTR; - while (Site) { - C++; - Site = Site->Next; - } - if (C > UCHAR_MAX) - C = UCHAR_MAX; - - return C; -} - -uint32_t getNumValueDataRT(const void *R, uint32_t VK) { - unsigned I, S = 0; - const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R; - for (I = 0; I < Record->NumValueSites[VK]; I++) - S += getNumValueDataForSiteRT(Record, VK, I); - return S; -} - -void getValueForSiteRT(const void *R, InstrProfValueData *Dst, uint32_t VK, - uint32_t S) { - unsigned I, N = 0; - const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R; - N = getNumValueDataForSiteRT(R, VK, S); - if (N == 0) - return; - ValueProfNode *VNode = Record->NodesKind[VK][S]; - for (I = 0; I < N; I++) { - Dst[I] = VNode->VData; - VNode = VNode->Next; - } -} - -ValueProfData *allocValueProfDataRT(size_t TotalSizeInBytes) { - return (ValueProfData *)calloc(TotalSizeInBytes, 1); -} - -static ValueProfRecordClosure RTRecordClosure = { - INSTR_PROF_NULLPTR, getNumValueKindsRT, getNumValueSitesRT, - getNumValueDataRT, getNumValueDataForSiteRT, INSTR_PROF_NULLPTR, - getValueForSiteRT, allocValueProfDataRT}; - -/* - * Return the size of ValueProfData structure to store data - * recorded in the runtime record. - */ -uint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record) { - RTRecordClosure.Record = Record; - return getValueProfDataSize(&RTRecordClosure); -} - -/* - * Return a ValueProfData instance that stores the data collected - * from runtime. If \c DstData is provided by the caller, the value - * profile data will be store in *DstData and DstData is returned, - * otherwise the method will allocate space for the value data and - * return pointer to the newly allocated space. - */ -ValueProfData * -serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record, - ValueProfData *DstData) { - RTRecordClosure.Record = Record; - return serializeValueProfDataFrom(&RTRecordClosure, DstData); -} - #undef INSTR_PROF_COMMON_API_IMPL #endif /* INSTR_PROF_COMMON_API_IMPL */ diff --git a/unittests/ProfileData/InstrProfTest.cpp b/unittests/ProfileData/InstrProfTest.cpp index 8659a8fd782..2d9a2218e55 100644 --- a/unittests/ProfileData/InstrProfTest.cpp +++ b/unittests/ProfileData/InstrProfTest.cpp @@ -659,39 +659,36 @@ TEST_P(MaybeSparseInstrProfTest, get_icall_data_merge_site_trunc) { } } -// Synthesize runtime value profile data. -ValueProfNode Site1Values[5] = {{{uint64_t(callee1), 400}, &Site1Values[1]}, - {{uint64_t(callee2), 1000}, &Site1Values[2]}, - {{uint64_t(callee3), 500}, &Site1Values[3]}, - {{uint64_t(callee4), 300}, &Site1Values[4]}, - {{uint64_t(callee5), 100}, nullptr}}; +static void addValueProfData(InstrProfRecord &Record) { + Record.reserveSites(IPVK_IndirectCallTarget, 5); + InstrProfValueData VD0[] = {{uint64_t(callee1), 400}, + {uint64_t(callee2), 1000}, + {uint64_t(callee3), 500}, + {uint64_t(callee4), 300}, + {uint64_t(callee5), 100}}; + Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 5, nullptr); + InstrProfValueData VD1[] = {{uint64_t(callee5), 800}, + {uint64_t(callee3), 1000}, + {uint64_t(callee2), 2500}, + {uint64_t(callee1), 1300}}; + Record.addValueData(IPVK_IndirectCallTarget, 1, VD1, 4, nullptr); + InstrProfValueData VD2[] = {{uint64_t(callee6), 800}, + {uint64_t(callee3), 1000}, + {uint64_t(callee4), 5500}}; + Record.addValueData(IPVK_IndirectCallTarget, 2, VD2, 3, nullptr); + InstrProfValueData VD3[] = {{uint64_t(callee2), 1800}, + {uint64_t(callee3), 2000}}; + Record.addValueData(IPVK_IndirectCallTarget, 3, VD3, 2, nullptr); + Record.addValueData(IPVK_IndirectCallTarget, 4, nullptr, 0, nullptr); +} -ValueProfNode Site2Values[4] = {{{uint64_t(callee5), 800}, &Site2Values[1]}, - {{uint64_t(callee3), 1000}, &Site2Values[2]}, - {{uint64_t(callee2), 2500}, &Site2Values[3]}, - {{uint64_t(callee1), 1300}, nullptr}}; - -ValueProfNode Site3Values[3] = {{{uint64_t(callee6), 800}, &Site3Values[1]}, - {{uint64_t(callee3), 1000}, &Site3Values[2]}, - {{uint64_t(callee4), 5500}, nullptr}}; - -ValueProfNode Site4Values[2] = {{{uint64_t(callee2), 1800}, &Site4Values[1]}, - {{uint64_t(callee3), 2000}, nullptr}}; - -static ValueProfNode *ValueProfNodes[5] = {&Site1Values[0], &Site2Values[0], - &Site3Values[0], &Site4Values[0], - nullptr}; - -static uint16_t NumValueSites[IPVK_Last + 1] = {5}; -TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write) { - ValueProfRuntimeRecord RTRecord; - initializeValueProfRuntimeRecord(&RTRecord, &NumValueSites[0], - &ValueProfNodes[0]); - - ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr); +TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write) { + InstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2}); + addValueProfData(SrcRecord); + std::unique_ptr VPData = + ValueProfData::serializeFrom(SrcRecord); InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2}); - VPData->deserializeTo(Record, nullptr); // Now read data from Record and sanity check the data @@ -748,18 +745,14 @@ TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write) { ASSERT_EQ(2000U, VD_3[0].Count); ASSERT_EQ(StringRef((const char *)VD_3[1].Value, 7), StringRef("callee2")); ASSERT_EQ(1800U, VD_3[1].Count); - - finalizeValueProfRuntimeRecord(&RTRecord); - 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]); +TEST_P(MaybeSparseInstrProfTest, value_prof_data_read_write_mapping) { - ValueProfData *VPData = serializeValueProfDataFromRT(&RTRecord, nullptr); + InstrProfRecord SrcRecord("caller", 0x1234, {1ULL << 31, 2}); + addValueProfData(SrcRecord); + std::unique_ptr VPData = + ValueProfData::serializeFrom(SrcRecord); InstrProfRecord Record("caller", 0x1234, {1ULL << 31, 2}); InstrProfSymtab Symtab; @@ -773,7 +766,7 @@ TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write_mapping) { 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.getNumValueSites(IPVK_IndirectCallTarget)); ASSERT_EQ(5U, Record.getNumValueDataForSite(IPVK_IndirectCallTarget, 0)); auto Cmp = [](const InstrProfValueData &VD1, const InstrProfValueData &VD2) { @@ -791,8 +784,6 @@ TEST_P(MaybeSparseInstrProfTest, runtime_value_prof_data_read_write_mapping) { // callee5 does not have a mapped value -- default to 0. ASSERT_EQ(VD_0[4].Value, 0ULL); - finalizeValueProfRuntimeRecord(&RTRecord); - free(VPData); } TEST_P(MaybeSparseInstrProfTest, get_max_function_count) {