Use LineLocation instead of CallsiteLocation to index callsite profile.
Summary: With discriminator, LineLocation can uniquely identify a callsite without the need to specifying callee name. Remove Callee function name from the key, and put it in the value (FunctionSamples). Reviewers: davidxl, dnovillo Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D17827 llvm-svn: 262634
This commit is contained in:
parent
022afe2538
commit
57d1dda558
|
@ -100,23 +100,6 @@ struct LineLocation {
|
||||||
|
|
||||||
raw_ostream &operator<<(raw_ostream &OS, const LineLocation &Loc);
|
raw_ostream &operator<<(raw_ostream &OS, const LineLocation &Loc);
|
||||||
|
|
||||||
/// Represents the relative location of a callsite.
|
|
||||||
///
|
|
||||||
/// Callsite locations are specified by the line offset from the
|
|
||||||
/// beginning of the function (marked by the line where the function
|
|
||||||
/// head is), the discriminator value within that line, and the callee
|
|
||||||
/// function name.
|
|
||||||
struct CallsiteLocation : public LineLocation {
|
|
||||||
CallsiteLocation(uint32_t L, uint32_t D, StringRef N)
|
|
||||||
: LineLocation(L, D), CalleeName(N) {}
|
|
||||||
void print(raw_ostream &OS) const;
|
|
||||||
void dump() const;
|
|
||||||
|
|
||||||
StringRef CalleeName;
|
|
||||||
};
|
|
||||||
|
|
||||||
raw_ostream &operator<<(raw_ostream &OS, const CallsiteLocation &Loc);
|
|
||||||
|
|
||||||
/// Representation of a single sample record.
|
/// Representation of a single sample record.
|
||||||
///
|
///
|
||||||
/// A sample record is represented by a positive integer value, which
|
/// A sample record is represented by a positive integer value, which
|
||||||
|
@ -188,7 +171,7 @@ raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample);
|
||||||
|
|
||||||
typedef std::map<LineLocation, SampleRecord> BodySampleMap;
|
typedef std::map<LineLocation, SampleRecord> BodySampleMap;
|
||||||
class FunctionSamples;
|
class FunctionSamples;
|
||||||
typedef std::map<CallsiteLocation, FunctionSamples> CallsiteSampleMap;
|
typedef std::map<LineLocation, FunctionSamples> CallsiteSampleMap;
|
||||||
|
|
||||||
/// Representation of the samples collected for a function.
|
/// Representation of the samples collected for a function.
|
||||||
///
|
///
|
||||||
|
@ -197,7 +180,7 @@ typedef std::map<CallsiteLocation, FunctionSamples> CallsiteSampleMap;
|
||||||
/// within the body of the function.
|
/// within the body of the function.
|
||||||
class FunctionSamples {
|
class FunctionSamples {
|
||||||
public:
|
public:
|
||||||
FunctionSamples() : TotalSamples(0), TotalHeadSamples(0) {}
|
FunctionSamples() : Name(), TotalSamples(0), TotalHeadSamples(0) {}
|
||||||
void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
|
void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
|
||||||
void dump() const;
|
void dump() const;
|
||||||
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight = 1) {
|
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight = 1) {
|
||||||
|
@ -240,13 +223,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the function samples at the given callsite location.
|
/// Return the function samples at the given callsite location.
|
||||||
FunctionSamples &functionSamplesAt(const CallsiteLocation &Loc) {
|
FunctionSamples &functionSamplesAt(const LineLocation &Loc) {
|
||||||
return CallsiteSamples[Loc];
|
return CallsiteSamples[Loc];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a pointer to function samples at the given callsite location.
|
/// Return a pointer to function samples at the given callsite location.
|
||||||
const FunctionSamples *
|
const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc) const {
|
||||||
findFunctionSamplesAt(const CallsiteLocation &Loc) const {
|
|
||||||
auto iter = CallsiteSamples.find(Loc);
|
auto iter = CallsiteSamples.find(Loc);
|
||||||
if (iter == CallsiteSamples.end()) {
|
if (iter == CallsiteSamples.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -276,6 +258,7 @@ public:
|
||||||
/// Optionally scale samples by \p Weight.
|
/// Optionally scale samples by \p Weight.
|
||||||
sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight = 1) {
|
sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight = 1) {
|
||||||
sampleprof_error Result = sampleprof_error::success;
|
sampleprof_error Result = sampleprof_error::success;
|
||||||
|
Name = Other.getName();
|
||||||
MergeResult(Result, addTotalSamples(Other.getTotalSamples(), Weight));
|
MergeResult(Result, addTotalSamples(Other.getTotalSamples(), Weight));
|
||||||
MergeResult(Result, addHeadSamples(Other.getHeadSamples(), Weight));
|
MergeResult(Result, addHeadSamples(Other.getHeadSamples(), Weight));
|
||||||
for (const auto &I : Other.getBodySamples()) {
|
for (const auto &I : Other.getBodySamples()) {
|
||||||
|
@ -284,14 +267,23 @@ public:
|
||||||
MergeResult(Result, BodySamples[Loc].merge(Rec, Weight));
|
MergeResult(Result, BodySamples[Loc].merge(Rec, Weight));
|
||||||
}
|
}
|
||||||
for (const auto &I : Other.getCallsiteSamples()) {
|
for (const auto &I : Other.getCallsiteSamples()) {
|
||||||
const CallsiteLocation &Loc = I.first;
|
const LineLocation &Loc = I.first;
|
||||||
const FunctionSamples &Rec = I.second;
|
const FunctionSamples &Rec = I.second;
|
||||||
MergeResult(Result, functionSamplesAt(Loc).merge(Rec, Weight));
|
MergeResult(Result, functionSamplesAt(Loc).merge(Rec, Weight));
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the name of the function.
|
||||||
|
void setName(StringRef FunctionName) { Name = FunctionName; }
|
||||||
|
|
||||||
|
/// Return the function name.
|
||||||
|
const StringRef &getName() const { return Name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Mangled name of the function.
|
||||||
|
StringRef Name;
|
||||||
|
|
||||||
/// Total number of samples collected inside this function.
|
/// Total number of samples collected inside this function.
|
||||||
///
|
///
|
||||||
/// Samples are cumulative, they include all the samples collected
|
/// Samples are cumulative, they include all the samples collected
|
||||||
|
|
|
@ -32,10 +32,10 @@ class SampleProfileWriter {
|
||||||
public:
|
public:
|
||||||
virtual ~SampleProfileWriter() {}
|
virtual ~SampleProfileWriter() {}
|
||||||
|
|
||||||
/// Write sample profiles in \p S for function \p FName.
|
/// Write sample profiles in \p S.
|
||||||
///
|
///
|
||||||
/// \returns status code of the file update operation.
|
/// \returns status code of the file update operation.
|
||||||
virtual std::error_code write(StringRef FName, const FunctionSamples &S) = 0;
|
virtual std::error_code write(const FunctionSamples &S) = 0;
|
||||||
|
|
||||||
/// Write all the sample profiles in the given map of samples.
|
/// Write all the sample profiles in the given map of samples.
|
||||||
///
|
///
|
||||||
|
@ -44,9 +44,8 @@ public:
|
||||||
if (std::error_code EC = writeHeader(ProfileMap))
|
if (std::error_code EC = writeHeader(ProfileMap))
|
||||||
return EC;
|
return EC;
|
||||||
for (const auto &I : ProfileMap) {
|
for (const auto &I : ProfileMap) {
|
||||||
StringRef FName = I.first();
|
|
||||||
const FunctionSamples &Profile = I.second;
|
const FunctionSamples &Profile = I.second;
|
||||||
if (std::error_code EC = write(FName, Profile))
|
if (std::error_code EC = write(Profile))
|
||||||
return EC;
|
return EC;
|
||||||
}
|
}
|
||||||
return sampleprof_error::success;
|
return sampleprof_error::success;
|
||||||
|
@ -86,7 +85,7 @@ protected:
|
||||||
/// \brief Sample-based profile writer (text format).
|
/// \brief Sample-based profile writer (text format).
|
||||||
class SampleProfileWriterText : public SampleProfileWriter {
|
class SampleProfileWriterText : public SampleProfileWriter {
|
||||||
public:
|
public:
|
||||||
std::error_code write(StringRef FName, const FunctionSamples &S) override;
|
std::error_code write(const FunctionSamples &S) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS)
|
SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS)
|
||||||
|
@ -111,7 +110,7 @@ private:
|
||||||
/// \brief Sample-based profile writer (binary format).
|
/// \brief Sample-based profile writer (binary format).
|
||||||
class SampleProfileWriterBinary : public SampleProfileWriter {
|
class SampleProfileWriterBinary : public SampleProfileWriter {
|
||||||
public:
|
public:
|
||||||
std::error_code write(StringRef F, const FunctionSamples &S) override;
|
std::error_code write(const FunctionSamples &S) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
|
SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
|
||||||
|
@ -121,7 +120,7 @@ protected:
|
||||||
writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
|
writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
|
||||||
std::error_code writeSummary();
|
std::error_code writeSummary();
|
||||||
std::error_code writeNameIdx(StringRef FName);
|
std::error_code writeNameIdx(StringRef FName);
|
||||||
std::error_code writeBody(StringRef FName, const FunctionSamples &S);
|
std::error_code writeBody(const FunctionSamples &S);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addName(StringRef FName);
|
void addName(StringRef FName);
|
||||||
|
|
|
@ -73,19 +73,6 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,
|
||||||
|
|
||||||
LLVM_DUMP_METHOD void LineLocation::dump() const { print(dbgs()); }
|
LLVM_DUMP_METHOD void LineLocation::dump() const { print(dbgs()); }
|
||||||
|
|
||||||
void CallsiteLocation::print(raw_ostream &OS) const {
|
|
||||||
LineLocation::print(OS);
|
|
||||||
OS << ": inlined callee: " << CalleeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
LLVM_DUMP_METHOD void CallsiteLocation::dump() const { print(dbgs()); }
|
|
||||||
|
|
||||||
inline raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,
|
|
||||||
const CallsiteLocation &Loc) {
|
|
||||||
Loc.print(OS);
|
|
||||||
return OS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Print the sample record to the stream \p OS indented by \p Indent.
|
/// \brief Print the sample record to the stream \p OS indented by \p Indent.
|
||||||
void SampleRecord::print(raw_ostream &OS, unsigned Indent) const {
|
void SampleRecord::print(raw_ostream &OS, unsigned Indent) const {
|
||||||
OS << NumSamples;
|
OS << NumSamples;
|
||||||
|
@ -127,11 +114,11 @@ void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {
|
||||||
OS.indent(Indent);
|
OS.indent(Indent);
|
||||||
if (CallsiteSamples.size() > 0) {
|
if (CallsiteSamples.size() > 0) {
|
||||||
OS << "Samples collected in inlined callsites {\n";
|
OS << "Samples collected in inlined callsites {\n";
|
||||||
SampleSorter<CallsiteLocation, FunctionSamples> SortedCallsiteSamples(
|
SampleSorter<LineLocation, FunctionSamples> SortedCallsiteSamples(
|
||||||
CallsiteSamples);
|
CallsiteSamples);
|
||||||
for (const auto &CS : SortedCallsiteSamples.get()) {
|
for (const auto &CS : SortedCallsiteSamples.get()) {
|
||||||
OS.indent(Indent + 2);
|
OS.indent(Indent + 2);
|
||||||
OS << CS->first << ": ";
|
OS << CS->first << ": inlined callee: " << CS->second.getName() << ": ";
|
||||||
CS->second.print(OS, Indent + 4);
|
CS->second.print(OS, Indent + 4);
|
||||||
}
|
}
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
|
|
|
@ -69,11 +69,8 @@ static bool ParseHead(const StringRef &Input, StringRef &FName,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \brief Returns true if line offset \p L is legal (only has 16 bits).
|
/// \brief Returns true if line offset \p L is legal (only has 16 bits).
|
||||||
static bool isOffsetLegal(unsigned L) {
|
static bool isOffsetLegal(unsigned L) { return (L & 0xffff) == L; }
|
||||||
return (L & 0xffff) == L;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Parse \p Input as line sample.
|
/// \brief Parse \p Input as line sample.
|
||||||
///
|
///
|
||||||
|
@ -181,6 +178,7 @@ std::error_code SampleProfileReaderText::read() {
|
||||||
}
|
}
|
||||||
Profiles[FName] = FunctionSamples();
|
Profiles[FName] = FunctionSamples();
|
||||||
FunctionSamples &FProfile = Profiles[FName];
|
FunctionSamples &FProfile = Profiles[FName];
|
||||||
|
FProfile.setName(FName);
|
||||||
MergeResult(Result, FProfile.addTotalSamples(NumSamples));
|
MergeResult(Result, FProfile.addTotalSamples(NumSamples));
|
||||||
MergeResult(Result, FProfile.addHeadSamples(NumHeadSamples));
|
MergeResult(Result, FProfile.addHeadSamples(NumHeadSamples));
|
||||||
InlineStack.clear();
|
InlineStack.clear();
|
||||||
|
@ -203,7 +201,8 @@ std::error_code SampleProfileReaderText::read() {
|
||||||
InlineStack.pop_back();
|
InlineStack.pop_back();
|
||||||
}
|
}
|
||||||
FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt(
|
FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt(
|
||||||
CallsiteLocation(LineOffset, Discriminator, FName));
|
LineLocation(LineOffset, Discriminator));
|
||||||
|
FSamples.setName(FName);
|
||||||
MergeResult(Result, FSamples.addTotalSamples(NumSamples));
|
MergeResult(Result, FSamples.addTotalSamples(NumSamples));
|
||||||
InlineStack.push_back(&FSamples);
|
InlineStack.push_back(&FSamples);
|
||||||
} else {
|
} else {
|
||||||
|
@ -354,8 +353,9 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
|
||||||
if (std::error_code EC = FName.getError())
|
if (std::error_code EC = FName.getError())
|
||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
FunctionSamples &CalleeProfile = FProfile.functionSamplesAt(
|
FunctionSamples &CalleeProfile =
|
||||||
CallsiteLocation(*LineOffset, *Discriminator, *FName));
|
FProfile.functionSamplesAt(LineLocation(*LineOffset, *Discriminator));
|
||||||
|
CalleeProfile.setName(*FName);
|
||||||
if (std::error_code EC = readProfile(CalleeProfile))
|
if (std::error_code EC = readProfile(CalleeProfile))
|
||||||
return EC;
|
return EC;
|
||||||
}
|
}
|
||||||
|
@ -375,6 +375,7 @@ std::error_code SampleProfileReaderBinary::read() {
|
||||||
|
|
||||||
Profiles[*FName] = FunctionSamples();
|
Profiles[*FName] = FunctionSamples();
|
||||||
FunctionSamples &FProfile = Profiles[*FName];
|
FunctionSamples &FProfile = Profiles[*FName];
|
||||||
|
FProfile.setName(*FName);
|
||||||
|
|
||||||
FProfile.addHeadSamples(*NumHeadSamples);
|
FProfile.addHeadSamples(*NumHeadSamples);
|
||||||
|
|
||||||
|
@ -625,8 +626,9 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile(
|
||||||
uint32_t LineOffset = Offset >> 16;
|
uint32_t LineOffset = Offset >> 16;
|
||||||
uint32_t Discriminator = Offset & 0xffff;
|
uint32_t Discriminator = Offset & 0xffff;
|
||||||
FProfile = &CallerProfile->functionSamplesAt(
|
FProfile = &CallerProfile->functionSamplesAt(
|
||||||
CallsiteLocation(LineOffset, Discriminator, Name));
|
LineLocation(LineOffset, Discriminator));
|
||||||
}
|
}
|
||||||
|
FProfile->setName(Name);
|
||||||
|
|
||||||
for (uint32_t I = 0; I < NumPosCounts; ++I) {
|
for (uint32_t I = 0; I < NumPosCounts; ++I) {
|
||||||
uint32_t Offset;
|
uint32_t Offset;
|
||||||
|
|
|
@ -37,11 +37,9 @@ using namespace llvm;
|
||||||
///
|
///
|
||||||
/// The format used here is more structured and deliberate because
|
/// The format used here is more structured and deliberate because
|
||||||
/// it needs to be parsed by the SampleProfileReaderText class.
|
/// it needs to be parsed by the SampleProfileReaderText class.
|
||||||
std::error_code SampleProfileWriterText::write(StringRef FName,
|
std::error_code SampleProfileWriterText::write(const FunctionSamples &S) {
|
||||||
const FunctionSamples &S) {
|
|
||||||
auto &OS = *OutputStream;
|
auto &OS = *OutputStream;
|
||||||
|
OS << S.getName() << ":" << S.getTotalSamples();
|
||||||
OS << FName << ":" << S.getTotalSamples();
|
|
||||||
if (Indent == 0)
|
if (Indent == 0)
|
||||||
OS << ":" << S.getHeadSamples();
|
OS << ":" << S.getHeadSamples();
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
|
@ -63,18 +61,18 @@ std::error_code SampleProfileWriterText::write(StringRef FName,
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleSorter<CallsiteLocation, FunctionSamples> SortedCallsiteSamples(
|
SampleSorter<LineLocation, FunctionSamples> SortedCallsiteSamples(
|
||||||
S.getCallsiteSamples());
|
S.getCallsiteSamples());
|
||||||
Indent += 1;
|
Indent += 1;
|
||||||
for (const auto &I : SortedCallsiteSamples.get()) {
|
for (const auto &I : SortedCallsiteSamples.get()) {
|
||||||
CallsiteLocation Loc = I->first;
|
LineLocation Loc = I->first;
|
||||||
const FunctionSamples &CalleeSamples = I->second;
|
const FunctionSamples &CalleeSamples = I->second;
|
||||||
OS.indent(Indent);
|
OS.indent(Indent);
|
||||||
if (Loc.Discriminator == 0)
|
if (Loc.Discriminator == 0)
|
||||||
OS << Loc.LineOffset << ": ";
|
OS << Loc.LineOffset << ": ";
|
||||||
else
|
else
|
||||||
OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
|
OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
|
||||||
if (std::error_code EC = write(Loc.CalleeName, CalleeSamples))
|
if (std::error_code EC = write(CalleeSamples))
|
||||||
return EC;
|
return EC;
|
||||||
}
|
}
|
||||||
Indent -= 1;
|
Indent -= 1;
|
||||||
|
@ -105,9 +103,8 @@ void SampleProfileWriterBinary::addNames(const FunctionSamples &S) {
|
||||||
|
|
||||||
// Recursively add all the names for inlined callsites.
|
// Recursively add all the names for inlined callsites.
|
||||||
for (const auto &J : S.getCallsiteSamples()) {
|
for (const auto &J : S.getCallsiteSamples()) {
|
||||||
CallsiteLocation Loc = J.first;
|
|
||||||
const FunctionSamples &CalleeSamples = J.second;
|
const FunctionSamples &CalleeSamples = J.second;
|
||||||
addName(Loc.CalleeName);
|
addName(CalleeSamples.getName());
|
||||||
addNames(CalleeSamples);
|
addNames(CalleeSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,11 +152,10 @@ std::error_code SampleProfileWriterBinary::writeSummary() {
|
||||||
}
|
}
|
||||||
return sampleprof_error::success;
|
return sampleprof_error::success;
|
||||||
}
|
}
|
||||||
std::error_code SampleProfileWriterBinary::writeBody(StringRef FName,
|
std::error_code SampleProfileWriterBinary::writeBody(const FunctionSamples &S) {
|
||||||
const FunctionSamples &S) {
|
|
||||||
auto &OS = *OutputStream;
|
auto &OS = *OutputStream;
|
||||||
|
|
||||||
if (std::error_code EC = writeNameIdx(FName))
|
if (std::error_code EC = writeNameIdx(S.getName()))
|
||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
encodeULEB128(S.getTotalSamples(), OS);
|
encodeULEB128(S.getTotalSamples(), OS);
|
||||||
|
@ -185,11 +181,11 @@ std::error_code SampleProfileWriterBinary::writeBody(StringRef FName,
|
||||||
// Recursively emit all the callsite samples.
|
// Recursively emit all the callsite samples.
|
||||||
encodeULEB128(S.getCallsiteSamples().size(), OS);
|
encodeULEB128(S.getCallsiteSamples().size(), OS);
|
||||||
for (const auto &J : S.getCallsiteSamples()) {
|
for (const auto &J : S.getCallsiteSamples()) {
|
||||||
CallsiteLocation Loc = J.first;
|
LineLocation Loc = J.first;
|
||||||
const FunctionSamples &CalleeSamples = J.second;
|
const FunctionSamples &CalleeSamples = J.second;
|
||||||
encodeULEB128(Loc.LineOffset, OS);
|
encodeULEB128(Loc.LineOffset, OS);
|
||||||
encodeULEB128(Loc.Discriminator, OS);
|
encodeULEB128(Loc.Discriminator, OS);
|
||||||
if (std::error_code EC = writeBody(Loc.CalleeName, CalleeSamples))
|
if (std::error_code EC = writeBody(CalleeSamples))
|
||||||
return EC;
|
return EC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,10 +195,9 @@ std::error_code SampleProfileWriterBinary::writeBody(StringRef FName,
|
||||||
/// \brief Write samples of a top-level function to a binary file.
|
/// \brief Write samples of a top-level function to a binary file.
|
||||||
///
|
///
|
||||||
/// \returns true if the samples were written successfully, false otherwise.
|
/// \returns true if the samples were written successfully, false otherwise.
|
||||||
std::error_code SampleProfileWriterBinary::write(StringRef FName,
|
std::error_code SampleProfileWriterBinary::write(const FunctionSamples &S) {
|
||||||
const FunctionSamples &S) {
|
|
||||||
encodeULEB128(S.getHeadSamples(), *OutputStream);
|
encodeULEB128(S.getHeadSamples(), *OutputStream);
|
||||||
return writeBody(FName, S);
|
return writeBody(S);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a sample profile file writer based on the specified format.
|
/// \brief Create a sample profile file writer based on the specified format.
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Transforms/IPO.h"
|
#include "llvm/Transforms/IPO.h"
|
||||||
#include "llvm/Transforms/Utils/Cloning.h"
|
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
|
#include "llvm/Transforms/Utils/Cloning.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -285,7 +285,6 @@ bool callsiteIsHot(const FunctionSamples *CallerFS,
|
||||||
(double)CallsiteTotalSamples / (double)ParentTotalSamples * 100.0;
|
(double)CallsiteTotalSamples / (double)ParentTotalSamples * 100.0;
|
||||||
return PercentSamples >= SampleProfileHotThreshold;
|
return PercentSamples >= SampleProfileHotThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark as used the sample record for the given function samples at
|
/// Mark as used the sample record for the given function samples at
|
||||||
|
@ -549,19 +548,12 @@ SampleProfileLoader::findCalleeFunctionSamples(const CallInst &Inst) const {
|
||||||
if (!SP)
|
if (!SP)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Function *CalleeFunc = Inst.getCalledFunction();
|
|
||||||
if (!CalleeFunc) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef CalleeName = CalleeFunc->getName();
|
|
||||||
const FunctionSamples *FS = findFunctionSamples(Inst);
|
const FunctionSamples *FS = findFunctionSamples(Inst);
|
||||||
if (FS == nullptr)
|
if (FS == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return FS->findFunctionSamplesAt(
|
return FS->findFunctionSamplesAt(LineLocation(
|
||||||
CallsiteLocation(getOffset(DIL->getLine(), SP->getLine()),
|
getOffset(DIL->getLine(), SP->getLine()), DIL->getDiscriminator()));
|
||||||
DIL->getDiscriminator(), CalleeName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Get the FunctionSamples for an instruction.
|
/// \brief Get the FunctionSamples for an instruction.
|
||||||
|
@ -575,7 +567,7 @@ SampleProfileLoader::findCalleeFunctionSamples(const CallInst &Inst) const {
|
||||||
/// \returns the FunctionSamples pointer to the inlined instance.
|
/// \returns the FunctionSamples pointer to the inlined instance.
|
||||||
const FunctionSamples *
|
const FunctionSamples *
|
||||||
SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
|
SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
|
||||||
SmallVector<CallsiteLocation, 10> S;
|
SmallVector<LineLocation, 10> S;
|
||||||
const DILocation *DIL = Inst.getDebugLoc();
|
const DILocation *DIL = Inst.getDebugLoc();
|
||||||
if (!DIL) {
|
if (!DIL) {
|
||||||
return Samples;
|
return Samples;
|
||||||
|
@ -587,8 +579,8 @@ SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
|
||||||
if (!SP)
|
if (!SP)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!CalleeName.empty()) {
|
if (!CalleeName.empty()) {
|
||||||
S.push_back(CallsiteLocation(getOffset(DIL->getLine(), SP->getLine()),
|
S.push_back(LineLocation(getOffset(DIL->getLine(), SP->getLine()),
|
||||||
DIL->getDiscriminator(), CalleeName));
|
DIL->getDiscriminator()));
|
||||||
}
|
}
|
||||||
CalleeName = SP->getLinkageName();
|
CalleeName = SP->getLinkageName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct SampleProfTest : ::testing::Test {
|
||||||
|
|
||||||
StringRef FooName("_Z3fooi");
|
StringRef FooName("_Z3fooi");
|
||||||
FunctionSamples FooSamples;
|
FunctionSamples FooSamples;
|
||||||
|
FooSamples.setName(FooName);
|
||||||
FooSamples.addTotalSamples(7711);
|
FooSamples.addTotalSamples(7711);
|
||||||
FooSamples.addHeadSamples(610);
|
FooSamples.addHeadSamples(610);
|
||||||
FooSamples.addBodySamples(1, 0, 610);
|
FooSamples.addBodySamples(1, 0, 610);
|
||||||
|
@ -63,6 +64,7 @@ struct SampleProfTest : ::testing::Test {
|
||||||
|
|
||||||
StringRef BarName("_Z3bari");
|
StringRef BarName("_Z3bari");
|
||||||
FunctionSamples BarSamples;
|
FunctionSamples BarSamples;
|
||||||
|
BarSamples.setName(BarName);
|
||||||
BarSamples.addTotalSamples(20301);
|
BarSamples.addTotalSamples(20301);
|
||||||
BarSamples.addHeadSamples(1437);
|
BarSamples.addHeadSamples(1437);
|
||||||
BarSamples.addBodySamples(1, 0, 1437);
|
BarSamples.addBodySamples(1, 0, 1437);
|
||||||
|
|
Loading…
Reference in New Issue