+std::error_code
+TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
+
+#define CHECK_LINE_END(Line) \
+ if (Line.is_at_end()) \
+ return error(instrprof_error::truncated);
+#define READ_NUM(Str, Dst) \
+ if ((Str).getAsInteger(10, (Dst))) \
+ return error(instrprof_error::malformed);
+#define VP_READ_ADVANCE(Val) \
+ CHECK_LINE_END(Line); \
+ uint32_t Val; \
+ READ_NUM((*Line), (Val)); \
+ Line++;
+
+ if (Line.is_at_end())
+ return success();
+ uint32_t NumValueKinds;
+ if (Line->getAsInteger(10, NumValueKinds)) {
+ // No value profile data
+ return success();
+ }
+ if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
+ return error(instrprof_error::malformed);
+ Line++;
+
+ for (uint32_t VK = 0; VK < NumValueKinds; VK++) {
+ VP_READ_ADVANCE(ValueKind);
+ if (ValueKind > IPVK_Last)
+ return error(instrprof_error::malformed);
+ VP_READ_ADVANCE(NumValueSites);
+ if (!NumValueSites)
+ continue;
+
+ Record.reserveSites(VK, NumValueSites);
+ for (uint32_t S = 0; S < NumValueSites; S++) {
+ VP_READ_ADVANCE(NumValueData);
+
+ std::vector<InstrProfValueData> CurrentValues;
+ for (uint32_t V = 0; V < NumValueData; V++) {
+ CHECK_LINE_END(Line);
+ std::pair<StringRef, StringRef> VD = Line->split(':');
+ uint64_t TakenCount, Value;
+ READ_NUM(VD.second, TakenCount);
+ if (VK == IPVK_IndirectCallTarget)
+ Value = (uint64_t)StringTable.insertString(VD.first);
+ else {
+ READ_NUM(VD.first, Value);
+ }
+ CurrentValues.push_back({Value, TakenCount});
+ Line++;
+ }
+ Record.addValueData(VK, S, CurrentValues.data(), NumValueData, nullptr);
+ }
+ }
+ return success();
+
+#undef CHECK_LINE_END
+#undef READ_NUM
+#undef VP_READ_ADVANCE
+}
+