Add profiler orchestration that loads samples, initializes DWARF,
correlates source data, and exports a profile. The command-line frontend
remains separate from this reusable pipeline.
afdo_tools/ChangeLog:
* src/autofdo_profiler.cc: New file.
* src/autofdo_profiler.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/autofdo_profiler.cc | 141 +++++++++++++++++++++++++++++
afdo_tools/src/autofdo_profiler.h | 76 ++++++++++++++++
2 files changed, 217 insertions(+)
create mode 100644 afdo_tools/src/autofdo_profiler.cc
create mode 100644 afdo_tools/src/autofdo_profiler.h
diff --git a/afdo_tools/src/autofdo_profiler.cc
b/afdo_tools/src/autofdo_profiler.cc
new file mode 100644
index 00000000000..8f13f20b03f
--- /dev/null
+++ b/afdo_tools/src/autofdo_profiler.cc
@@ -0,0 +1,141 @@
+/* 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/>. */
+
+#include "autofdo_profiler.h"
+#include "autofdo_correlator.h"
+#include "autofdo_debug_dump.h"
+#include "dwarf_reader.h"
+#include "live_branch_stack_reader.h"
+#include "perf_file_reader.h"
+#include "profile_reader.h"
+#include "profile_timer.h"
+
+#include <cstdio>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace autofdo {
+
+autofdo_profiler::autofdo_profiler (const std::string &binary_path,
+ const profiler_run_options &run_opts,
+ const std::string &perf_data_path,
+ perf_data::sampling_mode sampling_mode)
+ : binary_path_ (binary_path), run_opts_ (run_opts)
+{
+ profile_source_ = perf_data::create_perf_reader (
+ perf_data_path, binary_path, sampling_mode);
+}
+
+autofdo_profiler::autofdo_profiler (const std::string &binary_path,
+ const profiler_run_options &run_opts,
+ std::vector<std::string> command_argv)
+ : binary_path_ (binary_path), run_opts_ (run_opts)
+{
+ profile_source_ = std::make_unique<perf_data::live_branch_stack_reader> (
+ binary_path, std::move (command_argv), run_opts.live_sample_period);
+}
+
+autofdo_profiler::~autofdo_profiler () = default;
+
+/* Run the whole pipeline: read the perf profile, load DWARF over the sampled
+ ranges, correlate samples to source, and write the gcov profile. */
+bool
+autofdo_profiler::generate_profile ()
+{
+ /* 1. Load samples. */
+ profile_timer::begin_stage (_("profile load"));
+ fprintf (stderr, _("Loading profile...\n"));
+ if (profile_source_ == nullptr)
+ {
+ fprintf (stderr, _("Error: no profile reader is available\n"));
+ return false;
+ }
+ if (!profile_source_->load_and_prepare (run_opts_.use_branch_stack))
+ return false;
+ if (!run_opts_.dump_perf_maps.empty ())
+ dump_ingested_perf_maps (*profile_source_, run_opts_.dump_perf_maps);
+ {
+ std::string detail
+ = std::to_string (profile_source_->get_total_samples ()) + _(" samples");
+ if (const auto *ranges = profile_source_->range_counts ())
+ detail += _(", ") + std::to_string (ranges->size ()) + _(" ranges");
+ profile_timer::end_stage (detail);
+ }
+
+ /* 2. Load DWARF for the sampled address scope. */
+ profile_timer::begin_stage (_("DWARF load"));
+ dwarf_debug::pc_range_list sampled_ranges
+ = profile_source_->sample_ranges_for_dwarf ();
+ if (sampled_ranges.empty ())
+ {
+ fprintf (stderr,
+ _("Error: No profile sample scope for DWARF load\n"));
+ return false;
+ }
+ dwarf_reader_ = std::make_unique<dwarf_debug::dwarf_reader> (
+ binary_path_, std::move (sampled_ranges));
+ dwarf_reader_->set_parse_threads (run_opts_.correlate_threads);
+ if (!dwarf_reader_->load ())
+ {
+ fprintf (stderr, _("Error: Failed to load DWARF from %s\n"),
+ binary_path_.c_str ());
+ return false;
+ }
+ {
+ const dwarf_debug::dwarf_load_summary &s = dwarf_reader_->load_summary ();
+ std::string detail = std::to_string (s.touch_cus) + _(" CUs, ")
+ + std::to_string (s.dwarf_functions)
+ + _(" DWARF funcs, ")
+ + std::to_string (s.symtab_functions) + _(" symtab, ")
+ + std::to_string (s.line_segments)
+ + _(" line segments, ") + std::to_string (s.touch_pcs)
+ + _(" touch PCs");
+ profile_timer::end_stage (detail);
+ }
+
+ profile_source_->fold_sample_timestamps_by_function (*dwarf_reader_);
+
+ /* 3. Correlate samples into the profile tree. */
+ profile_timer::begin_stage (_("correlate"));
+ const bool correlated = correlate_samples_to_source
+ (profile_, *profile_source_, *dwarf_reader_, run_opts_);
+ if (!correlated)
+ return false;
+ profile_timer::end_stage ();
+
+ /* 4. Finalize and emit GCOV. */
+ profile_timer::begin_stage (_("finalize"));
+ profile_.finalize_after_correlate (*profile_source_);
+ profile_.materialize_alias_profiles (
+ dwarf_reader_->symtab_functions (), dwarf_reader_->symtab_aliases ());
+ profile_timer::end_stage ();
+
+ profile_timer::begin_stage (_("build gcov"));
+ profile_.build_gcov_profile (gcov_out_);
+ if (gcov_out_.get_functions ().empty ())
+ {
+ fprintf (stderr,
+ _("Error: correlation produced no source-level profile data\n"));
+ return false;
+ }
+ profile_timer::end_stage ();
+ return true;
+}
+
+} /* namespace autofdo. */
diff --git a/afdo_tools/src/autofdo_profiler.h
b/afdo_tools/src/autofdo_profiler.h
new file mode 100644
index 00000000000..e326fbc4aa1
--- /dev/null
+++ b/afdo_tools/src/autofdo_profiler.h
@@ -0,0 +1,76 @@
+/* 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_AUTOFDO_PROFILER_H
+#define GCC_AUTOFDO_PROFILER_H
+
+#include "autofdo_model.h"
+#include "autofdo_options.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace dwarf_debug {
+class dwarf_reader;
+}
+
+namespace perf_data {
+class profile_reader;
+enum class sampling_mode : uint8_t;
+} /* namespace perf_data. */
+
+namespace autofdo {
+
+/* Drive sample load, DWARF, correlate, then GCOV. Offline perf.data and live
+ capture differ only in how profile_source_ is constructed. */
+class autofdo_profiler
+{
+public:
+ autofdo_profiler (const std::string &binary_path,
+ const profiler_run_options &run_opts,
+ const std::string &perf_data_path,
+ perf_data::sampling_mode sampling_mode);
+
+ /* Live capture via perf_event_open (command after --). */
+ autofdo_profiler (const std::string &binary_path,
+ const profiler_run_options &run_opts,
+ std::vector<std::string> command_argv);
+
+ ~autofdo_profiler ();
+ autofdo_profiler (const autofdo_profiler &) = delete;
+ autofdo_profiler &operator= (const autofdo_profiler &) = delete;
+ autofdo_profiler (autofdo_profiler &&) = delete;
+ autofdo_profiler &operator= (autofdo_profiler &&) = delete;
+
+ bool generate_profile ();
+ const gcov::gcov_profile &get_gcov_profile () const { return gcov_out_; }
+
+private:
+ std::string binary_path_;
+ profiler_run_options run_opts_;
+ std::unique_ptr<perf_data::profile_reader> profile_source_;
+ std::unique_ptr<dwarf_debug::dwarf_reader> dwarf_reader_;
+ profile_builder profile_;
+ gcov::gcov_profile gcov_out_;
+};
+
+} /* namespace autofdo. */
+
+#endif /* GCC_AUTOFDO_PROFILER_H. */
--
2.34.1