Add the abstract profile_reader interface that the perf, branch-stack
and SPE readers derive from.  It precedes them because a base class
cannot be forward declared, so each reader header needs this
definition to parse.

afdo_tools/ChangeLog:

        * src/profile_reader.h: New file.

Signed-off-by: Kugan Vivekanandarajah <[email protected]>
Co-authored-by: Dhruv Chawla <[email protected]>
Co-authored-by: Rahul Shinde <[email protected]>
---
 afdo_tools/src/profile_reader.h | 126 ++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100644 afdo_tools/src/profile_reader.h

diff --git a/afdo_tools/src/profile_reader.h b/afdo_tools/src/profile_reader.h
new file mode 100644
index 00000000000..9521e6efcee
--- /dev/null
+++ b/afdo_tools/src/profile_reader.h
@@ -0,0 +1,126 @@
+/* Copyright The GNU Toolchain Authors
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_PROFILE_READER_H
+#define GCC_PROFILE_READER_H
+
+#include "dwarf_types.h"
+#include "perf.h"
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace dwarf_debug {
+class dwarf_reader;
+}
+
+namespace perf_data {
+
+class branch_stack_reader_base;
+
+using function_timestamp_map
+  = std::map<std::pair<std::string, uint64_t>, uint64_t>;
+
+class profile_reader
+{
+  friend class branch_stack_reader_base;
+
+  /* Earliest observed sample time at each sampled PC.  */
+  std::unordered_map<uint64_t, uint64_t> first_sample_time_by_pc_;
+
+  /* Earliest observed sample time for each function after DWARF folding.  */
+  function_timestamp_map function_timestamps_;
+
+protected:
+  /* False when correlate scores sampled IPs and ignores the branch stack.  */
+  bool use_branch_stack_for_correlation_ = true;
+  std::vector<uint64_t> sorted_touch_pcs_;
+
+  void reset_profile_state ();
+  void note_sample_timestamp (uint64_t pc, uint64_t time);
+
+  /* Stamp IP with SAMPLE_TIME and, when ACCUMULATE_SAMPLE_IP, count it in
+     ADDRESS_FREQUENCIES.  Returns true when IP was counted.  */
+  bool
+  record_sample_ip (uint64_t ip, bool ip_is_target, uint64_t sample_time,
+                   bool accumulate_sample_ip,
+                   std::unordered_map<uint64_t, uint64_t> &address_frequencies)
+  {
+    if (sample_time != 0 && ip_is_target)
+      note_sample_timestamp (ip, sample_time);
+    if (!accumulate_sample_ip || !ip_is_target)
+      return false;
+    address_frequencies[ip]++;
+    return true;
+  }
+
+public:
+  virtual ~profile_reader () = default;
+
+  virtual bool load () = 0;
+  virtual const std::unordered_map<uint64_t, uint64_t> &
+  get_address_frequencies () const
+    = 0;
+  virtual uint64_t get_total_samples () const = 0;
+
+  /* Return the branch-stack interface when supported.  */
+  virtual branch_stack_reader_base *as_branch_stack_reader ()
+  {
+    return nullptr;
+  }
+  virtual const branch_stack_reader_base *as_branch_stack_reader () const
+  {
+    return nullptr;
+  }
+
+  /* Configure branch-stack mode, load, and prepare maps for correlate.
+     Returns false on load failure or empty sample mass.  */
+  bool load_and_prepare (bool use_branch_stack);
+
+  /* Address ranges that DWARF load should cover (half-open [beg, end)).  */
+  dwarf_debug::pc_range_list sample_ranges_for_dwarf () const;
+
+  /* Unique sorted touch PCs (built at load finalize).  */
+  const std::vector<uint64_t> &sorted_touch_pcs () const
+  {
+    return sorted_touch_pcs_;
+  }
+
+  /* Finalized branch-stack tables (nullptr when absent or empty).  */
+  const std::vector<profile_range> *range_counts () const;
+  const std::vector<profile_branch> *branch_counts () const;
+
+  /* True when correlate has range mass, branch edges, or per-PC counts.  */
+  bool has_sample_mass () const;
+
+  /* Retain the earliest sampled time for each function.  */
+  void
+  fold_sample_timestamps_by_function (const dwarf_debug::dwarf_reader &dwarf);
+
+  const function_timestamp_map &function_timestamps () const
+  {
+    return function_timestamps_;
+  }
+};
+
+} /* namespace perf_data.  */
+
+#endif /* GCC_PROFILE_READER_H.  */
-- 
2.34.1

Reply via email to