mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
64425caba2
My previous patch D151283 added a new option to llvm-cov to make it generate a hierarchical report for better view. This patch is to enable it for the coverage report of LLVM itself. Reviewed By: phosek Differential Revision: https://reviews.llvm.org/D158703
199 lines
5.5 KiB
Python
Executable File
199 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function
|
|
|
|
"""Prepare a code coverage artifact.
|
|
|
|
- Collate raw profiles into one indexed profile.
|
|
- Generate html reports for the given binaries.
|
|
|
|
Caution: The positional arguments to this script must be specified before any
|
|
optional arguments, such as --restrict.
|
|
"""
|
|
|
|
import argparse
|
|
import glob
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def merge_raw_profiles(host_llvm_profdata, profile_data_dir, preserve_profiles):
|
|
print(":: Merging raw profiles...", end="")
|
|
sys.stdout.flush()
|
|
raw_profiles = glob.glob(os.path.join(profile_data_dir, "*.profraw"))
|
|
manifest_path = os.path.join(profile_data_dir, "profiles.manifest")
|
|
profdata_path = os.path.join(profile_data_dir, "Coverage.profdata")
|
|
with open(manifest_path, "w") as manifest:
|
|
manifest.write("\n".join(raw_profiles))
|
|
subprocess.check_call(
|
|
[
|
|
host_llvm_profdata,
|
|
"merge",
|
|
"-sparse",
|
|
"-f",
|
|
manifest_path,
|
|
"-o",
|
|
profdata_path,
|
|
]
|
|
)
|
|
if not preserve_profiles:
|
|
for raw_profile in raw_profiles:
|
|
os.remove(raw_profile)
|
|
os.remove(manifest_path)
|
|
print("Done!")
|
|
return profdata_path
|
|
|
|
|
|
def prepare_html_report(
|
|
host_llvm_cov, profile, report_dir, binaries, restricted_dirs, compilation_dir
|
|
):
|
|
print(":: Preparing html report for {0}...".format(binaries), end="")
|
|
sys.stdout.flush()
|
|
objects = []
|
|
for i, binary in enumerate(binaries):
|
|
if i == 0:
|
|
objects.append(binary)
|
|
else:
|
|
objects.extend(("-object", binary))
|
|
invocation = (
|
|
[host_llvm_cov, "show"]
|
|
+ objects
|
|
+ [
|
|
"-format",
|
|
"html",
|
|
"-instr-profile",
|
|
profile,
|
|
"-o",
|
|
report_dir,
|
|
"-show-line-counts-or-regions",
|
|
"-show-directory-coverage",
|
|
"-Xdemangler",
|
|
"c++filt",
|
|
"-Xdemangler",
|
|
"-n",
|
|
]
|
|
+ restricted_dirs
|
|
)
|
|
if compilation_dir:
|
|
invocation += ["-compilation-dir=" + compilation_dir]
|
|
subprocess.check_call(invocation)
|
|
with open(os.path.join(report_dir, "summary.txt"), "wb") as Summary:
|
|
subprocess.check_call(
|
|
[host_llvm_cov, "report"]
|
|
+ objects
|
|
+ ["-instr-profile", profile]
|
|
+ restricted_dirs,
|
|
stdout=Summary,
|
|
)
|
|
print("Done!")
|
|
|
|
|
|
def prepare_html_reports(
|
|
host_llvm_cov,
|
|
profdata_path,
|
|
report_dir,
|
|
binaries,
|
|
unified_report,
|
|
restricted_dirs,
|
|
compilation_dir,
|
|
):
|
|
if unified_report:
|
|
prepare_html_report(
|
|
host_llvm_cov,
|
|
profdata_path,
|
|
report_dir,
|
|
binaries,
|
|
restricted_dirs,
|
|
compilation_dir,
|
|
)
|
|
else:
|
|
for binary in binaries:
|
|
binary_report_dir = os.path.join(report_dir, os.path.basename(binary))
|
|
prepare_html_report(
|
|
host_llvm_cov,
|
|
profdata_path,
|
|
binary_report_dir,
|
|
[binary],
|
|
restricted_dirs,
|
|
compilation_dir,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("host_llvm_profdata", help="Path to llvm-profdata")
|
|
parser.add_argument("host_llvm_cov", help="Path to llvm-cov")
|
|
parser.add_argument(
|
|
"profile_data_dir", help="Path to the directory containing the raw profiles"
|
|
)
|
|
parser.add_argument(
|
|
"report_dir", help="Path to the output directory for html reports"
|
|
)
|
|
parser.add_argument(
|
|
"binaries",
|
|
metavar="B",
|
|
type=str,
|
|
nargs="*",
|
|
help="Path to an instrumented binary",
|
|
)
|
|
parser.add_argument(
|
|
"--only-merge",
|
|
action="store_true",
|
|
help="Only merge raw profiles together, skip report " "generation",
|
|
)
|
|
parser.add_argument(
|
|
"--preserve-profiles", help="Do not delete raw profiles", action="store_true"
|
|
)
|
|
parser.add_argument(
|
|
"--use-existing-profdata", help="Specify an existing indexed profile to use"
|
|
)
|
|
parser.add_argument(
|
|
"--unified-report",
|
|
action="store_true",
|
|
help="Emit a unified report for all binaries",
|
|
)
|
|
parser.add_argument(
|
|
"--restrict",
|
|
metavar="R",
|
|
type=str,
|
|
nargs="*",
|
|
default=[],
|
|
help="Restrict the reporting to the given source paths"
|
|
" (must be specified after all other positional arguments)",
|
|
)
|
|
parser.add_argument(
|
|
"-C",
|
|
"--compilation-dir",
|
|
type=str,
|
|
default="",
|
|
help="The compilation directory of the binary",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
if args.use_existing_profdata and args.only_merge:
|
|
print("--use-existing-profdata and --only-merge are incompatible")
|
|
exit(1)
|
|
|
|
if args.use_existing_profdata:
|
|
profdata_path = args.use_existing_profdata
|
|
else:
|
|
profdata_path = merge_raw_profiles(
|
|
args.host_llvm_profdata, args.profile_data_dir, args.preserve_profiles
|
|
)
|
|
|
|
if not len(args.binaries):
|
|
print("No binaries specified, no work to do!")
|
|
exit(1)
|
|
|
|
if not args.only_merge:
|
|
prepare_html_reports(
|
|
args.host_llvm_cov,
|
|
profdata_path,
|
|
args.report_dir,
|
|
args.binaries,
|
|
args.unified_report,
|
|
args.restrict,
|
|
args.compilation_dir,
|
|
)
|