llvm.org GIT mirror llvm / 04af5ff
Support for remapping profile data when symbols change, for sample-based profiling. Reviewers: davidxl, tejohnson, dlj, erik.pilkington Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D51248 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344187 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Smith 1 year, 11 days ago
3 changed file(s) with 144 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
221221 #include "llvm/Support/Debug.h"
222222 #include "llvm/Support/ErrorOr.h"
223223 #include "llvm/Support/MemoryBuffer.h"
224 #include "llvm/Support/SymbolRemappingReader.h"
224225 #include
225226 #include
226227 #include
288289 // The function name may have been updated by adding suffix. In sample
289290 // profile, the function names are all stripped, so we need to strip
290291 // the function name suffix before matching with profile.
291 StringRef Fname = F.getName().split('.').first;
292 return getSamplesFor(F.getName().split('.').first);
293 }
294
295 /// Return the samples collected for function \p F.
296 virtual FunctionSamples *getSamplesFor(StringRef Fname) {
292297 std::string FGUID;
293298 Fname = getRepInFormat(Fname, getFormat(), FGUID);
294 if (Profiles.count(Fname))
295 return &Profiles[Fname];
299 auto It = Profiles.find(Fname);
300 if (It != Profiles.end())
301 return &It->second;
296302 return nullptr;
297303 }
298304
335341
336342 /// Profile summary information.
337343 std::unique_ptr Summary;
344
345 /// Take ownership of the summary of this reader.
346 static std::unique_ptr
347 takeSummary(SampleProfileReader &Reader) {
348 return std::move(Reader.Summary);
349 }
338350
339351 /// Compute summary for this profile.
340352 void computeSummary();
524536 static const uint32_t GCOVTagAFDOFunction = 0xac000000;
525537 };
526538
539 /// A profile data reader proxy that remaps the profile data from another
540 /// sample profile data reader, by applying a provided set of equivalences
541 /// between components of the symbol names in the profile.
542 class SampleProfileReaderItaniumRemapper : public SampleProfileReader {
543 public:
544 SampleProfileReaderItaniumRemapper(
545 std::unique_ptr B, LLVMContext &C,
546 std::unique_ptr Underlying)
547 : SampleProfileReader(std::move(B), C, Underlying->getFormat()) {
548 Profiles = std::move(Underlying->getProfiles());
549 Summary = takeSummary(*Underlying);
550 }
551
552 /// Create a remapped sample profile from the given remapping file and
553 /// underlying samples.
554 static ErrorOr>
555 create(const Twine &Filename, LLVMContext &C,
556 std::unique_ptr Underlying);
557
558 /// Read and validate the file header.
559 std::error_code readHeader() override { return sampleprof_error::success; }
560
561 /// Read remapping file and apply it to the sample profile.
562 std::error_code read() override;
563
564 /// Return the samples collected for function \p F.
565 FunctionSamples *getSamplesFor(StringRef FunctionName) override;
566 using SampleProfileReader::getSamplesFor;
567
568 private:
569 SymbolRemappingReader Remappings;
570 DenseMap SampleMap;
571 };
572
527573 } // end namespace sampleprof
528574
529575 } // end namespace llvm
911911 return Magic == "adcg*704";
912912 }
913913
914 std::error_code SampleProfileReaderItaniumRemapper::read() {
915 // If the underlying data is in compact format, we can't remap it because
916 // we don't know what the original function names were.
917 if (getFormat() == SPF_Compact_Binary) {
918 Ctx.diagnose(DiagnosticInfoSampleProfile(
919 Buffer->getBufferIdentifier(),
920 "Profile data remapping cannot be applied to profile data "
921 "in compact format (original mangled names are not available).",
922 DS_Warning));
923 return sampleprof_error::success;
924 }
925
926 if (Error E = Remappings.read(*Buffer)) {
927 handleAllErrors(
928 std::move(E), [&](const SymbolRemappingParseError &ParseError) {
929 reportError(ParseError.getLineNum(), ParseError.getMessage());
930 });
931 return sampleprof_error::malformed;
932 }
933
934 for (auto &Sample : getProfiles())
935 if (auto Key = Remappings.insert(Sample.first()))
936 SampleMap.insert({Key, &Sample.second});
937
938 return sampleprof_error::success;
939 }
940
941 FunctionSamples *
942 SampleProfileReaderItaniumRemapper::getSamplesFor(StringRef Fname) {
943 if (auto Key = Remappings.lookup(Fname))
944 return SampleMap.lookup(Key);
945 return SampleProfileReader::getSamplesFor(Fname);
946 }
947
914948 /// Prepare a memory buffer for the contents of \p Filename.
915949 ///
916950 /// \returns an error code indicating the status of the buffer.
941975 if (std::error_code EC = BufferOrError.getError())
942976 return EC;
943977 return create(BufferOrError.get(), C);
978 }
979
980 /// Create a sample profile remapper from the given input, to remap the
981 /// function names in the given profile data.
982 ///
983 /// \param Filename The file to open.
984 ///
985 /// \param C The LLVM context to use to emit diagnostics.
986 ///
987 /// \param Underlying The underlying profile data reader to remap.
988 ///
989 /// \returns an error code indicating the status of the created reader.
990 ErrorOr>
991 SampleProfileReaderItaniumRemapper::create(
992 const Twine &Filename, LLVMContext &C,
993 std::unique_ptr Underlying) {
994 auto BufferOrError = setupMemoryBuffer(Filename);
995 if (std::error_code EC = BufferOrError.getError())
996 return EC;
997 return llvm::make_unique(
998 std::move(BufferOrError.get()), C, std::move(Underlying));
944999 }
9451000
9461001 /// Create a sample profile reader based on the format of the input data.
5757 Reader->collectFuncsToUse(M);
5858 }
5959
60 void testRoundTrip(SampleProfileFormat Format) {
60 void testRoundTrip(SampleProfileFormat Format, bool Remap) {
6161 SmallVector ProfilePath;
6262 ASSERT_TRUE(NoError(llvm::sys::fs::createTemporaryFile("profile", "", ProfilePath)));
6363 StringRef Profile(ProfilePath.data(), ProfilePath.size());
107107 EC = Reader->read();
108108 ASSERT_TRUE(NoError(EC));
109109
110 StringMap &ReadProfiles = Reader->getProfiles();
111 ASSERT_EQ(2u, ReadProfiles.size());
112
113 std::string FooGUID;
114 StringRef FooRep = getRepInFormat(FooName, Format, FooGUID);
115 FunctionSamples &ReadFooSamples = ReadProfiles[FooRep];
116 ASSERT_EQ(7711u, ReadFooSamples.getTotalSamples());
117 ASSERT_EQ(610u, ReadFooSamples.getHeadSamples());
118
119 std::string BarGUID;
120 StringRef BarRep = getRepInFormat(BarName, Format, BarGUID);
121 FunctionSamples &ReadBarSamples = ReadProfiles[BarRep];
122 ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples());
123 ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples());
110 if (Remap) {
111 auto MemBuffer = llvm::MemoryBuffer::getMemBuffer(R"(
112 # Types 'int' and 'long' are equivalent
113 type i l
114 # Function names 'foo' and 'faux' are equivalent
115 name 3foo 4faux
116 )");
117 Reader.reset(new SampleProfileReaderItaniumRemapper(
118 std::move(MemBuffer), Context, std::move(Reader)));
119 FooName = "_Z4fauxi";
120 BarName = "_Z3barl";
121
122 EC = Reader->read();
123 ASSERT_TRUE(NoError(EC));
124 }
125
126 ASSERT_EQ(2u, Reader->getProfiles().size());
127
128 FunctionSamples *ReadFooSamples = Reader->getSamplesFor(FooName);
129 ASSERT_TRUE(ReadFooSamples != nullptr);
130 ASSERT_EQ(7711u, ReadFooSamples->getTotalSamples());
131 ASSERT_EQ(610u, ReadFooSamples->getHeadSamples());
132
133 FunctionSamples *ReadBarSamples = Reader->getSamplesFor(BarName);
134 ASSERT_TRUE(ReadBarSamples != nullptr);
135 ASSERT_EQ(20301u, ReadBarSamples->getTotalSamples());
136 ASSERT_EQ(1437u, ReadBarSamples->getHeadSamples());
124137 ErrorOr CTMap =
125 ReadBarSamples.findCallTargetMapAt(1, 0);
138 ReadBarSamples->findCallTargetMapAt(1, 0);
126139 ASSERT_FALSE(CTMap.getError());
127140
128141 std::string MconstructGUID;
183196 };
184197
185198 TEST_F(SampleProfTest, roundtrip_text_profile) {
186 testRoundTrip(SampleProfileFormat::SPF_Text);
199 testRoundTrip(SampleProfileFormat::SPF_Text, false);
187200 }
188201
189202 TEST_F(SampleProfTest, roundtrip_raw_binary_profile) {
190 testRoundTrip(SampleProfileFormat::SPF_Binary);
203 testRoundTrip(SampleProfileFormat::SPF_Binary, false);
191204 }
192205
193206 TEST_F(SampleProfTest, roundtrip_compact_binary_profile) {
194 testRoundTrip(SampleProfileFormat::SPF_Compact_Binary);
207 testRoundTrip(SampleProfileFormat::SPF_Compact_Binary, false);
208 }
209
210 TEST_F(SampleProfTest, remap_text_profile) {
211 testRoundTrip(SampleProfileFormat::SPF_Text, true);
212 }
213
214 TEST_F(SampleProfTest, remap_raw_binary_profile) {
215 testRoundTrip(SampleProfileFormat::SPF_Binary, true);
195216 }
196217
197218 TEST_F(SampleProfTest, sample_overflow_saturation) {