brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 5d4f549 Raw
197 lines · python
1#!/usr/bin/env python32 3"""Prepare a code coverage artifact.4 5- Collate raw profiles into one indexed profile.6- Generate html reports for the given binaries.7 8Caution: The positional arguments to this script must be specified before any 9optional arguments, such as --restrict.10"""11 12import argparse13import glob14import os15import subprocess16import sys17 18 19def merge_raw_profiles(host_llvm_profdata, profile_data_dir, preserve_profiles):20    print(":: Merging raw profiles...", end="")21    sys.stdout.flush()22    raw_profiles = glob.glob(os.path.join(profile_data_dir, "*.profraw"))23    manifest_path = os.path.join(profile_data_dir, "profiles.manifest")24    profdata_path = os.path.join(profile_data_dir, "Coverage.profdata")25    with open(manifest_path, "w") as manifest:26        manifest.write("\n".join(raw_profiles))27    subprocess.check_call(28        [29            host_llvm_profdata,30            "merge",31            "-sparse",32            "-f",33            manifest_path,34            "-o",35            profdata_path,36        ]37    )38    if not preserve_profiles:39        for raw_profile in raw_profiles:40            os.remove(raw_profile)41    os.remove(manifest_path)42    print("Done!")43    return profdata_path44 45 46def prepare_html_report(47    host_llvm_cov, profile, report_dir, binaries, restricted_dirs, compilation_dir48):49    print(":: Preparing html report for {0}...".format(binaries), end="")50    sys.stdout.flush()51    objects = []52    for i, binary in enumerate(binaries):53        if i == 0:54            objects.append(binary)55        else:56            objects.extend(("-object", binary))57    invocation = (58        [host_llvm_cov, "show"]59        + objects60        + [61            "-format",62            "html",63            "-instr-profile",64            profile,65            "-o",66            report_dir,67            "-show-line-counts-or-regions",68            "-show-directory-coverage",69            "-Xdemangler",70            "c++filt",71            "-Xdemangler",72            "-n",73        ]74        + restricted_dirs75    )76    if compilation_dir:77        invocation += ["-compilation-dir=" + compilation_dir]78    subprocess.check_call(invocation)79    with open(os.path.join(report_dir, "summary.txt"), "wb") as Summary:80        subprocess.check_call(81            [host_llvm_cov, "report"]82            + objects83            + ["-instr-profile", profile]84            + restricted_dirs,85            stdout=Summary,86        )87    print("Done!")88 89 90def prepare_html_reports(91    host_llvm_cov,92    profdata_path,93    report_dir,94    binaries,95    unified_report,96    restricted_dirs,97    compilation_dir,98):99    if unified_report:100        prepare_html_report(101            host_llvm_cov,102            profdata_path,103            report_dir,104            binaries,105            restricted_dirs,106            compilation_dir,107        )108    else:109        for binary in binaries:110            binary_report_dir = os.path.join(report_dir, os.path.basename(binary))111            prepare_html_report(112                host_llvm_cov,113                profdata_path,114                binary_report_dir,115                [binary],116                restricted_dirs,117                compilation_dir,118            )119 120 121if __name__ == "__main__":122    parser = argparse.ArgumentParser(description=__doc__)123    parser.add_argument("host_llvm_profdata", help="Path to llvm-profdata")124    parser.add_argument("host_llvm_cov", help="Path to llvm-cov")125    parser.add_argument(126        "profile_data_dir", help="Path to the directory containing the raw profiles"127    )128    parser.add_argument(129        "report_dir", help="Path to the output directory for html reports"130    )131    parser.add_argument(132        "binaries",133        metavar="B",134        type=str,135        nargs="*",136        help="Path to an instrumented binary",137    )138    parser.add_argument(139        "--only-merge",140        action="store_true",141        help="Only merge raw profiles together, skip report " "generation",142    )143    parser.add_argument(144        "--preserve-profiles", help="Do not delete raw profiles", action="store_true"145    )146    parser.add_argument(147        "--use-existing-profdata", help="Specify an existing indexed profile to use"148    )149    parser.add_argument(150        "--unified-report",151        action="store_true",152        help="Emit a unified report for all binaries",153    )154    parser.add_argument(155        "--restrict",156        metavar="R",157        type=str,158        nargs="*",159        default=[],160        help="Restrict the reporting to the given source paths"161        " (must be specified after all other positional arguments)",162    )163    parser.add_argument(164        "-C",165        "--compilation-dir",166        type=str,167        default="",168        help="The compilation directory of the binary",169    )170    args = parser.parse_args()171 172    if args.use_existing_profdata and args.only_merge:173        print("--use-existing-profdata and --only-merge are incompatible")174        exit(1)175 176    if args.use_existing_profdata:177        profdata_path = args.use_existing_profdata178    else:179        profdata_path = merge_raw_profiles(180            args.host_llvm_profdata, args.profile_data_dir, args.preserve_profiles181        )182 183    if not len(args.binaries):184        print("No binaries specified, no work to do!")185        exit(1)186 187    if not args.only_merge:188        prepare_html_reports(189            args.host_llvm_cov,190            profdata_path,191            args.report_dir,192            args.binaries,193            args.unified_report,194            args.restrict,195            args.compilation_dir,196        )197