[Lldb-commits] [PATCH] D122603: [intelpt] Refactor timestamps out of IntelPTInstruction

walter erquinigo via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed Mar 30 18:56:22 PDT 2022


wallace requested changes to this revision.
wallace added a comment.
This revision now requires changes to proceed.

Some calculations are wrong, but overall this is good. We are very close!



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:112-113
+DecodedThread::CalculateTscRange(size_t insn_index) const {
+  if (m_instruction_timestamps.empty())
+    return None;
+
----------------
now that I think of this, you can delete this, because if the map is empty, this function will return in line 117


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:135-138
+    : m_thread_sp(thread_sp), m_last_tsc(None) {}
 
 DecodedThread::DecodedThread(ThreadSP thread_sp, Error &&error)
+    : m_thread_sp(thread_sp), m_last_tsc(None) {
----------------
undo these two lines


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:159
+DecodedThread::TscRange::TscRange(std::map<size_t, uint64_t>::const_iterator it,
+                                  const DecodedThread &ref)
+    : m_it(it), m_decoded_thread(ref) {
----------------
decoded_thread instead of ref


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:161-162
+    : m_it(it), m_decoded_thread(ref) {
+  m_start_index = it->first;
+  m_tsc = it->second;
+
----------------
delete


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:164-168
+  auto end = m_decoded_thread.m_instruction_timestamps.end();
+  if (it != end)
+    m_end_index = (++it--)->first - 1;
+  else
+    m_end_index = end->first;
----------------
seeing ++ and -- is very hard to read. I also prefer not to modify the `it` variable for cleanness. Also doing end->first might crash the program. I'm writing here a correct version


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:173
+
+size_t DecodedThread::TscRange::GetStart() const { return m_start_index; }
+
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:178
+bool DecodedThread::TscRange::InRange(size_t insn_index) {
+  if (insn_index < m_end_index && insn_index > m_start_index)
+    return true;
----------------
The comparison is not right. let's use <= in a specific order to make it easier to read


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:186
+    return None;
+  return TscRange(++m_it, m_decoded_thread);
+}
----------------
As m_it is valid, doing the comparison `m_it == m_decoded_thread.m_instruction_timestamps.end()` will always return false. Remember that .end() will return a fake iterator that points to no value.

Besides that, don't modify m_it. Let's better create a new iterator


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp:190-192
+  if (m_it == m_decoded_thread.m_instruction_timestamps.end())
+    return None;
+  return TscRange(--m_it, m_decoded_thread);
----------------
Similarly, this has to be improved. I also like to put `--it` statements in their own line to make it easier to read.


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:142
+  /// \class TscRange
+  /// Class that represents the instruction range associated with a given TSC.
+  /// It provides efficient iteration to the previous or next TSC range in the
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:147-148
+  /// TSC timestamps are emitted by the decoder infrequently, which means
+  /// that each TSC covers a range of instruction indices, which we can use to
+  /// speed up TSC lookups.
+  class TscRange {
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:149
+  /// speed up TSC lookups.
+  class TscRange {
+  public:
----------------
Move this class to the beginning of the public section of DecodedThread for easier discoverability


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:151
+  public:
+    // Check if current TSC range covers given instruction index.
+    bool InRange(size_t insn_index);
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:167-173
+    TscRange &operator=(const TscRange &r) {
+      m_it = r.m_it;
+      m_tsc = r.m_tsc;
+      m_start_index = r.m_start_index;
+      m_end_index = r.m_end_index;
+      return *this;
+    }
----------------
let's better delete this. It adds some maintenance cost with little benefits


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:178
+
+    // Construct TscRange respecting bounds of timestamp map in thread
+    TscRange(std::map<size_t, uint64_t>::const_iterator it,
----------------
This comment is hard to follow. Let's just delete it because it's a private constructor


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:185-188
+    /// The TSC value
+    uint64_t m_tsc;
+    /// The smallest instruction index that has this TSC.
+    size_t m_start_index;
----------------
Let's just delete this, as we can get them directly from m_it without doing any operations


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:193
+
+  /// Construct a TSC range of an instruction by its index.
+  /// This operation is O(logn) and should be used sparingly.
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:232-236
+  /// This map contains the TSCs of the decoded instructions. It might be empty
+  /// if the trace doesn't contain TSCs. It maps `instruction index -> TSC`,
+  /// where `instruction index` is the first index at which the mapped TSC
+  /// appears. We use this representation because TSCs are sporadic and we can
+  /// think of it as ranges.
----------------
let's add another piece of information


================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:236
+  /// appears. We use this representation because TSCs are sporadic and we can
+  /// think of it as ranges.
+  std::map<size_t, uint64_t> m_instruction_timestamps;
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h:239
+  /// This is the chronologically last TSC that has been added.
+  llvm::Optional<uint64_t> m_last_tsc;
+  // This variables stores the messages of all the error instructions in the
----------------
Setting to llvm::None here is equivalent to doing it from all the constructors


================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp:45-52
+    if (!m_current_tsc)
+      m_current_tsc = m_decoded_thread_sp->CalculateTscRange(m_pos);
+    else if (!m_current_tsc->InRange(m_pos)) {
+      if (m_pos > m_current_tsc->GetEnd())
+        m_current_tsc = m_current_tsc->Next();
+      if (m_pos < m_current_tsc->GetStart())
+        m_current_tsc = m_current_tsc->Prev();
----------------
No need to do `m_current_tsc = m_decoded_thread_sp->CalculateTscRange(m_pos);` because its value has already been calculated in the constructor. We can simplify this as well


================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp:102-103
 
-Optional<uint64_t> TraceCursorIntelPT::GetCounter(lldb::TraceCounter counter_type) {
+Optional<uint64_t>
+TraceCursorIntelPT::GetCounter(lldb::TraceCounter counter_type) {
+  if (!m_current_tsc)
----------------
are you using git clang-format? I'm curious why this line changed


================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp:104-110
+  if (!m_current_tsc)
+    return None;
+
   switch (counter_type) {
-    case lldb::eTraceCounterTSC:
-      return m_decoded_thread_sp->GetInstructions()[m_pos].GetTimestampCounter();
+  case lldb::eTraceCounterTSC:
+    return m_current_tsc->GetTsc();
   }
----------------



================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h:45
   size_t m_pos;
+  /// Current instruction timestamp.
+  llvm::Optional<DecodedThread::TscRange> m_current_tsc;
----------------
/// Tsc range covering the current instruction.


================
Comment at: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp:124
+    s.Printf("  Average memory usage per instruction: %zu bytes\n",
+            (mem_used - *raw_size) / insn_len);
   return;
----------------
Instead of doing ` *raw_size`, better remove this number from CalculateApproximateMemoryUsage()


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122603/new/

https://reviews.llvm.org/D122603



More information about the lldb-commits mailing list