From 3b8ef7876ec797a03569184264e7ba4e5e046b68 Mon Sep 17 00:00:00 2001 From: Djordje Todorovic Date: Wed, 15 Jan 2020 13:00:14 +0100 Subject: [PATCH] [llvm-locstats] Add the --compare option Draw a plot showing the difference in debug loc coverage on two files provided. Differential Revision: https://reviews.llvm.org/D71870 --- llvm/docs/CommandGuide/llvm-locstats.rst | 18 +++++ llvm/docs/CommandGuide/locstats-compare.png | Bin 0 -> 58210 bytes llvm/utils/llvm-locstats/llvm-locstats.py | 115 ++++++++++++++++++++++------ 3 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 llvm/docs/CommandGuide/locstats-compare.png diff --git a/llvm/docs/CommandGuide/llvm-locstats.rst b/llvm/docs/CommandGuide/llvm-locstats.rst index 227c069..3186566 100644 --- a/llvm/docs/CommandGuide/llvm-locstats.rst +++ b/llvm/docs/CommandGuide/llvm-locstats.rst @@ -43,6 +43,11 @@ OPTIONS make histogram of location buckets generated (requires matplotlib) +.. option:: --compare + + compare the debug location coverage on two files provided, and draw + a plot showing the difference (requires matplotlib) + EXIT STATUS ----------- @@ -94,6 +99,19 @@ Generate a plot as an image file. .. image:: locstats-draw-plot.png :align: center +EXAMPLE 3 +-------------- + +Generate a plot as an image file showing the difference in the debug location +coverage. + +.. code-block:: none + + llvm-locstats --compare file1.out file1.withentryvals.out + +.. image:: locstats-compare.png + :align: center + SEE ALSO -------- diff --git a/llvm/docs/CommandGuide/locstats-compare.png b/llvm/docs/CommandGuide/locstats-compare.png new file mode 100644 index 0000000000000000000000000000000000000000..1f0a3af65e4a6f8bb38e418fd421e161ecd857b6 GIT binary patch literal 58210 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

rQO=8oJbuz7f6=ib`4dV+cQh|f)^ZQSp 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 literal 0 HcmV?d00001 diff --git a/llvm/utils/llvm-locstats/llvm-locstats.py b/llvm/utils/llvm-locstats/llvm-locstats.py index 03b4082..7b2f706 100755 --- a/llvm/utils/llvm-locstats/llvm-locstats.py +++ b/llvm/utils/llvm-locstats/llvm-locstats.py @@ -14,6 +14,21 @@ from math import ceil from collections import OrderedDict from subprocess import Popen, PIPE +# Initialize the plot. +def init_plot(plt): + plt.title('Debug Location Statistics', fontweight='bold') + plt.xlabel('location buckets') + plt.ylabel('number of variables in the location buckets') + plt.xticks(rotation=45, fontsize='x-small') + plt.yticks() + +# Finalize the plot. +def finish_plot(plt): + plt.legend() + plt.grid(color='grey', which='major', axis='y', linestyle='-', linewidth=0.3) + plt.savefig('locstats.png') + print('The plot was saved within "locstats.png".') + # Holds the debug location statistics. class LocationStats: def __init__(self, file_name, variables_total, variables_total_locstats, @@ -73,24 +88,14 @@ class LocationStats: # Draw a plot representing the location buckets. def draw_plot(self): - try: - import matplotlib - except ImportError: - print('error: matplotlib not found.') - sys.exit(1) - from matplotlib import pyplot as plt buckets = range(len(self.variables_coverage_map)) plt.figure(figsize=(12, 8)) - plt.title('Debug Location Statistics', fontweight='bold') - plt.xlabel('location buckets') - plt.ylabel('number of variables in the location buckets') + init_plot(plt) plt.bar(buckets, self.variables_coverage_map.values(), align='center', tick_label=self.variables_coverage_map.keys(), label='variables of {}'.format(self.file_name)) - plt.xticks(rotation=45, fontsize='x-small') - plt.yticks() # Place the text box with the coverage info. pc_ranges_covered = self.get_pc_coverage() @@ -98,11 +103,47 @@ class LocationStats: plt.text(0.02, 0.90, 'PC ranges covered: {}%'.format(pc_ranges_covered), transform=plt.gca().transAxes, fontsize=12, verticalalignment='top', bbox=props) - plt.legend() - plt.grid(color='grey', which='major', axis='y', linestyle='-', linewidth=0.3) - plt.savefig('locstats.png') - print('The plot was saved within "locstats.png".') + finish_plot(plt) + + # Compare the two LocationStats objects and draw a plot showing + # the difference. + def draw_location_diff(self, locstats_to_compare): + from matplotlib import pyplot as plt + + pc_ranges_covered = self.get_pc_coverage() + pc_ranges_covered_to_compare = locstats_to_compare.get_pc_coverage() + + buckets = range(len(self.variables_coverage_map)) + buckets_to_compare = range(len(locstats_to_compare.variables_coverage_map)) + + fig = plt.figure(figsize=(12, 8)) + ax = fig.add_subplot(111) + init_plot(plt) + + ax.bar(buckets, self.variables_coverage_map.values(), align='edge', + tick_label=self.variables_coverage_map.keys(), width=0.4, + label='variables of {}'.format(self.file_name)) + ax.bar(buckets_to_compare, + locstats_to_compare.variables_coverage_map.values(), + color='r', align='edge', width=-0.4, + tick_label=locstats_to_compare.variables_coverage_map.keys(), + label='variables of {}'.format(locstats_to_compare.file_name)) + + props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) + plt.text(0.02, 0.88, + '{} PC ranges covered: {}%'. \ + format(self.file_name, pc_ranges_covered), + transform=plt.gca().transAxes, fontsize=12, + verticalalignment='top', bbox=props) + plt.text(0.02, 0.83, + '{} PC ranges covered: {}%'. \ + format(locstats_to_compare.file_name, + pc_ranges_covered_to_compare), + transform=plt.gca().transAxes, fontsize=12, + verticalalignment='top', bbox=props) + + finish_plot(plt) # Define the location buckets. def coverage_buckets(): @@ -233,7 +274,11 @@ def parse_program_args(parser): parser.add_argument('--draw-plot', action='store_true', default=False, help='show histogram of location buckets generated (requires ' 'matplotlib)') - parser.add_argument('file_name', type=str, help='file to process') + parser.add_argument('--compare', action='store_true', default=False, + help='compare the debug location coverage on two files provided, ' + 'and draw a plot showing the difference (requires ' + 'matplotlib)') + parser.add_argument('file_names', nargs='+', type=str, help='file to process') return parser.parse_args() @@ -247,6 +292,21 @@ def verify_program_inputs(opts): print ('error: Please use just one --only* option.') return False + if not opts.compare and len(opts.file_names) != 1: + print ('error: Please specify only one file to process.') + return False + + if opts.compare and len(opts.file_names) != 2: + print ('error: Please specify two files to process.') + return False + + if opts.draw_plot or opts.compare: + try: + import matplotlib + except ImportError: + print('error: matplotlib not found.') + return False + return True def Main(): @@ -257,16 +317,23 @@ def Main(): parser.print_help() sys.exit(1) - binary = opts.file_name - locstats = parse_locstats(opts, binary) + binary_file = opts.file_names[0] + locstats = parse_locstats(opts, binary_file) - if opts.draw_plot: - # Draw a histogram representing the location buckets. - locstats.draw_plot() + if not opts.compare: + if opts.draw_plot: + # Draw a histogram representing the location buckets. + locstats.draw_plot() + else: + # Pretty print collected info on the standard output. + if locstats.pretty_print() == -1: + sys.exit(0) else: - # Pretty print collected info on the standard output. - if locstats.pretty_print() == -1: - sys.exit(0) + binary_file_to_compare = opts.file_names[1] + locstats_to_compare = parse_locstats(opts, binary_file_to_compare) + # Draw a plot showing the difference in debug location coverage between + # two files. + locstats.draw_location_diff(locstats_to_compare) if __name__ == '__main__': Main() -- 2.7.4