aboutsummaryrefslogtreecommitdiff
path: root/afdo_tools
diff options
context:
space:
mode:
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'