[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