[LNT] r335825 - [cPerf] Decide whether to discard functions before disassembling them
John Brawn via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 28 03:11:45 PDT 2018
Author: john.brawn
Date: Thu Jun 28 03:11:45 2018
New Revision: 335825
URL: http://llvm.org/viewvc/llvm-project?rev=335825&view=rev
Log:
[cPerf] Decide whether to discard functions before disassembling them
Currently we disassemble functions at the same time as we collect the events
that happen in them, which can lead to wasting a lot of time disassembling
functions that later get discarded. Fix this by restructuring so that we discard
before disassembling.
Differential Revision: https://reviews.llvm.org/D48648
Modified:
lnt/trunk/lnt/testing/profile/cPerf.cpp
Modified: lnt/trunk/lnt/testing/profile/cPerf.cpp
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/testing/profile/cPerf.cpp?rev=335825&r1=335824&r2=335825&view=diff
==============================================================================
--- lnt/trunk/lnt/testing/profile/cPerf.cpp (original)
+++ lnt/trunk/lnt/testing/profile/cPerf.cpp Thu Jun 28 03:11:45 2018
@@ -438,7 +438,8 @@ public:
void emitMaps();
void emitSymbol(
Symbol &Sym, Map &M,
- std::map<uint64_t, std::map<const char *, uint64_t>>::iterator &Event,
+ std::map<uint64_t, std::map<const char *, uint64_t>>::iterator Event,
+ std::map<const char *, uint64_t> &SymEvents,
uint64_t Adjust);
PyObject *complete();
@@ -633,15 +634,6 @@ void PerfReader::emitFunctionStart(std::
void PerfReader::emitFunctionEnd(std::string &Name,
std::map<const char *, uint64_t> &Counters) {
- // If the function only took up < 0.5% of any counter, don't bother with it.
- bool Keep = false;
- for (auto &KV : Counters) {
- if ((double)KV.second / (double)TotalEvents[KV.first] > 0.005)
- Keep = true;
- }
- if (!Keep)
- return;
-
auto *CounterDict = PyDict_New();
for (auto &KV : Counters)
PyDict_SetItemString(CounterDict, KV.first,
@@ -718,37 +710,54 @@ void PerfReader::emitMaps() {
NmOutput Syms(Nm);
Syms.reset(&Maps[MapID]);
- auto Sym = Syms.begin();
+ // Accumulate the event totals for each symbol
+ auto Sym = Syms.begin();
auto Event = MapEvents.begin();
+ std::map<uint64_t, std::map<const char*, uint64_t>> SymToEventTotals;
while (Event != MapEvents.end() && Sym != Syms.end()) {
+ // Skip events until we find one after the start of Sym
auto PC = Event->first - Adjust;
if (PC < Sym->Start) {
++Event;
continue;
}
- while (Sym != Syms.end() && PC >= Sym->End)
+ // Skip symbols until the event is before the end of Sym
+ if (PC >= Sym->End) {
++Sym;
- if (Sym == Syms.end() || Sym->Start > PC) {
- ++Event;
continue;
}
+ // We now know that Event lies within Sym, so add it to the totals
+ for (auto &KV : Event->second)
+ SymToEventTotals[Sym->Start][KV.first] += KV.second;
+ ++Event;
+ }
- emitSymbol(*Sym++, Maps[MapID], Event, Adjust);
+ // Emit only symbols that took up > 0.5% of any counter
+ for (auto &Sym : Syms) {
+ bool Keep = false;
+ for (auto &KV : SymToEventTotals[Sym.Start]) {
+ if ((double)KV.second / (double)TotalEvents[KV.first] > 0.005) {
+ Keep = true;
+ break;
+ }
+ }
+ if (Keep)
+ emitSymbol(Sym, Maps[MapID], MapEvents.lower_bound(Sym.Start),
+ SymToEventTotals[Sym.Start], Adjust);
}
}
}
void PerfReader::emitSymbol(
Symbol &Sym, Map &M,
- std::map<uint64_t, std::map<const char *, uint64_t>>::iterator &Event,
+ std::map<uint64_t, std::map<const char *, uint64_t>>::iterator Event,
+ std::map<const char *, uint64_t> &SymEvents,
uint64_t Adjust) {
ObjdumpOutput Dump(Objdump);
Dump.reset(&M, Sym.Start, Sym.End);
Dump.next();
- std::map<const char *, uint64_t> SymEvents;
-
emitFunctionStart(Sym.Name);
for (uint64_t I = Sym.Start; I < Sym.End; I = Dump.next()) {
auto PC = Event->first - Adjust;
@@ -756,10 +765,6 @@ void PerfReader::emitSymbol(
auto Text = Dump.getText();
if (PC == I) {
emitLine(I, &Event->second, Text);
-
- for (auto &KV : Event->second)
- SymEvents[KV.first] += KV.second;
-
++Event;
} else {
emitLine(I, nullptr, Text);
More information about the llvm-commits
mailing list