aboutsummaryrefslogtreecommitdiff
path: root/afdo_tools
diff options
context:
space:
mode:
authorEmma Vukelj <emmavukelj@google.com>2019-07-23 17:16:01 -0700
committerEmma Vukelj <emmavukelj@google.com>2019-07-24 16:36:30 +0000
commitadcb8bff41c7f3756756cbe581547897ad49d098 (patch)
tree24924622b212cf514af60e1af42fe2eb1f28e2e6 /afdo_tools
parent73ed016fe9ef0f8719390fcba8ea59d9a020a171 (diff)
downloadtoolchain-utils-adcb8bff41c7f3756756cbe581547897ad49d098.tar.gz
AFDO-Bisect: Remove separate parsing module
The initial parsing was written as a separate module imported by the main analysis and the tests. This is pretty unnecessary since it is only one relatively small function, and so this CL consolidates that code into the main functionality (and updates the tests to reflect this). BUG=None TEST=All existing tests succeed. Change-Id: I1d6ac4cf0abdbcdf7b837492580887d08d007bad Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1716324 Reviewed-by: George Burgess <gbiv@chromium.org> Reviewed-by: Caroline Tice <cmtice@chromium.org> Tested-by: Emma Vukelj <emmavukelj@google.com>
Diffstat (limited to 'afdo_tools')
-rwxr-xr-xafdo_tools/bisection/afdo_parse.py63
-rwxr-xr-xafdo_tools/bisection/afdo_parse_test.py56
-rwxr-xr-xafdo_tools/bisection/afdo_prof_analysis.py31
-rwxr-xr-xafdo_tools/bisection/afdo_prof_analysis_test.py35
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'