diff options
Diffstat (limited to 'afdo_tools')
-rwxr-xr-x | afdo_tools/bisection/afdo_parse.py | 63 | ||||
-rwxr-xr-x | afdo_tools/bisection/afdo_parse_test.py | 56 | ||||
-rwxr-xr-x | afdo_tools/bisection/afdo_prof_analysis.py | 31 | ||||
-rwxr-xr-x | afdo_tools/bisection/afdo_prof_analysis_test.py | 35 |
4 files changed, 62 insertions, 123 deletions
diff --git a/afdo_tools/bisection/afdo_parse.py b/afdo_tools/bisection/afdo_parse.py deleted file mode 100755 index 876c2c8f..00000000 --- a/afdo_tools/bisection/afdo_parse.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# Copyright 2019 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Performs basic parsing of an AFDO text-based profile. - -This short script performs very basic parsing of an AFDO text-based profile -into a dictionary which associates each top-level function with its profile -data (as plain text), and these results are dumped to a pickle file. -""" - -from __future__ import print_function -from absl import app -from absl import flags - -import json -import pprint - -flags.DEFINE_string('afdo_text', None, 'AFDO text-based profile to be parsed') -flags.DEFINE_string('output_file', None, 'File to write JSON results to') -FLAGS = flags.FLAGS - - -def parse_afdo(f): - """Performs basic parsing of an AFDO text-based profile. - - This parsing expects an input file of the form generated by bin/llvm-profdata - (within an LLVM build). - """ - results = {} - curr_func = None - curr_data = [] - for line in f: - if not line.startswith(' '): - if curr_func: - results[curr_func] = ''.join(curr_data) - curr_data = [] - curr_func, rest = line.split(':', 1) - curr_func = curr_func.strip() - curr_data.append(':' + rest) - else: - curr_data.append(line) - - if curr_func: - results[curr_func] = ''.join(curr_data) - return results - - -def main(_): - with open(FLAGS.afdo_text) as f: - results = parse_afdo(f) - if FLAGS.output_file: - with open(FLAGS.output_file, 'wb') as f_out: - json.dump(results, f_out, indent=2) - else: - pprint.pprint(results) - - -if __name__ == '__main__': - flags.mark_flag_as_required('afdo_text') - app.run(main) diff --git a/afdo_tools/bisection/afdo_parse_test.py b/afdo_tools/bisection/afdo_parse_test.py deleted file mode 100755 index 3c9288a0..00000000 --- a/afdo_tools/bisection/afdo_parse_test.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# Copyright 2019 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Tests for afdo_parse.""" - -from __future__ import print_function - -import StringIO -import unittest - -import afdo_parse - - -class SimpleAfdoParseTest(unittest.TestCase): - """Test class for AFDO parsing.""" - - def test_parse_afdo(self): - test_data = StringIO.StringIO('deflate_slow:87460059:3\n' - ' 3: 24\n' - ' 14: 54767\n' - ' 15: 664 fill_window:22\n' - ' 16: 661\n' - ' 19: 637\n' - ' 41: 36692 longest_match:36863\n' - ' 44: 36692\n' - ' 44.2: 5861\n' - ' 46: 13942\n' - ' 46.1: 14003\n') - expected = { - 'deflate_slow': ':87460059:3\n' - ' 3: 24\n' - ' 14: 54767\n' - ' 15: 664 fill_window:22\n' - ' 16: 661\n' - ' 19: 637\n' - ' 41: 36692 longest_match:36863\n' - ' 44: 36692\n' - ' 44.2: 5861\n' - ' 46: 13942\n' - ' 46.1: 14003\n' - } - actual = afdo_parse.parse_afdo(test_data) - self.assertEqual(actual, expected) - test_data.close() - - def test_parse_empty_afdo(self): - expected = {} - actual = afdo_parse.parse_afdo('') - self.assertEqual(actual, expected) - - -if __name__ == '__main__': - unittest.main() diff --git a/afdo_tools/bisection/afdo_prof_analysis.py b/afdo_tools/bisection/afdo_prof_analysis.py index f50e0b88..27ed7110 100755 --- a/afdo_tools/bisection/afdo_prof_analysis.py +++ b/afdo_tools/bisection/afdo_prof_analysis.py @@ -21,8 +21,6 @@ from datetime import date from enum import IntEnum from tempfile import mkstemp -from afdo_parse import parse_afdo - import json # Pylint recommends we use "from chromite.lib import cros_logging as logging". # Chromite specific policy message, we want to keep using the standard logging @@ -77,6 +75,31 @@ def json_to_text(json_prof): return ''.join(text_profile) +def text_to_json(f): + """Performs basic parsing of an AFDO text-based profile. + + This parsing expects an input file object with contents of the form generated + by bin/llvm-profdata (within an LLVM build). + """ + results = {} + curr_func = None + curr_data = [] + for line in f: + if not line.startswith(' '): + if curr_func: + results[curr_func] = ''.join(curr_data) + curr_data = [] + curr_func, rest = line.split(':', 1) + curr_func = curr_func.strip() + curr_data.append(':' + rest) + else: + curr_data.append(line) + + if curr_func: + results[curr_func] = ''.join(curr_data) + return results + + def prof_to_tmp(prof): """Creates (and returns) temp filename for given JSON-based AFDO profile.""" fd, temp_path = mkstemp() @@ -369,9 +392,9 @@ def main(_): random.seed(decider.seed) with open(FLAGS.good_prof) as good_f: - good_items = parse_afdo(good_f) + good_items = text_to_json(good_f) with open(FLAGS.bad_prof) as bad_f: - bad_items = parse_afdo(bad_f) + bad_items = text_to_json(bad_f) bisect_results = bisect_profiles_wrapper(decider, good_items, bad_items) gnb_result = check_good_not_bad(decider, good_items, bad_items) diff --git a/afdo_tools/bisection/afdo_prof_analysis_test.py b/afdo_tools/bisection/afdo_prof_analysis_test.py index ae87a1f9..7bd3050c 100755 --- a/afdo_tools/bisection/afdo_prof_analysis_test.py +++ b/afdo_tools/bisection/afdo_prof_analysis_test.py @@ -11,6 +11,7 @@ from __future__ import print_function import afdo_prof_analysis as analysis import random +import StringIO import unittest @@ -31,6 +32,40 @@ class AfdoProfAnalysisTest(unittest.TestCase): analysis.random.seed(5) # 5 is an arbitrary choice. For consistent testing + def test_text_to_json(self): + test_data = StringIO.StringIO('deflate_slow:87460059:3\n' + ' 3: 24\n' + ' 14: 54767\n' + ' 15: 664 fill_window:22\n' + ' 16: 661\n' + ' 19: 637\n' + ' 41: 36692 longest_match:36863\n' + ' 44: 36692\n' + ' 44.2: 5861\n' + ' 46: 13942\n' + ' 46.1: 14003\n') + expected = { + 'deflate_slow': ':87460059:3\n' + ' 3: 24\n' + ' 14: 54767\n' + ' 15: 664 fill_window:22\n' + ' 16: 661\n' + ' 19: 637\n' + ' 41: 36692 longest_match:36863\n' + ' 44: 36692\n' + ' 44.2: 5861\n' + ' 46: 13942\n' + ' 46.1: 14003\n' + } + actual = analysis.text_to_json(test_data) + self.assertEqual(actual, expected) + test_data.close() + + def test_text_to_json_empty_afdo(self): + expected = {} + actual = analysis.text_to_json('') + self.assertEqual(actual, expected) + def test_json_to_text(self): example_prof = {'func_a': ':1\ndata\n', 'func_b': ':2\nmore data\n'} expected_text = 'func_a:1\ndata\nfunc_b:2\nmore data\n' |