|
@@ -264,8 +264,9 @@ namespace sampleprof {
|
|
/// compact and I/O efficient. They can both be used interchangeably.
|
|
/// compact and I/O efficient. They can both be used interchangeably.
|
|
class SampleProfileReader {
|
|
class SampleProfileReader {
|
|
public:
|
|
public:
|
|
- SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
|
|
- : Profiles(0), Ctx(C), Buffer(std::move(B)) {}
|
|
|
|
|
|
+ SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
|
|
|
|
+ SampleProfileFormat Format = SPF_None)
|
|
|
|
+ : Profiles(0), Ctx(C), Buffer(std::move(B)), Format(Format) {}
|
|
|
|
|
|
virtual ~SampleProfileReader() = default;
|
|
virtual ~SampleProfileReader() = default;
|
|
|
|
|
|
@@ -286,8 +287,11 @@ public:
|
|
// The function name may have been updated by adding suffix. In sample
|
|
// The function name may have been updated by adding suffix. In sample
|
|
// profile, the function names are all stripped, so we need to strip
|
|
// profile, the function names are all stripped, so we need to strip
|
|
// the function name suffix before matching with profile.
|
|
// the function name suffix before matching with profile.
|
|
- if (Profiles.count(F.getName().split('.').first))
|
|
|
|
- return &Profiles[(F.getName().split('.').first)];
|
|
|
|
|
|
+ StringRef Fname = F.getName().split('.').first;
|
|
|
|
+ std::string FGUID;
|
|
|
|
+ Fname = getRepInFormat(Fname, getFormat(), FGUID);
|
|
|
|
+ if (Profiles.count(Fname))
|
|
|
|
+ return &Profiles[Fname];
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -311,6 +315,9 @@ public:
|
|
/// Return the profile summary.
|
|
/// Return the profile summary.
|
|
ProfileSummary &getSummary() { return *(Summary.get()); }
|
|
ProfileSummary &getSummary() { return *(Summary.get()); }
|
|
|
|
|
|
|
|
+ /// \brief Return the profile format.
|
|
|
|
+ SampleProfileFormat getFormat() { return Format; }
|
|
|
|
+
|
|
protected:
|
|
protected:
|
|
/// Map every function to its associated profile.
|
|
/// Map every function to its associated profile.
|
|
///
|
|
///
|
|
@@ -330,12 +337,15 @@ protected:
|
|
|
|
|
|
/// Compute summary for this profile.
|
|
/// Compute summary for this profile.
|
|
void computeSummary();
|
|
void computeSummary();
|
|
|
|
+
|
|
|
|
+ /// \brief The format of sample.
|
|
|
|
+ SampleProfileFormat Format = SPF_None;
|
|
};
|
|
};
|
|
|
|
|
|
class SampleProfileReaderText : public SampleProfileReader {
|
|
class SampleProfileReaderText : public SampleProfileReader {
|
|
public:
|
|
public:
|
|
SampleProfileReaderText(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
SampleProfileReaderText(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
- : SampleProfileReader(std::move(B), C) {}
|
|
|
|
|
|
+ : SampleProfileReader(std::move(B), C, SPF_Text) {}
|
|
|
|
|
|
/// Read and validate the file header.
|
|
/// Read and validate the file header.
|
|
std::error_code readHeader() override { return sampleprof_error::success; }
|
|
std::error_code readHeader() override { return sampleprof_error::success; }
|
|
@@ -349,8 +359,9 @@ public:
|
|
|
|
|
|
class SampleProfileReaderBinary : public SampleProfileReader {
|
|
class SampleProfileReaderBinary : public SampleProfileReader {
|
|
public:
|
|
public:
|
|
- SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
|
|
- : SampleProfileReader(std::move(B), C) {}
|
|
|
|
|
|
+ SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
|
|
|
|
+ SampleProfileFormat Format = SPF_None)
|
|
|
|
+ : SampleProfileReader(std::move(B), C, Format) {}
|
|
|
|
|
|
/// Read and validate the file header.
|
|
/// Read and validate the file header.
|
|
std::error_code readHeader() override;
|
|
std::error_code readHeader() override;
|
|
@@ -358,9 +369,6 @@ public:
|
|
/// Read sample profiles from the associated file.
|
|
/// Read sample profiles from the associated file.
|
|
std::error_code read() override;
|
|
std::error_code read() override;
|
|
|
|
|
|
- /// Return true if \p Buffer is in the format supported by this class.
|
|
|
|
- static bool hasFormat(const MemoryBuffer &Buffer);
|
|
|
|
-
|
|
|
|
protected:
|
|
protected:
|
|
/// Read a numeric value of type T from the profile.
|
|
/// Read a numeric value of type T from the profile.
|
|
///
|
|
///
|
|
@@ -378,8 +386,8 @@ protected:
|
|
/// \returns the read value.
|
|
/// \returns the read value.
|
|
ErrorOr<StringRef> readString();
|
|
ErrorOr<StringRef> readString();
|
|
|
|
|
|
- /// Read a string indirectly via the name table.
|
|
|
|
- ErrorOr<StringRef> readStringFromTable();
|
|
|
|
|
|
+ /// Read the string index and check whether it overflows the table.
|
|
|
|
+ template <typename T> inline ErrorOr<uint32_t> readStringIndex(T &Table);
|
|
|
|
|
|
/// Return true if we've reached the end of file.
|
|
/// Return true if we've reached the end of file.
|
|
bool at_eof() const { return Data >= End; }
|
|
bool at_eof() const { return Data >= End; }
|
|
@@ -393,14 +401,53 @@ protected:
|
|
/// Points to the end of the buffer.
|
|
/// Points to the end of the buffer.
|
|
const uint8_t *End = nullptr;
|
|
const uint8_t *End = nullptr;
|
|
|
|
|
|
- /// Function name table.
|
|
|
|
- std::vector<StringRef> NameTable;
|
|
|
|
-
|
|
|
|
private:
|
|
private:
|
|
std::error_code readSummaryEntry(std::vector<ProfileSummaryEntry> &Entries);
|
|
std::error_code readSummaryEntry(std::vector<ProfileSummaryEntry> &Entries);
|
|
|
|
+ virtual std::error_code verifySPMagic(uint64_t Magic) = 0;
|
|
|
|
|
|
/// Read profile summary.
|
|
/// Read profile summary.
|
|
std::error_code readSummary();
|
|
std::error_code readSummary();
|
|
|
|
+
|
|
|
|
+ /// Read the whole name table.
|
|
|
|
+ virtual std::error_code readNameTable() = 0;
|
|
|
|
+
|
|
|
|
+ /// Read a string indirectly via the name table.
|
|
|
|
+ virtual ErrorOr<StringRef> readStringFromTable() = 0;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+class SampleProfileReaderRawBinary : public SampleProfileReaderBinary {
|
|
|
|
+private:
|
|
|
|
+ /// Function name table.
|
|
|
|
+ std::vector<StringRef> NameTable;
|
|
|
|
+ virtual std::error_code verifySPMagic(uint64_t Magic) override;
|
|
|
|
+ virtual std::error_code readNameTable() override;
|
|
|
|
+ /// Read a string indirectly via the name table.
|
|
|
|
+ virtual ErrorOr<StringRef> readStringFromTable() override;
|
|
|
|
+
|
|
|
|
+public:
|
|
|
|
+ SampleProfileReaderRawBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
|
|
+ : SampleProfileReaderBinary(std::move(B), C, SPF_Raw_Binary) {}
|
|
|
|
+
|
|
|
|
+ /// \brief Return true if \p Buffer is in the format supported by this class.
|
|
|
|
+ static bool hasFormat(const MemoryBuffer &Buffer);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+class SampleProfileReaderCompactBinary : public SampleProfileReaderBinary {
|
|
|
|
+private:
|
|
|
|
+ /// Function name table.
|
|
|
|
+ std::vector<std::string> NameTable;
|
|
|
|
+ virtual std::error_code verifySPMagic(uint64_t Magic) override;
|
|
|
|
+ virtual std::error_code readNameTable() override;
|
|
|
|
+ /// Read a string indirectly via the name table.
|
|
|
|
+ virtual ErrorOr<StringRef> readStringFromTable() override;
|
|
|
|
+
|
|
|
|
+public:
|
|
|
|
+ SampleProfileReaderCompactBinary(std::unique_ptr<MemoryBuffer> B,
|
|
|
|
+ LLVMContext &C)
|
|
|
|
+ : SampleProfileReaderBinary(std::move(B), C, SPF_Compact_Binary) {}
|
|
|
|
+
|
|
|
|
+ /// \brief Return true if \p Buffer is in the format supported by this class.
|
|
|
|
+ static bool hasFormat(const MemoryBuffer &Buffer);
|
|
};
|
|
};
|
|
|
|
|
|
using InlineCallStack = SmallVector<FunctionSamples *, 10>;
|
|
using InlineCallStack = SmallVector<FunctionSamples *, 10>;
|
|
@@ -421,7 +468,8 @@ enum HistType {
|
|
class SampleProfileReaderGCC : public SampleProfileReader {
|
|
class SampleProfileReaderGCC : public SampleProfileReader {
|
|
public:
|
|
public:
|
|
SampleProfileReaderGCC(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
SampleProfileReaderGCC(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
|
|
- : SampleProfileReader(std::move(B), C), GcovBuffer(Buffer.get()) {}
|
|
|
|
|
|
+ : SampleProfileReader(std::move(B), C, SPF_GCC),
|
|
|
|
+ GcovBuffer(Buffer.get()) {}
|
|
|
|
|
|
/// Read and validate the file header.
|
|
/// Read and validate the file header.
|
|
std::error_code readHeader() override;
|
|
std::error_code readHeader() override;
|