LineLocation(uint32_t L, uint32_t D) : LineOffset(L), Discriminator(D) {}
void print(raw_ostream &OS) const;
void dump() const;
+ bool operator<(const LineLocation &O) const {
+ return LineOffset < O.LineOffset ||
+ (LineOffset == O.LineOffset && Discriminator < O.Discriminator);
+ }
uint32_t LineOffset;
uint32_t Discriminator;
raw_ostream &operator<<(raw_ostream &OS, const FunctionSamples &FS);
+/// Sort a LocationT->SampleT map by LocationT.
+///
+/// It produces a sorted list of <LocationT, SampleT> records by ascending
+/// order of LocationT.
+template <class LocationT, class SampleT> class SampleSorter {
+public:
+ typedef detail::DenseMapPair<LocationT, SampleT> SamplesWithLoc;
+ typedef SmallVector<const SamplesWithLoc *, 20> SamplesWithLocList;
+
+ SampleSorter(const DenseMap<LocationT, SampleT> &Samples) {
+ for (const auto &I : Samples)
+ V.push_back(&I);
+ std::stable_sort(V.begin(), V.end(),
+ [](const SamplesWithLoc *A, const SamplesWithLoc *B) {
+ return A->first < B->first;
+ });
+ }
+ const SamplesWithLocList &get() const { return V; }
+
+private:
+ SamplesWithLocList V;
+};
+
} // end namespace sampleprof
} // end namespace llvm
OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size()
<< " sampled lines\n";
- for (const auto &SI : BodySamples) {
+ SampleSorter<LineLocation, SampleRecord> SortedBodySamples(BodySamples);
+ for (const auto &SI : SortedBodySamples.get()) {
OS.indent(Indent);
- OS << SI.first << ": " << SI.second;
+ OS << SI->first << ": " << SI->second;
}
- for (const auto &CS : CallsiteSamples) {
+ SampleSorter<CallsiteLocation, FunctionSamples> SortedCallsiteSamples(
+ CallsiteSamples);
+ for (const auto &CS : SortedCallsiteSamples.get()) {
OS.indent(Indent);
- OS << CS.first << ": ";
- CS.second.print(OS, Indent + 2);
+ OS << CS->first << ": ";
+ CS->second.print(OS, Indent + 2);
}
}
/// \brief Write samples to a text file.
///
/// Note: it may be tempting to implement this in terms of
-/// FunctionSamples::dump(). Please don't. The dump functionality is intended
+/// FunctionSamples::print(). Please don't. The dump functionality is intended
/// for debugging and has no specified form.
///
/// The format used here is more structured and deliberate because
OS << ":" << S.getHeadSamples();
OS << "\n";
- for (const auto &I : S.getBodySamples()) {
- LineLocation Loc = I.first;
- const SampleRecord &Sample = I.second;
+ SampleSorter<LineLocation, SampleRecord> SortedSamples(S.getBodySamples());
+ for (const auto &I : SortedSamples.get()) {
+ LineLocation Loc = I->first;
+ const SampleRecord &Sample = I->second;
OS.indent(Indent + 1);
if (Loc.Discriminator == 0)
OS << Loc.LineOffset << ": ";
OS << "\n";
}
+ SampleSorter<CallsiteLocation, FunctionSamples> SortedCallsiteSamples(
+ S.getCallsiteSamples());
Indent += 1;
- for (const auto &I : S.getCallsiteSamples()) {
- CallsiteLocation Loc = I.first;
- const FunctionSamples &CalleeSamples = I.second;
+ for (const auto &I : SortedCallsiteSamples.get()) {
+ CallsiteLocation Loc = I->first;
+ const FunctionSamples &CalleeSamples = I->second;
OS.indent(Indent);
if (Loc.Discriminator == 0)
OS << Loc.LineOffset << ": ";
SHOW1: Function: main: 364084, 0, 6 sampled lines
SHOW1: 2.3: inlined callee: _Z3fool: 243786, 0, 3 sampled lines
SHOW1: 1.3: inlined callee: _Z3bari: 0, 0, 2 sampled lines
-SHOW1: 1.8: inlined callee: _Z3bari: 0, 0, 2 sampled lines
SHOW1: 1.7: inlined callee: _Z3bari: 98558, 0, 2 sampled lines
+SHOW1: 1.8: inlined callee: _Z3bari: 0, 0, 2 sampled lines
2- Convert the profile to text encoding and check that they are both
identical.
SHOW1: Function: main: 366846, 0, 6 sampled lines
SHOW1: 2.3: inlined callee: _Z3fool: 246044, 0, 3 sampled lines
SHOW1: 1.3: inlined callee: _Z3bari: 0, 0, 2 sampled lines
-SHOW1: 1.8: inlined callee: _Z3bari: 0, 0, 2 sampled lines
SHOW1: 1.7: inlined callee: _Z3bari: 99492, 0, 2 sampled lines
SHOW1: 1.2: 46732
+SHOW1: 1.8: inlined callee: _Z3bari: 0, 0, 2 sampled lines
3- Convert the binary profile to text encoding and check that they are both
identical.