blob: 726375e899cd741b6e4ce6e131b5802010d689b1 [file] [log] [blame]
Vedant Kumard9aed822016-06-13 23:33:48 +00001#!/usr/bin/env python
2
Vedant Kumar74669872016-10-26 22:07:37 +00003from __future__ import print_function
4
Vedant Kumard9aed822016-06-13 23:33:48 +00005'''Prepare a code coverage artifact.
6
7- Collate raw profiles into one indexed profile.
Vedant Kumar547ebad2016-09-22 21:49:49 +00008- Generate html reports for the given binaries.
Vedant Kumard9aed822016-06-13 23:33:48 +00009'''
10
11import argparse
12import glob
13import os
14import subprocess
15import sys
16
Vedant Kumar05ee94f2016-07-18 22:50:10 +000017def merge_raw_profiles(host_llvm_profdata, profile_data_dir, preserve_profiles):
Vedant Kumar74669872016-10-26 22:07:37 +000018 print(':: Merging raw profiles...', end='')
Vedant Kumard9aed822016-06-13 23:33:48 +000019 sys.stdout.flush()
20 raw_profiles = glob.glob(os.path.join(profile_data_dir, '*.profraw'))
21 manifest_path = os.path.join(profile_data_dir, 'profiles.manifest')
22 profdata_path = os.path.join(profile_data_dir, 'Coverage.profdata')
23 with open(manifest_path, 'w') as manifest:
24 manifest.write('\n'.join(raw_profiles))
25 subprocess.check_call([host_llvm_profdata, 'merge', '-sparse', '-f',
26 manifest_path, '-o', profdata_path])
Vedant Kumar05ee94f2016-07-18 22:50:10 +000027 if not preserve_profiles:
28 for raw_profile in raw_profiles:
29 os.remove(raw_profile)
30 os.remove(manifest_path)
Vedant Kumar74669872016-10-26 22:07:37 +000031 print('Done!')
Vedant Kumar547ebad2016-09-22 21:49:49 +000032 return profdata_path
Vedant Kumard9aed822016-06-13 23:33:48 +000033
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000034def prepare_html_report(host_llvm_cov, profile, report_dir, binaries,
Vedant Kumar547ebad2016-09-22 21:49:49 +000035 restricted_dirs):
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000036 print(':: Preparing html report for {0}...'.format(binaries), end='')
Vedant Kumard9aed822016-06-13 23:33:48 +000037 sys.stdout.flush()
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000038 objects = []
39 for i, binary in enumerate(binaries):
40 if i == 0:
41 objects.append(binary)
42 else:
43 objects.extend(('-object', binary))
44 invocation = [host_llvm_cov, 'show'] + objects + ['-format', 'html',
45 '-instr-profile', profile, '-o', report_dir,
Vedant Kumar547ebad2016-09-22 21:49:49 +000046 '-show-line-counts-or-regions', '-Xdemangler', 'c++filt',
47 '-Xdemangler', '-n'] + restricted_dirs
48 subprocess.check_call(invocation)
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000049 with open(os.path.join(report_dir, 'summary.txt'), 'wb') as Summary:
50 subprocess.check_call([host_llvm_cov, 'report'] + objects +
51 ['-instr-profile', profile], stdout=Summary)
Vedant Kumar74669872016-10-26 22:07:37 +000052 print('Done!')
Vedant Kumard9aed822016-06-13 23:33:48 +000053
Vedant Kumar547ebad2016-09-22 21:49:49 +000054def prepare_html_reports(host_llvm_cov, profdata_path, report_dir, binaries,
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000055 unified_report, restricted_dirs):
56 if unified_report:
57 prepare_html_report(host_llvm_cov, profdata_path, report_dir, binaries,
Vedant Kumar547ebad2016-09-22 21:49:49 +000058 restricted_dirs)
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000059 else:
60 for binary in binaries:
61 binary_report_dir = os.path.join(report_dir,
62 os.path.basename(binary))
63 prepare_html_report(host_llvm_cov, profdata_path, binary_report_dir,
64 [binary], restricted_dirs)
Vedant Kumar05ee94f2016-07-18 22:50:10 +000065
Vedant Kumard9aed822016-06-13 23:33:48 +000066if __name__ == '__main__':
67 parser = argparse.ArgumentParser(description=__doc__)
68 parser.add_argument('host_llvm_profdata', help='Path to llvm-profdata')
69 parser.add_argument('host_llvm_cov', help='Path to llvm-cov')
70 parser.add_argument('profile_data_dir',
71 help='Path to the directory containing the raw profiles')
Vedant Kumar05ee94f2016-07-18 22:50:10 +000072 parser.add_argument('report_dir',
73 help='Path to the output directory for html reports')
Vedant Kumar273b6dc2016-10-26 22:07:35 +000074 parser.add_argument('binaries', metavar='B', type=str, nargs='*',
Vedant Kumar05ee94f2016-07-18 22:50:10 +000075 help='Path to an instrumented binary')
Vedant Kumar273b6dc2016-10-26 22:07:35 +000076 parser.add_argument('--only-merge', action='store_true',
77 help='Only merge raw profiles together, skip report '
78 'generation')
Vedant Kumar05ee94f2016-07-18 22:50:10 +000079 parser.add_argument('--preserve-profiles',
80 help='Do not delete raw profiles', action='store_true')
Vedant Kumar547ebad2016-09-22 21:49:49 +000081 parser.add_argument('--use-existing-profdata',
82 help='Specify an existing indexed profile to use')
Vedant Kumarf4df0ed2016-10-26 22:07:39 +000083 parser.add_argument('--unified-report', action='store_true',
84 help='Emit a unified report for all binaries')
Vedant Kumar547ebad2016-09-22 21:49:49 +000085 parser.add_argument('--restrict', metavar='R', type=str, nargs='*',
86 default=[],
87 help='Restrict the reporting to the given source paths')
Vedant Kumard9aed822016-06-13 23:33:48 +000088 args = parser.parse_args()
89
Vedant Kumar273b6dc2016-10-26 22:07:35 +000090 if args.use_existing_profdata and args.only_merge:
Vedant Kumar74669872016-10-26 22:07:37 +000091 print('--use-existing-profdata and --only-merge are incompatible')
Vedant Kumar273b6dc2016-10-26 22:07:35 +000092 exit(1)
93
Vedant Kumar547ebad2016-09-22 21:49:49 +000094 if args.use_existing_profdata:
95 profdata_path = args.use_existing_profdata
96 else:
97 profdata_path = merge_raw_profiles(args.host_llvm_profdata,
98 args.profile_data_dir,
99 args.preserve_profiles)
100
Vedant Kumarf4df0ed2016-10-26 22:07:39 +0000101 if not len(args.binaries):
102 print('No binaries specified, no work to do!')
103 exit(1)
104
Vedant Kumar273b6dc2016-10-26 22:07:35 +0000105 if not args.only_merge:
106 prepare_html_reports(args.host_llvm_cov, profdata_path, args.report_dir,
Vedant Kumarf4df0ed2016-10-26 22:07:39 +0000107 args.binaries, args.unified_report, args.restrict)