Index: include/llvm/ProfileData/InstrProf.h =================================================================== --- include/llvm/ProfileData/InstrProf.h +++ include/llvm/ProfileData/InstrProf.h @@ -581,16 +581,15 @@ /// Merge data from another InstrProfValueSiteRecord /// Optionally scale merged counts by \p Weight. - void merge(SoftInstrProfErrors &SIPE, InstrProfValueSiteRecord &Input, - uint64_t Weight = 1); + void merge(function_ref Warn, + InstrProfValueSiteRecord &Input, uint64_t Weight = 1); /// Scale up value profile data counts. - void scale(SoftInstrProfErrors &SIPE, uint64_t Weight); + void scale(function_ref Warn, uint64_t Weight); }; /// Profiling information for a single function. struct InstrProfRecord { std::vector Counts; - SoftInstrProfErrors SIPE; InstrProfRecord() = default; InstrProfRecord(std::vector Counts) : Counts(std::move(Counts)) {} @@ -653,11 +652,12 @@ /// Merge the counts in \p Other into this one. /// Optionally scale merged counts by \p Weight. - void merge(InstrProfRecord &Other, uint64_t Weight = 1); + void merge(function_ref Warn, InstrProfRecord &Other, + uint64_t Weight = 1); /// Scale up profile counts (including value profile data) by /// \p Weight. - void scale(uint64_t Weight); + void scale(function_ref Warn, uint64_t Weight); /// Sort value profile data (per site) by count. void sortValueData() { @@ -675,9 +675,6 @@ /// Clear value data entries void clearValueData() { ValueData = nullptr; } - /// Get the error contained within the record's soft error counter. - Error takeError() { return SIPE.takeError(); } - private: struct ValueProfData { std::vector IndirectCallSites; @@ -729,11 +726,13 @@ // Merge Value Profile data from Src record to this record for ValueKind. // Scale merged value counts by \p Weight. - void mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src, + void mergeValueProfData(function_ref Warn, + uint32_t ValueKind, InstrProfRecord &Src, uint64_t Weight); // Scale up value profile data count. - void scaleValueProfData(uint32_t ValueKind, uint64_t Weight); + void scaleValueProfData(function_ref Warn, + uint32_t ValueKind, uint64_t Weight); }; struct NamedInstrProfRecord : InstrProfRecord { Index: include/llvm/ProfileData/InstrProfWriter.h =================================================================== --- include/llvm/ProfileData/InstrProfWriter.h +++ include/llvm/ProfileData/InstrProfWriter.h @@ -51,10 +51,12 @@ /// Add function counts for the given function. If there are already counts /// for this function and the hash and number of counts match, each counter is /// summed. Optionally scale counts by \p Weight. - Error addRecord(NamedInstrProfRecord &&I, uint64_t Weight = 1); + void addRecord(function_ref Warn, NamedInstrProfRecord &&I, + uint64_t Weight = 1); /// Merge existing function counts from the given writer. - Error mergeRecordsFromWriter(InstrProfWriter &&IPW); + void mergeRecordsFromWriter(function_ref Warn, + InstrProfWriter &&IPW); /// Write the profile to \c OS void write(raw_fd_ostream &OS); @@ -87,8 +89,8 @@ void setOutputSparse(bool Sparse); private: - Error addRecord(StringRef Name, uint64_t Hash, InstrProfRecord &&I, - uint64_t Weight = 1); + void addRecord(function_ref Warn, StringRef Name, uint64_t Hash, + InstrProfRecord &&I, uint64_t Weight = 1); bool shouldEncodeData(const ProfilingData &PD); void writeImpl(ProfOStream &OS); }; Index: lib/ProfileData/InstrProf.cpp =================================================================== --- lib/ProfileData/InstrProf.cpp +++ lib/ProfileData/InstrProf.cpp @@ -460,7 +460,7 @@ return Error::success(); } -void InstrProfValueSiteRecord::merge(SoftInstrProfErrors &SIPE, +void InstrProfValueSiteRecord::merge(function_ref Warn, InstrProfValueSiteRecord &Input, uint64_t Weight) { this->sortByTargetValues(); @@ -475,7 +475,7 @@ bool Overflowed; I->Count = SaturatingMultiplyAdd(J->Count, Weight, I->Count, &Overflowed); if (Overflowed) - SIPE.addError(instrprof_error::counter_overflow); + Warn(instrprof_error::counter_overflow); ++I; continue; } @@ -483,25 +483,25 @@ } } -void InstrProfValueSiteRecord::scale(SoftInstrProfErrors &SIPE, +void InstrProfValueSiteRecord::scale(function_ref Warn, uint64_t Weight) { for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) { bool Overflowed; I->Count = SaturatingMultiply(I->Count, Weight, &Overflowed); if (Overflowed) - SIPE.addError(instrprof_error::counter_overflow); + Warn(instrprof_error::counter_overflow); } } // Merge Value Profile data from Src record to this record for ValueKind. // Scale merged value counts by \p Weight. -void InstrProfRecord::mergeValueProfData(uint32_t ValueKind, - InstrProfRecord &Src, - uint64_t Weight) { +void InstrProfRecord::mergeValueProfData( + function_ref Warn, uint32_t ValueKind, + InstrProfRecord &Src, uint64_t Weight) { uint32_t ThisNumValueSites = getNumValueSites(ValueKind); uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind); if (ThisNumValueSites != OtherNumValueSites) { - SIPE.addError(instrprof_error::value_site_count_mismatch); + Warn(instrprof_error::value_site_count_mismatch); return; } if (!ThisNumValueSites) @@ -511,14 +511,15 @@ MutableArrayRef OtherSiteRecords = Src.getValueSitesForKind(ValueKind); for (uint32_t I = 0; I < ThisNumValueSites; I++) - ThisSiteRecords[I].merge(SIPE, OtherSiteRecords[I], Weight); + ThisSiteRecords[I].merge(Warn, OtherSiteRecords[I], Weight); } -void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight) { +void InstrProfRecord::merge(function_ref Warn, + InstrProfRecord &Other, uint64_t Weight) { // If the number of counters doesn't match we either have bad data // or a hash collision. if (Counts.size() != Other.Counts.size()) { - SIPE.addError(instrprof_error::count_mismatch); + Warn(instrprof_error::count_mismatch); return; } @@ -527,27 +528,30 @@ Counts[I] = SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed); if (Overflowed) - SIPE.addError(instrprof_error::counter_overflow); + Warn(instrprof_error::counter_overflow); } for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) - mergeValueProfData(Kind, Other, Weight); + mergeValueProfData(Warn, Kind, Other, Weight); } -void InstrProfRecord::scaleValueProfData(uint32_t ValueKind, uint64_t Weight) { +void InstrProfRecord::scaleValueProfData( + function_ref Warn, uint32_t ValueKind, + uint64_t Weight) { for (auto &R : getValueSitesForKind(ValueKind)) - R.scale(SIPE, Weight); + R.scale(Warn, Weight); } -void InstrProfRecord::scale(uint64_t Weight) { +void InstrProfRecord::scale(function_ref Warn, + uint64_t Weight) { for (auto &Count : this->Counts) { bool Overflowed; Count = SaturatingMultiply(Count, Weight, &Overflowed); if (Overflowed) - SIPE.addError(instrprof_error::counter_overflow); + Warn(instrprof_error::counter_overflow); } for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) - scaleValueProfData(Kind, Weight); + scaleValueProfData(Warn, Kind, Weight); } // Map indirect call target name hash to name string. Index: lib/ProfileData/InstrProfWriter.cpp =================================================================== --- lib/ProfileData/InstrProfWriter.cpp +++ lib/ProfileData/InstrProfWriter.cpp @@ -176,14 +176,16 @@ this->Sparse = Sparse; } -Error InstrProfWriter::addRecord(NamedInstrProfRecord &&I, uint64_t Weight) { +void InstrProfWriter::addRecord(function_ref Warn, + NamedInstrProfRecord &&I, uint64_t Weight) { auto Name = I.Name; auto Hash = I.Hash; - return addRecord(Name, Hash, std::move(I), Weight); + addRecord(Warn, Name, Hash, std::move(I), Weight); } -Error InstrProfWriter::addRecord(StringRef Name, uint64_t Hash, - InstrProfRecord &&I, uint64_t Weight) { +void InstrProfWriter::addRecord(function_ref Warn, StringRef Name, + uint64_t Hash, InstrProfRecord &&I, + uint64_t Weight) { auto &ProfileDataMap = FunctionData[Name]; bool NewFunc; @@ -192,27 +194,28 @@ ProfileDataMap.insert(std::make_pair(Hash, InstrProfRecord())); InstrProfRecord &Dest = Where->second; + auto MapWarn = [&](instrprof_error E) { + Warn(make_error(E)); + }; + if (NewFunc) { // We've never seen a function with this name and hash, add it. Dest = std::move(I); if (Weight > 1) - Dest.scale(Weight); + Dest.scale(MapWarn, Weight); } else { // We're updating a function we've seen before. - Dest.merge(I, Weight); + Dest.merge(MapWarn, I, Weight); } Dest.sortValueData(); - - return Dest.takeError(); } -Error InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW) { +void InstrProfWriter::mergeRecordsFromWriter(function_ref Warn, + InstrProfWriter &&IPW) { for (auto &I : IPW.FunctionData) for (auto &Func : I.getValue()) - if (Error E = addRecord(I.getKey(), Func.first, std::move(Func.second))) - return E; - return Error::success(); + addRecord(Warn, I.getKey(), Func.first, std::move(Func.second)); } bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) { Index: tools/llvm-profdata/llvm-profdata.cpp =================================================================== --- tools/llvm-profdata/llvm-profdata.cpp +++ tools/llvm-profdata/llvm-profdata.cpp @@ -159,14 +159,22 @@ for (auto &I : *Reader) { const StringRef FuncName = I.Name; - if (Error E = WC->Writer.addRecord(std::move(I), Input.Weight)) { - // Only show hint the first time an error occurs. - instrprof_error IPE = InstrProfError::take(std::move(E)); - std::unique_lock ErrGuard{WC->ErrLock}; - bool firstTime = WC->WriterErrorCodes.insert(IPE).second; - handleMergeWriterError(make_error(IPE), Input.Filename, - FuncName, firstTime); - } + bool Reported = false; + WC->Writer.addRecord( + [&](Error E) { + if (Reported) { + consumeError(std::move(E)); + return; + } + Reported = true; + // Only show hint the first time an error occurs. + instrprof_error IPE = InstrProfError::take(std::move(E)); + std::unique_lock ErrGuard{WC->ErrLock}; + bool firstTime = WC->WriterErrorCodes.insert(IPE).second; + handleMergeWriterError(make_error(IPE), + Input.Filename, FuncName, firstTime); + }, + std::move(I), Input.Weight); } if (Reader->hasError()) WC->Err = Reader->getError(); @@ -174,8 +182,17 @@ /// Merge the \p Src writer context into \p Dst. static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) { - if (Error E = Dst->Writer.mergeRecordsFromWriter(std::move(Src->Writer))) - Dst->Err = std::move(E); + bool Reported = false; + Dst->Writer.mergeRecordsFromWriter( + [&](Error E) { + if (Reported) { + consumeError(std::move(E)); + return; + } + Reported = true; + Dst->Err = std::move(E); + }, + std::move(Src->Writer)); } static void mergeInstrProfile(const WeightedFileVector &Inputs, Index: unittests/ProfileData/CoverageMappingTest.cpp =================================================================== --- unittests/ProfileData/CoverageMappingTest.cpp +++ unittests/ProfileData/CoverageMappingTest.cpp @@ -303,9 +303,10 @@ } } +static const auto Err = [](Error E) { FAIL(); }; + TEST_P(CoverageMappingTest, load_coverage_for_more_than_two_files) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {0}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {0}}); const char *FileNames[] = {"bar", "baz", "foo"}; static const unsigned N = array_lengthof(FileNames); @@ -326,17 +327,15 @@ } TEST_P(CoverageMappingTest, load_coverage_with_bogus_function_name) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"", 0x1234, {10}}), Succeeded()); + ProfileWriter.addRecord(Err, {"", 0x1234, {10}}); startFunction("", 0x1234); addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5); EXPECT_TRUE(ErrorEquals(coveragemap_error::malformed, loadCoverageMapping())); } TEST_P(CoverageMappingTest, load_coverage_for_several_functions) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func1", 0x1234, {10}}), - Succeeded()); - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func2", 0x2345, {20}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func1", 0x1234, {10}}); + ProfileWriter.addRecord(Err, {"func2", 0x2345, {20}}); startFunction("func1", 0x1234); addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5); @@ -380,8 +379,7 @@ } TEST_P(CoverageMappingTest, basic_coverage_iteration) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {30, 20, 10, 0}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); @@ -429,8 +427,7 @@ } TEST_P(CoverageMappingTest, combine_regions) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {10, 20, 30}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {10, 20, 30}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); @@ -448,8 +445,7 @@ } TEST_P(CoverageMappingTest, restore_combined_counter_after_nested_region) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {10, 20, 40}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {10, 20, 40}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); @@ -469,10 +465,8 @@ // If CodeRegions and ExpansionRegions cover the same area, // only counts of CodeRegions should be used. TEST_P(CoverageMappingTest, dont_combine_expansions) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {10, 20}}), - Succeeded()); - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {0, 0}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {10, 20}}); + ProfileWriter.addRecord(Err, {"func", 0x1234, {0, 0}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); @@ -492,8 +486,7 @@ // If an area is covered only by ExpansionRegions, they should be combinated. TEST_P(CoverageMappingTest, combine_expansions) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {2, 3, 7}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {2, 3, 7}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(1), "include1", 1, 1, 1, 10); @@ -514,8 +507,7 @@ } TEST_P(CoverageMappingTest, strip_filename_prefix) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"file1:func", 0x1234, {0}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"file1:func", 0x1234, {0}}); startFunction("file1:func", 0x1234); addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); @@ -529,8 +521,7 @@ } TEST_P(CoverageMappingTest, strip_unknown_filename_prefix) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({":func", 0x1234, {0}}), - Succeeded()); + ProfileWriter.addRecord(Err, {":func", 0x1234, {0}}); startFunction(":func", 0x1234); addCMR(Counter::getCounter(0), "", 1, 1, 9, 9); @@ -544,10 +535,8 @@ } TEST_P(CoverageMappingTest, dont_detect_false_instantiations) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"foo", 0x1234, {10}}), - Succeeded()); - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"bar", 0x2345, {20}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"foo", 0x1234, {10}}); + ProfileWriter.addRecord(Err, {"bar", 0x2345, {20}}); startFunction("foo", 0x1234); addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10); @@ -565,8 +554,7 @@ } TEST_P(CoverageMappingTest, load_coverage_for_expanded_file) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {10}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {10}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10); @@ -582,8 +570,7 @@ } TEST_P(CoverageMappingTest, skip_duplicate_function_record) { - EXPECT_THAT_ERROR(ProfileWriter.addRecord({"func", 0x1234, {1}}), - Succeeded()); + ProfileWriter.addRecord(Err, {"func", 0x1234, {1}}); startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); Index: unittests/ProfileData/InstrProfTest.cpp =================================================================== --- unittests/ProfileData/InstrProfTest.cpp +++ unittests/ProfileData/InstrProfTest.cpp @@ -64,9 +64,13 @@ ASSERT_TRUE(Reader->begin() == Reader->end()); } +static const auto Err = [](Error E) { + consumeError(std::move(E)); + FAIL(); +}; + TEST_P(MaybeSparseInstrProfTest, write_and_read_one_function) { - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2, 3, 4}}), - Succeeded()); + Writer.addRecord(Err, {"foo", 0x1234, {1, 2, 3, 4}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -83,8 +87,8 @@ } TEST_P(MaybeSparseInstrProfTest, get_instr_prof_record) { - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1235, {3, 4}}), Succeeded()); + Writer.addRecord(Err, {"foo", 0x1234, {1, 2}}); + Writer.addRecord(Err, {"foo", 0x1235, {3, 4}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -108,8 +112,8 @@ } TEST_P(MaybeSparseInstrProfTest, get_function_counts) { - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1235, {3, 4}}), Succeeded()); + Writer.addRecord(Err, {"foo", 0x1234, {1, 2}}); + Writer.addRecord(Err, {"foo", 0x1235, {3, 4}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -135,15 +139,14 @@ // Profile data is copied from general.proftext TEST_F(InstrProfTest, get_profile_summary) { - EXPECT_THAT_ERROR(Writer.addRecord({"func1", 0x1234, {97531}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"func2", 0x1234, {0, 0}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"func3", - 0x1234, - {2305843009213693952, 1152921504606846976, - 576460752303423488, 288230376151711744, - 144115188075855872, 72057594037927936}}), - Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"func4", 0x1234, {0}}), Succeeded()); + Writer.addRecord(Err, {"func1", 0x1234, {97531}}); + Writer.addRecord(Err, {"func2", 0x1234, {0, 0}}); + Writer.addRecord( + Err, {"func3", + 0x1234, + {2305843009213693952, 1152921504606846976, 576460752303423488, + 288230376151711744, 144115188075855872, 72057594037927936}}); + Writer.addRecord(Err, {"func4", 0x1234, {0}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -194,13 +197,12 @@ } TEST_F(InstrProfTest, test_writer_merge) { - EXPECT_THAT_ERROR(Writer.addRecord({"func1", 0x1234, {42}}), Succeeded()); + Writer.addRecord(Err, {"func1", 0x1234, {42}}); InstrProfWriter Writer2; - EXPECT_THAT_ERROR(Writer2.addRecord({"func2", 0x1234, {0, 0}}), Succeeded()); + Writer2.addRecord(Err, {"func2", 0x1234, {0, 0}}); - EXPECT_THAT_ERROR(Writer.mergeRecordsFromWriter(std::move(Writer2)), - Succeeded()); + Writer.mergeRecordsFromWriter(Err, std::move(Writer2)); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -239,10 +241,10 @@ InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record1)), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee1", 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee2", 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee3", 0x1235, {3, 4}}), Succeeded()); + Writer.addRecord(Err, std::move(Record1)); + Writer.addRecord(Err, {"callee1", 0x1235, {3, 4}}); + Writer.addRecord(Err, {"callee2", 0x1235, {3, 4}}); + Writer.addRecord(Err, {"callee3", 0x1235, {3, 4}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -274,7 +276,7 @@ InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}, {5000, 5}, {4000, 4}, {6000, 6}}; Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 6, nullptr); - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record)), Succeeded()); + Writer.addRecord(Err, std::move(Record)); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); Expected R = Reader->getInstrProfRecord("caller", 0x1234); @@ -379,10 +381,10 @@ InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record1), 10), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee1", 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee2", 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee3", 0x1235, {3, 4}}), Succeeded()); + Writer.addRecord(Err, std::move(Record1), 10); + Writer.addRecord(Err, {"callee1", 0x1235, {3, 4}}); + Writer.addRecord(Err, {"callee2", 0x1235, {3, 4}}); + Writer.addRecord(Err, {"callee3", 0x1235, {3, 4}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -422,10 +424,10 @@ InstrProfValueData VD3[] = {{(uint64_t)callee1, 1}}; Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr); - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record1)), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee1", 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee2", 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"callee3", 0x1235, {3, 4}}), Succeeded()); + Writer.addRecord(Err, std::move(Record1)); + Writer.addRecord(Err, {"callee1", 0x1235, {3, 4}}); + Writer.addRecord(Err, {"callee2", 0x1235, {3, 4}}); + Writer.addRecord(Err, {"callee3", 0x1235, {3, 4}}); // Set big endian output. Writer.setValueProfDataEndianness(support::big); @@ -501,15 +503,15 @@ {uint64_t(callee3), 3}}; Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr); - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record11)), Succeeded()); + Writer.addRecord(Err, std::move(Record11)); // Merge profile data. - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record12)), Succeeded()); + Writer.addRecord(Err, std::move(Record12)); - EXPECT_THAT_ERROR(Writer.addRecord({callee1, 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({callee2, 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({callee3, 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({callee3, 0x1235, {3, 4}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({callee4, 0x1235, {3, 5}}), Succeeded()); + Writer.addRecord(Err, {callee1, 0x1235, {3, 4}}); + Writer.addRecord(Err, {callee2, 0x1235, {3, 4}}); + Writer.addRecord(Err, {callee3, 0x1235, {3, 4}}); + Writer.addRecord(Err, {callee3, 0x1235, {3, 4}}); + Writer.addRecord(Err, {callee4, 0x1235, {3, 5}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -564,35 +566,37 @@ const uint64_t Max = std::numeric_limits::max(); - auto Result1 = Writer.addRecord({"foo", 0x1234, {1}}); - ASSERT_EQ(InstrProfError::take(std::move(Result1)), - instrprof_error::success); + instrprof_error Result; + auto Err = [&](Error E) { Result = InstrProfError::take(std::move(E)); }; + Result = instrprof_error::success; + Writer.addRecord(Err, {"foo", 0x1234, {1}}); + ASSERT_EQ(Result, instrprof_error::success); // Verify counter overflow. - auto Result2 = Writer.addRecord({"foo", 0x1234, {Max}}); - ASSERT_EQ(InstrProfError::take(std::move(Result2)), - instrprof_error::counter_overflow); + Result = instrprof_error::success; + Writer.addRecord(Err, {"foo", 0x1234, {Max}}); + ASSERT_EQ(Result, instrprof_error::counter_overflow); - auto Result3 = Writer.addRecord({bar, 0x9012, {8}}); - ASSERT_EQ(InstrProfError::take(std::move(Result3)), - instrprof_error::success); + Result = instrprof_error::success; + Writer.addRecord(Err, {bar, 0x9012, {8}}); + ASSERT_EQ(Result, instrprof_error::success); NamedInstrProfRecord Record4("baz", 0x5678, {3, 4}); Record4.reserveSites(IPVK_IndirectCallTarget, 1); InstrProfValueData VD4[] = {{uint64_t(bar), 1}}; Record4.addValueData(IPVK_IndirectCallTarget, 0, VD4, 1, nullptr); - auto Result4 = Writer.addRecord(std::move(Record4)); - ASSERT_EQ(InstrProfError::take(std::move(Result4)), - instrprof_error::success); + Result = instrprof_error::success; + Writer.addRecord(Err, std::move(Record4)); + ASSERT_EQ(Result, instrprof_error::success); // Verify value data counter overflow. NamedInstrProfRecord Record5("baz", 0x5678, {5, 6}); Record5.reserveSites(IPVK_IndirectCallTarget, 1); InstrProfValueData VD5[] = {{uint64_t(bar), Max}}; Record5.addValueData(IPVK_IndirectCallTarget, 0, VD5, 1, nullptr); - auto Result5 = Writer.addRecord(std::move(Record5)); - ASSERT_EQ(InstrProfError::take(std::move(Result5)), - instrprof_error::counter_overflow); + Result = instrprof_error::success; + Writer.addRecord(Err, std::move(Record5)); + ASSERT_EQ(Result, instrprof_error::counter_overflow); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -643,9 +647,9 @@ Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr); Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr); - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record11)), Succeeded()); + Writer.addRecord(Err, std::move(Record11)); // Merge profile data. - EXPECT_THAT_ERROR(Writer.addRecord(std::move(Record12)), Succeeded()); + Writer.addRecord(Err, std::move(Record12)); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -790,11 +794,9 @@ } TEST_P(MaybeSparseInstrProfTest, get_max_function_count) { - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1ULL << 31, 2}}), - Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"bar", 0, {1ULL << 63}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"baz", 0x5678, {0, 0, 0, 0}}), - Succeeded()); + Writer.addRecord(Err, {"foo", 0x1234, {1ULL << 31, 2}}); + Writer.addRecord(Err, {"bar", 0, {1ULL << 63}}); + Writer.addRecord(Err, {"baz", 0x5678, {0, 0, 0, 0}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -802,8 +804,8 @@ } TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) { - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {1, 2}}, 3), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1235, {3, 4}}, 5), Succeeded()); + Writer.addRecord(Err, {"foo", 0x1234, {1, 2}}, 3); + Writer.addRecord(Err, {"foo", 0x1235, {3, 4}}, 5); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile)); @@ -991,11 +993,12 @@ } TEST_F(SparseInstrProfTest, preserve_no_records) { - EXPECT_THAT_ERROR(Writer.addRecord({"foo", 0x1234, {0}}), Succeeded()); - EXPECT_THAT_ERROR(Writer.addRecord({"bar", 0x4321, {0, 0}}), Succeeded()); + Writer.addRecord(Err, {"foo", 0x1234, {0}}); + Writer.addRecord(Err, {"bar", 0x4321, {0, 0}}); // FIXME: I'm guessing this data should be different, but the original author // should check/update this test so it doesn't produce errors. - consumeError(Writer.addRecord({"bar", 0x4321, {0, 0, 0}})); + Writer.addRecord([](Error E) { consumeError(std::move(E)); }, + {"bar", 0x4321, {0, 0, 0}}); auto Profile = Writer.writeBuffer(); readProfile(std::move(Profile));