mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
Add diff and merge capability to cg_annotate.
And deprecate the use of `cg_diff` and `cg_merge`. Because `cg_annotate` can do a better job, even annotating source files when doing diffs in some cases. The user requests merging by passing multiple cgout files to `cg_annotate`, and diffing by passing two cgout files to `cg_annotate` along with `--diff`.
This commit is contained in:
parent
a2af9adec4
commit
1fdf0e728a
@ -34,17 +34,28 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import filecmp
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from argparse import ArgumentParser, BooleanOptionalAction, Namespace
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict, NoReturn, TextIO
|
||||
from typing import Callable, DefaultDict, NoReturn, TextIO
|
||||
|
||||
|
||||
def die(msg: str) -> NoReturn:
|
||||
print("cg_annotate: error:", msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
SearchAndReplace = Callable[[str], str]
|
||||
|
||||
# A typed wrapper for parsed args.
|
||||
class Args(Namespace):
|
||||
# None of these fields are modified after arg parsing finishes.
|
||||
diff: bool
|
||||
mod_filename: SearchAndReplace
|
||||
mod_funcname: SearchAndReplace
|
||||
show: list[str]
|
||||
sort: list[str]
|
||||
threshold: float # a percentage
|
||||
@ -55,6 +66,42 @@ class Args(Namespace):
|
||||
|
||||
@staticmethod
|
||||
def parse() -> Args:
|
||||
# We support Perl-style `s/old/new/flags` search-and-replace
|
||||
# expressions, because that's how this option was implemented in the
|
||||
# old Perl version of `cg_diff`. This requires conversion from
|
||||
# `s/old/new/` style to `re.sub`. The conversion isn't a perfect
|
||||
# emulation of Perl regexps (e.g. Python uses `\1` rather than `$1` for
|
||||
# using captures in the `new` part), but it should be close enough. The
|
||||
# only supported flags are `g` (global) and `i` (ignore case).
|
||||
def search_and_replace(regex: str | None) -> SearchAndReplace:
|
||||
if regex is None:
|
||||
return lambda s: s
|
||||
|
||||
# Extract the parts of an `s/old/new/tail` regex. `(?<!\\)/` is an
|
||||
# example of negative lookbehind. It means "match a forward slash
|
||||
# unless preceded by a backslash".
|
||||
m = re.match(r"s/(.*)(?<!\\)/(.*)(?<!\\)/(g|i|gi|ig|)$", regex)
|
||||
if m is None:
|
||||
raise ValueError
|
||||
|
||||
# Forward slashes must be escaped in an `s/old/new/` expression,
|
||||
# but we then must unescape them before using them with `re.sub`.
|
||||
pat = m.group(1).replace(r"\/", r"/")
|
||||
repl = m.group(2).replace(r"\/", r"/")
|
||||
tail = m.group(3)
|
||||
|
||||
if "g" in tail:
|
||||
count = 0 # unlimited
|
||||
else:
|
||||
count = 1
|
||||
|
||||
if "i" in tail:
|
||||
flags = re.IGNORECASE
|
||||
else:
|
||||
flags = re.RegexFlag(0)
|
||||
|
||||
return lambda s: re.sub(re.compile(pat, flags=flags), repl, s, count=count)
|
||||
|
||||
def comma_separated_list(values: str) -> list[str]:
|
||||
return values.split(",")
|
||||
|
||||
@ -97,9 +144,30 @@ class Args(Namespace):
|
||||
help=f"(deprecated) same as --no-{new_name}",
|
||||
)
|
||||
|
||||
p = ArgumentParser(description="Process a Cachegrind output file.")
|
||||
p = ArgumentParser(description="Process one or more Cachegrind output files.")
|
||||
|
||||
p.add_argument("--version", action="version", version="%(prog)s-@VERSION@")
|
||||
p.add_argument(
|
||||
"--diff",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="perform a diff between two Cachegrind output files",
|
||||
)
|
||||
p.add_argument(
|
||||
"--mod-filename",
|
||||
type=search_and_replace,
|
||||
metavar="REGEX",
|
||||
default=search_and_replace(None),
|
||||
help="a search-and-replace regex applied to filenames, e.g. "
|
||||
"`s/prog[0-9]/progN/`",
|
||||
)
|
||||
p.add_argument(
|
||||
"--mod-funcname",
|
||||
type=search_and_replace,
|
||||
metavar="REGEX",
|
||||
default=search_and_replace(None),
|
||||
help="like --mod-filename, but for function names",
|
||||
)
|
||||
p.add_argument(
|
||||
"--show",
|
||||
type=comma_separated_list,
|
||||
@ -143,12 +211,19 @@ class Args(Namespace):
|
||||
)
|
||||
p.add_argument(
|
||||
"cgout_filename",
|
||||
nargs=1,
|
||||
nargs="+",
|
||||
metavar="cachegrind-out-file",
|
||||
help="file produced by Cachegrind",
|
||||
)
|
||||
|
||||
return p.parse_args(namespace=Args())
|
||||
# `args0` name used to avoid shadowing the global `args`, which pylint
|
||||
# doesn't like.
|
||||
args0 = p.parse_args(namespace=Args())
|
||||
if args0.diff and len(args0.cgout_filename) != 2:
|
||||
p.print_usage(file=sys.stderr)
|
||||
die("argument --diff: requires exactly two Cachegrind output files")
|
||||
|
||||
return args0
|
||||
|
||||
|
||||
# Args are stored in a global for easy access.
|
||||
@ -178,7 +253,11 @@ class Events:
|
||||
# Like `sort_events`, but indices into `events`, rather than names.
|
||||
sort_indices: list[int]
|
||||
|
||||
def __init__(self, text: str) -> None:
|
||||
def __init__(self) -> None:
|
||||
# All fields are left uninitialized here, and set instead in `init`.
|
||||
pass
|
||||
|
||||
def init(self, text: str) -> None:
|
||||
self.events = text.split()
|
||||
self.num_events = len(self.events)
|
||||
|
||||
@ -245,9 +324,15 @@ def add_cc_to_cc(a_cc: Cc, b_cc: Cc) -> None:
|
||||
b_cc[i] += a_count
|
||||
|
||||
|
||||
# Subtract the counts in `a_cc` from `b_cc`.
|
||||
def sub_cc_from_cc(a_cc: Cc, b_cc: Cc) -> None:
|
||||
for i, a_count in enumerate(a_cc):
|
||||
b_cc[i] -= a_count
|
||||
|
||||
|
||||
# Unrolled version of `add_cc_to_cc`, for speed.
|
||||
def add_cc_to_ccs(
|
||||
a_cc: Cc, b_cc1: Cc, b_cc2: Cc, b_cc3: Cc, b_cc4: Cc, b_cc5: Cc
|
||||
a_cc: Cc, b_cc1: Cc, b_cc2: Cc, b_cc3: Cc, b_cc4: Cc, b_cc5: Cc, total_cc: Cc
|
||||
) -> None:
|
||||
for i, a_count in enumerate(a_cc):
|
||||
b_cc1[i] += a_count
|
||||
@ -255,6 +340,21 @@ def add_cc_to_ccs(
|
||||
b_cc3[i] += a_count
|
||||
b_cc4[i] += a_count
|
||||
b_cc5[i] += a_count
|
||||
total_cc[i] += a_count
|
||||
|
||||
|
||||
# Unrolled version of `sub_cc_from_cc`, for speed. Note that the last one,
|
||||
# `total_cc`, is added.
|
||||
def sub_cc_from_ccs(
|
||||
a_cc: Cc, b_cc1: Cc, b_cc2: Cc, b_cc3: Cc, b_cc4: Cc, b_cc5: Cc, total_cc: Cc
|
||||
) -> None:
|
||||
for i, a_count in enumerate(a_cc):
|
||||
b_cc1[i] -= a_count
|
||||
b_cc2[i] -= a_count
|
||||
b_cc3[i] -= a_count
|
||||
b_cc4[i] -= a_count
|
||||
b_cc5[i] -= a_count
|
||||
total_cc[i] += a_count
|
||||
|
||||
|
||||
# Update `min_cc` and `max_cc` with `self`.
|
||||
@ -266,59 +366,70 @@ def update_cc_extremes(self: Cc, min_cc: Cc, max_cc: Cc) -> None:
|
||||
min_cc[i] = count
|
||||
|
||||
|
||||
# A deep cost centre with a dict for the inner names and CCs.
|
||||
# Note: some abbrevations used below:
|
||||
# - Ofl/ofl: original filename, as mentioned in a cgout file.
|
||||
# - Ofn/ofn: original function name, as mentioned in a cgout file.
|
||||
# - Mfl/mfl: modified filename, the result of passing an Ofl through
|
||||
# `--mod-filename`.
|
||||
# - Mfn/mfn: modified function name, the result of passing an Ofn through
|
||||
# `--mod-funcname`.
|
||||
# - Mname/mname: modified name, used for what could be an Mfl or an Mfn.
|
||||
|
||||
# A deep cost centre with a dict for the inner mnames and CCs.
|
||||
class Dcc:
|
||||
outer_cc: Cc
|
||||
inner_dict_name_cc: DictNameCc
|
||||
inner_dict_mname_cc: DictMnameCc
|
||||
|
||||
def __init__(self, outer_cc: Cc, inner_dict_name_cc: DictNameCc) -> None:
|
||||
def __init__(self, outer_cc: Cc, inner_dict_mname_cc: DictMnameCc) -> None:
|
||||
self.outer_cc = outer_cc
|
||||
self.inner_dict_name_cc = inner_dict_name_cc
|
||||
self.inner_dict_mname_cc = inner_dict_mname_cc
|
||||
|
||||
|
||||
# A deep cost centre with a list for the inner names and CCs. Used during
|
||||
# A deep cost centre with a list for the inner mnames and CCs. Used during
|
||||
# filtering and sorting.
|
||||
class Lcc:
|
||||
outer_cc: Cc
|
||||
inner_list_name_cc: ListNameCc
|
||||
inner_list_mname_cc: ListMnameCc
|
||||
|
||||
def __init__(self, outer_cc: Cc, inner_list_name_cc: ListNameCc) -> None:
|
||||
def __init__(self, outer_cc: Cc, inner_list_mname_cc: ListMnameCc) -> None:
|
||||
self.outer_cc = outer_cc
|
||||
self.inner_list_name_cc = inner_list_name_cc
|
||||
self.inner_list_mname_cc = inner_list_mname_cc
|
||||
|
||||
|
||||
# Per-file/function CCs. The list version is used during filtering and sorting.
|
||||
DictNameCc = DefaultDict[str, Cc]
|
||||
ListNameCc = list[tuple[str, Cc]]
|
||||
# Per-Mfl/Mfn CCs. The list version is used during filtering and sorting.
|
||||
DictMnameCc = DefaultDict[str, Cc]
|
||||
ListMnameCc = list[tuple[str, Cc]]
|
||||
|
||||
# Per-file/function DCCs. The outer names are filenames and the inner names are
|
||||
# function names, or vice versa. The list version is used during filtering and
|
||||
# sorting.
|
||||
DictNameDcc = DefaultDict[str, Dcc]
|
||||
ListNameLcc = list[tuple[str, Lcc]]
|
||||
# Per-Mfl/Mfn DCCs. The outer Mnames are Mfls and the inner Mnames are Mfns, or
|
||||
# vice versa. The list version is used during filtering and sorting.
|
||||
DictMnameDcc = DefaultDict[str, Dcc]
|
||||
ListMnameLcc = list[tuple[str, Lcc]]
|
||||
|
||||
# Per-line CCs, organised by filename and line number.
|
||||
# Per-line CCs, organised by Mfl and line number.
|
||||
DictLineCc = DefaultDict[int, Cc]
|
||||
DictFlDictLineCc = DefaultDict[str, DictLineCc]
|
||||
DictMflDictLineCc = DefaultDict[str, DictLineCc]
|
||||
|
||||
# A dictionary tracking how Ofls get mapped to Mfls by `--mod-filename`. If
|
||||
# `--mod-filename` isn't used, each entry will be the identity mapping: ("foo"
|
||||
# -> set(["foo"])).
|
||||
DictMflOfls = DefaultDict[str, set[str]]
|
||||
|
||||
|
||||
def die(msg: str) -> NoReturn:
|
||||
print("cg_annotate: error:", msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def read_cgout_file() -> tuple[
|
||||
str,
|
||||
str,
|
||||
Events,
|
||||
DictNameDcc,
|
||||
DictNameDcc,
|
||||
DictFlDictLineCc,
|
||||
Cc,
|
||||
]:
|
||||
def read_cgout_file(
|
||||
cgout_filename: str,
|
||||
is_first_file: bool,
|
||||
descs: list[str],
|
||||
cmds: list[str],
|
||||
events: Events,
|
||||
dict_mfl_ofls: DictMflOfls,
|
||||
dict_mfl_dcc: DictMnameDcc,
|
||||
dict_mfn_dcc: DictMnameDcc,
|
||||
dict_mfl_dict_line_cc: DictMflDictLineCc,
|
||||
summary_cc: Cc,
|
||||
) -> None:
|
||||
# The file format is described in Cachegrind's manual.
|
||||
try:
|
||||
cgout_file = open(args.cgout_filename[0], "r", encoding="utf-8")
|
||||
cgout_file = open(cgout_filename, "r", encoding="utf-8")
|
||||
except OSError as err:
|
||||
die(f"{err}")
|
||||
|
||||
@ -340,40 +451,64 @@ def read_cgout_file() -> tuple[
|
||||
desc += m.group(1) + "\n"
|
||||
else:
|
||||
break
|
||||
descs.append(desc)
|
||||
|
||||
# Read "cmd:" line. (`line` is already set from the "desc:" loop.)
|
||||
if m := re.match(r"cmd:\s+(.*)", line):
|
||||
cmd = m.group(1)
|
||||
cmds.append(m.group(1))
|
||||
else:
|
||||
parse_die("missing a `command:` line")
|
||||
|
||||
# Read "events:" line.
|
||||
line = readline()
|
||||
if m := re.match(r"events:\s+(.*)", line):
|
||||
events = Events(m.group(1))
|
||||
if is_first_file:
|
||||
events.init(m.group(1))
|
||||
else:
|
||||
events2 = Events()
|
||||
events2.init(m.group(1))
|
||||
if events.events != events2.events:
|
||||
die("events in data files don't match")
|
||||
else:
|
||||
parse_die("missing an `events:` line")
|
||||
|
||||
def mk_empty_dict_line_cc() -> DictLineCc:
|
||||
return defaultdict(events.mk_empty_cc)
|
||||
|
||||
# The current filename and function name.
|
||||
fl = ""
|
||||
fn = ""
|
||||
# The current Mfl and Mfn.
|
||||
mfl = ""
|
||||
mfn = ""
|
||||
|
||||
# Different places where we accumulate CC data.
|
||||
dict_fl_dcc: DictNameDcc = defaultdict(events.mk_empty_dcc)
|
||||
dict_fn_dcc: DictNameDcc = defaultdict(events.mk_empty_dcc)
|
||||
dict_fl_dict_line_cc: DictFlDictLineCc = defaultdict(mk_empty_dict_line_cc)
|
||||
summary_cc = None
|
||||
# These values are passed in by reference and are modified by this
|
||||
# function. But they can't be properly initialized until the `events:`
|
||||
# line of the first file is read and the number of events is known. So
|
||||
# we initialize them in an invalid state in `main`, and then
|
||||
# reinitialize them properly here, before their first use.
|
||||
if is_first_file:
|
||||
dict_mfl_dcc.default_factory = events.mk_empty_dcc
|
||||
dict_mfn_dcc.default_factory = events.mk_empty_dcc
|
||||
dict_mfl_dict_line_cc.default_factory = mk_empty_dict_line_cc
|
||||
summary_cc.extend(events.mk_empty_cc())
|
||||
|
||||
# These are refs into the dicts above, used to avoid repeated lookups.
|
||||
# They are all overwritten before first use.
|
||||
fl_dcc = events.mk_empty_dcc()
|
||||
fn_dcc = events.mk_empty_dcc()
|
||||
fl_dcc_inner_fn_cc = events.mk_empty_cc()
|
||||
fn_dcc_inner_fl_cc = events.mk_empty_cc()
|
||||
mfl_dcc = events.mk_empty_dcc()
|
||||
mfn_dcc = events.mk_empty_dcc()
|
||||
mfl_dcc_inner_mfn_cc = events.mk_empty_cc()
|
||||
mfn_dcc_inner_mfl_cc = events.mk_empty_cc()
|
||||
dict_line_cc = mk_empty_dict_line_cc()
|
||||
total_cc = events.mk_empty_cc()
|
||||
|
||||
# When diffing, we negate the first cgout file's counts to effectively
|
||||
# achieve `cgout2 - cgout1`.
|
||||
if args.diff and is_first_file:
|
||||
combine_cc_with_cc = sub_cc_from_cc
|
||||
combine_cc_with_ccs = sub_cc_from_ccs
|
||||
else:
|
||||
combine_cc_with_cc = add_cc_to_cc
|
||||
combine_cc_with_ccs = add_cc_to_ccs
|
||||
|
||||
summary_cc_present = False
|
||||
|
||||
# Line matching is done in order of pattern frequency, for speed.
|
||||
while line := readline():
|
||||
@ -385,37 +520,54 @@ def read_cgout_file() -> tuple[
|
||||
except ValueError:
|
||||
parse_die("malformed or too many event counts")
|
||||
|
||||
# Record this CC at the file:function level, the function:file
|
||||
# level, and the file/line level.
|
||||
add_cc_to_ccs(
|
||||
# Record this CC at various levels.
|
||||
combine_cc_with_ccs(
|
||||
cc,
|
||||
fl_dcc.outer_cc,
|
||||
fn_dcc.outer_cc,
|
||||
fl_dcc_inner_fn_cc,
|
||||
fn_dcc_inner_fl_cc,
|
||||
mfl_dcc.outer_cc,
|
||||
mfn_dcc.outer_cc,
|
||||
mfl_dcc_inner_mfn_cc,
|
||||
mfn_dcc_inner_mfl_cc,
|
||||
dict_line_cc[line_num],
|
||||
total_cc,
|
||||
)
|
||||
|
||||
elif line.startswith("fn="):
|
||||
fn = line[3:-1]
|
||||
# `fl_dcc` is unchanged.
|
||||
fn_dcc = dict_fn_dcc[fn]
|
||||
fl_dcc_inner_fn_cc = fl_dcc.inner_dict_name_cc[fn]
|
||||
fn_dcc_inner_fl_cc = fn_dcc.inner_dict_name_cc[fl]
|
||||
ofn = line[3:-1]
|
||||
mfn = args.mod_funcname(ofn)
|
||||
# `mfl_dcc` is unchanged.
|
||||
mfn_dcc = dict_mfn_dcc[mfn]
|
||||
mfl_dcc_inner_mfn_cc = mfl_dcc.inner_dict_mname_cc[mfn]
|
||||
mfn_dcc_inner_mfl_cc = mfn_dcc.inner_dict_mname_cc[mfl]
|
||||
|
||||
elif line.startswith("fl="):
|
||||
fl = line[3:-1]
|
||||
ofl = line[3:-1]
|
||||
mfl = args.mod_filename(ofl)
|
||||
dict_mfl_ofls[mfl].add(ofl)
|
||||
# A `fn=` line should follow, overwriting the function name.
|
||||
fn = "<unspecified>"
|
||||
fl_dcc = dict_fl_dcc[fl]
|
||||
fn_dcc = dict_fn_dcc[fn]
|
||||
fl_dcc_inner_fn_cc = fl_dcc.inner_dict_name_cc[fn]
|
||||
fn_dcc_inner_fl_cc = fn_dcc.inner_dict_name_cc[fl]
|
||||
dict_line_cc = dict_fl_dict_line_cc[fl]
|
||||
mfn = "<unspecified>"
|
||||
mfl_dcc = dict_mfl_dcc[mfl]
|
||||
mfn_dcc = dict_mfn_dcc[mfn]
|
||||
mfl_dcc_inner_mfn_cc = mfl_dcc.inner_dict_mname_cc[mfn]
|
||||
mfn_dcc_inner_mfl_cc = mfn_dcc.inner_dict_mname_cc[mfl]
|
||||
dict_line_cc = dict_mfl_dict_line_cc[mfl]
|
||||
|
||||
elif m := re.match(r"summary:\s+(.*)", line):
|
||||
summary_cc_present = True
|
||||
try:
|
||||
summary_cc = events.mk_cc(m.group(1).split())
|
||||
this_summary_cc = events.mk_cc(m.group(1).split())
|
||||
combine_cc_with_cc(this_summary_cc, summary_cc)
|
||||
|
||||
# Check summary is correct. Note that `total_cc` doesn't
|
||||
# get negated for the first file in a diff, unlike the
|
||||
# other CCs, because it's only used here as a sanity check.
|
||||
if this_summary_cc != total_cc:
|
||||
msg = (
|
||||
"`summary:` line doesn't match computed total\n"
|
||||
f"- summary: {this_summary_cc}\n"
|
||||
f"- computed: {total_cc}"
|
||||
)
|
||||
parse_die(msg)
|
||||
|
||||
except ValueError:
|
||||
parse_die("malformed or too many event counts")
|
||||
|
||||
@ -427,31 +579,9 @@ def read_cgout_file() -> tuple[
|
||||
parse_die(f"malformed line: {line[:-1]}")
|
||||
|
||||
# Check if summary line was present.
|
||||
if not summary_cc:
|
||||
if not summary_cc_present:
|
||||
parse_die("missing `summary:` line, aborting")
|
||||
|
||||
# Check summary is correct. (Only using the outer CCs.)
|
||||
total_cc = events.mk_empty_cc()
|
||||
for dcc in dict_fl_dcc.values():
|
||||
add_cc_to_cc(dcc.outer_cc, total_cc)
|
||||
if summary_cc != total_cc:
|
||||
msg = (
|
||||
"`summary:` line doesn't match computed total\n"
|
||||
f"- summary: {summary_cc}\n"
|
||||
f"- total: {total_cc}"
|
||||
)
|
||||
parse_die(msg)
|
||||
|
||||
return (
|
||||
desc,
|
||||
cmd,
|
||||
events,
|
||||
dict_fl_dcc,
|
||||
dict_fn_dcc,
|
||||
dict_fl_dict_line_cc,
|
||||
summary_cc,
|
||||
)
|
||||
|
||||
|
||||
# The width of a column, in three parts.
|
||||
class Width:
|
||||
@ -487,7 +617,7 @@ class CcPrinter:
|
||||
# Text of a missing CC, which can be computed in advance.
|
||||
missing_cc_str: str
|
||||
|
||||
# Must call `init_ccs` or `init_list_name_lcc` after this.
|
||||
# Must call `init_ccs` or `init_list_mname_lcc` after this.
|
||||
def __init__(self, events: Events, summary_cc: Cc) -> None:
|
||||
self.events = events
|
||||
self.summary_cc = summary_cc
|
||||
@ -505,7 +635,7 @@ class CcPrinter:
|
||||
|
||||
self.init_widths(min_cc, max_cc, None, None)
|
||||
|
||||
def init_list_name_lcc(self, list_name_lcc: ListNameLcc) -> None:
|
||||
def init_list_mname_lcc(self, list_mname_lcc: ListMnameLcc) -> None:
|
||||
self.events_prefix = " "
|
||||
|
||||
cumul_cc = self.events.mk_empty_cc()
|
||||
@ -516,10 +646,10 @@ class CcPrinter:
|
||||
max_cc = self.events.mk_empty_cc()
|
||||
min_cumul_cc = self.events.mk_empty_cc()
|
||||
max_cumul_cc = self.events.mk_empty_cc()
|
||||
for _, lcc in list_name_lcc:
|
||||
for _, lcc in list_mname_lcc:
|
||||
# Consider both outer and inner CCs for `count` and `perc1`.
|
||||
update_cc_extremes(lcc.outer_cc, min_cc, max_cc)
|
||||
for _, inner_cc in lcc.inner_list_name_cc:
|
||||
for _, inner_cc in lcc.inner_list_mname_cc:
|
||||
update_cc_extremes(inner_cc, min_cc, max_cc)
|
||||
|
||||
# Consider only outer CCs for `perc2`.
|
||||
@ -604,24 +734,24 @@ class CcPrinter:
|
||||
|
||||
print(suffix)
|
||||
|
||||
def print_lcc(self, lcc: Lcc, outer_name: str, cumul_cc: Cc) -> None:
|
||||
print("> ", end="")
|
||||
def print_lcc(self, indent: str, lcc: Lcc, outer_mname: str, cumul_cc: Cc) -> None:
|
||||
print(indent, end="")
|
||||
if (
|
||||
len(lcc.inner_list_name_cc) == 1
|
||||
and lcc.outer_cc == lcc.inner_list_name_cc[0][1]
|
||||
len(lcc.inner_list_mname_cc) == 1
|
||||
and lcc.outer_cc == lcc.inner_list_mname_cc[0][1]
|
||||
):
|
||||
# There is only one inner CC, it met the threshold, and it is equal
|
||||
# to the outer CC. Print the inner CC and outer CC in a single
|
||||
# line, because they are the same.
|
||||
inner_name = lcc.inner_list_name_cc[0][0]
|
||||
self.print_cc(lcc.outer_cc, cumul_cc, f"{outer_name}:{inner_name}")
|
||||
inner_mname = lcc.inner_list_mname_cc[0][0]
|
||||
self.print_cc(lcc.outer_cc, cumul_cc, f"{outer_mname}:{inner_mname}")
|
||||
else:
|
||||
# There are multiple inner CCs, and at least one met the threshold.
|
||||
# Print the outer CC and then the inner CCs, indented.
|
||||
self.print_cc(lcc.outer_cc, cumul_cc, f"{outer_name}:")
|
||||
for inner_name, inner_cc in lcc.inner_list_name_cc:
|
||||
self.print_cc(lcc.outer_cc, cumul_cc, f"{outer_mname}:")
|
||||
for inner_mname, inner_cc in lcc.inner_list_mname_cc:
|
||||
print(" ", end="")
|
||||
self.print_cc(inner_cc, None, f" {inner_name}")
|
||||
self.print_cc(inner_cc, None, f" {inner_mname}")
|
||||
print()
|
||||
|
||||
# If `cc2` is `None`, it's a vanilla CC or inner CC. Otherwise, it's an
|
||||
@ -645,15 +775,42 @@ def print_fancy(text: str) -> None:
|
||||
print(fancy)
|
||||
|
||||
|
||||
def print_metadata(desc: str, cmd: str, events: Events) -> None:
|
||||
def print_metadata(descs: list[str], cmds: list[str], events: Events) -> None:
|
||||
print_fancy("Metadata")
|
||||
print(desc, end="")
|
||||
print("Command: ", cmd)
|
||||
print("Data file: ", args.cgout_filename[0])
|
||||
|
||||
def all_the_same(strs: list[str]) -> bool:
|
||||
for i in range(len(strs) - 1):
|
||||
if strs[i] != strs[i + 1]:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
print("Invocation: ", *sys.argv)
|
||||
|
||||
# When there are multiple descriptions, they are usually all the same. Only
|
||||
# print the description once in that case.
|
||||
if all_the_same(descs):
|
||||
print(descs[0], end="")
|
||||
else:
|
||||
for i, desc in enumerate(descs):
|
||||
print(f"Description {i+1}:")
|
||||
print(desc, end="")
|
||||
|
||||
# Commands are sometimes the same, sometimes not. Always print them
|
||||
# individually, but refer to the previous one when appropriate.
|
||||
if len(cmds) == 1:
|
||||
print("Command: ", cmds[0])
|
||||
else:
|
||||
for i, cmd in enumerate(cmds):
|
||||
if i > 0 and cmds[i - 1] == cmd:
|
||||
print(f"Command {i+1}: (same as Command {i})")
|
||||
else:
|
||||
print(f"Command {i+1}: ", cmd)
|
||||
|
||||
print("Events recorded: ", *events.events)
|
||||
print("Events shown: ", *events.show_events)
|
||||
print("Event sort order:", *events.sort_events)
|
||||
print("Threshold: ", args.threshold)
|
||||
print("Threshold: ", args.threshold, "%", sep="")
|
||||
print("Annotation: ", "on" if args.annotate else "off")
|
||||
print()
|
||||
|
||||
@ -668,8 +825,8 @@ def print_summary(events: Events, summary_cc: Cc) -> None:
|
||||
print()
|
||||
|
||||
|
||||
def print_name_summary(
|
||||
kind: str, events: Events, dict_name_dcc: DictNameDcc, summary_cc: Cc
|
||||
def print_mname_summary(
|
||||
kind: str, indent: str, events: Events, dict_mname_dcc: DictMnameDcc, summary_cc: Cc
|
||||
) -> set[str]:
|
||||
# The primary sort event is used for the threshold.
|
||||
threshold_index = events.sort_indices[0]
|
||||
@ -677,66 +834,67 @@ def print_name_summary(
|
||||
# Convert the threshold from a percentage to an event count.
|
||||
threshold = args.threshold * abs(summary_cc[threshold_index]) / 100
|
||||
|
||||
def meets_threshold(name_and_cc: tuple[str, Cc]) -> bool:
|
||||
cc = name_and_cc[1]
|
||||
def meets_threshold(mname_and_cc: tuple[str, Cc]) -> bool:
|
||||
cc = mname_and_cc[1]
|
||||
return abs(cc[threshold_index]) >= threshold
|
||||
|
||||
# Create a list with the outer CC counts in sort order, so that
|
||||
# left-to-right list comparison does the right thing. Plus the outer name
|
||||
# at the end for deterministic output when all the event counts are
|
||||
# identical in two CCs.
|
||||
def key_name_and_lcc(name_and_lcc: tuple[str, Lcc]) -> tuple[list[int], str]:
|
||||
(outer_name, lcc) = name_and_lcc
|
||||
def key_mname_and_lcc(mname_and_lcc: tuple[str, Lcc]) -> tuple[list[int], str]:
|
||||
(outer_mname, lcc) = mname_and_lcc
|
||||
return (
|
||||
[abs(lcc.outer_cc[i]) for i in events.sort_indices],
|
||||
outer_name,
|
||||
outer_mname,
|
||||
)
|
||||
|
||||
# Similar to `key_name_and_lcc`.
|
||||
def key_name_and_cc(name_and_cc: tuple[str, Cc]) -> tuple[list[int], str]:
|
||||
(name, cc) = name_and_cc
|
||||
return ([abs(cc[i]) for i in events.sort_indices], name)
|
||||
# Similar to `key_mname_and_lcc`.
|
||||
def key_mname_and_cc(mname_and_cc: tuple[str, Cc]) -> tuple[list[int], str]:
|
||||
(mname, cc) = mname_and_cc
|
||||
return ([abs(cc[i]) for i in events.sort_indices], mname)
|
||||
|
||||
# This is a `filter_map` operation, which Python doesn't directly support.
|
||||
list_name_lcc: ListNameLcc = []
|
||||
for outer_name, dcc in dict_name_dcc.items():
|
||||
list_mname_lcc: ListMnameLcc = []
|
||||
for outer_mname, dcc in dict_mname_dcc.items():
|
||||
# Filter out inner CCs for which the primary sort event count is below the
|
||||
# threshold, and sort the remainder.
|
||||
inner_list_name_cc = sorted(
|
||||
filter(meets_threshold, dcc.inner_dict_name_cc.items()),
|
||||
key=key_name_and_cc,
|
||||
inner_list_mname_cc = sorted(
|
||||
filter(meets_threshold, dcc.inner_dict_mname_cc.items()),
|
||||
key=key_mname_and_cc,
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
# If no inner CCs meet the threshold, ignore the entire DCC, even if
|
||||
# the outer CC meets the threshold.
|
||||
if len(inner_list_name_cc) == 0:
|
||||
if len(inner_list_mname_cc) == 0:
|
||||
continue
|
||||
|
||||
list_name_lcc.append((outer_name, Lcc(dcc.outer_cc, inner_list_name_cc)))
|
||||
list_mname_lcc.append((outer_mname, Lcc(dcc.outer_cc, inner_list_mname_cc)))
|
||||
|
||||
list_name_lcc = sorted(list_name_lcc, key=key_name_and_lcc, reverse=True)
|
||||
list_mname_lcc = sorted(list_mname_lcc, key=key_mname_and_lcc, reverse=True)
|
||||
|
||||
printer = CcPrinter(events, summary_cc)
|
||||
printer.init_list_name_lcc(list_name_lcc)
|
||||
printer.init_list_mname_lcc(list_mname_lcc)
|
||||
print_fancy(kind + " summary")
|
||||
printer.print_events(" " + kind.lower())
|
||||
print()
|
||||
|
||||
# Print LCCs.
|
||||
threshold_names = set([])
|
||||
threshold_mnames = set([])
|
||||
cumul_cc = events.mk_empty_cc()
|
||||
for name, lcc in list_name_lcc:
|
||||
for mname, lcc in list_mname_lcc:
|
||||
add_cc_to_cc(lcc.outer_cc, cumul_cc)
|
||||
printer.print_lcc(lcc, name, cumul_cc)
|
||||
threshold_names.add(name)
|
||||
printer.print_lcc(indent, lcc, mname, cumul_cc)
|
||||
threshold_mnames.add(mname)
|
||||
|
||||
return threshold_names
|
||||
return threshold_mnames
|
||||
|
||||
|
||||
class AnnotatedCcs:
|
||||
line_nums_known_cc: Cc
|
||||
line_nums_unknown_cc: Cc
|
||||
non_identical_cc: Cc
|
||||
unreadable_cc: Cc
|
||||
below_threshold_cc: Cc
|
||||
files_unknown_cc: Cc
|
||||
@ -744,6 +902,7 @@ class AnnotatedCcs:
|
||||
labels = [
|
||||
" annotated: files known & above threshold & readable, line numbers known",
|
||||
" annotated: files known & above threshold & readable, line numbers unknown",
|
||||
"unannotated: files known & above threshold & two or more non-identical",
|
||||
"unannotated: files known & above threshold & unreadable ",
|
||||
"unannotated: files known & below threshold",
|
||||
"unannotated: files unknown",
|
||||
@ -752,6 +911,7 @@ class AnnotatedCcs:
|
||||
def __init__(self, events: Events) -> None:
|
||||
self.line_nums_known_cc = events.mk_empty_cc()
|
||||
self.line_nums_unknown_cc = events.mk_empty_cc()
|
||||
self.non_identical_cc = events.mk_empty_cc()
|
||||
self.unreadable_cc = events.mk_empty_cc()
|
||||
self.below_threshold_cc = events.mk_empty_cc()
|
||||
self.files_unknown_cc = events.mk_empty_cc()
|
||||
@ -760,6 +920,7 @@ class AnnotatedCcs:
|
||||
return [
|
||||
self.line_nums_known_cc,
|
||||
self.line_nums_unknown_cc,
|
||||
self.non_identical_cc,
|
||||
self.unreadable_cc,
|
||||
self.below_threshold_cc,
|
||||
self.files_unknown_cc,
|
||||
@ -776,10 +937,11 @@ def mk_warning(msg: str) -> str:
|
||||
"""
|
||||
|
||||
|
||||
def warn_src_file_is_newer(src_filename: str, cgout_filename: str) -> None:
|
||||
def warn_ofls_are_all_newer(ofls: list[str], cgout_filename: str) -> None:
|
||||
s = "".join([f"@ - {ofl}\n" for ofl in ofls])
|
||||
msg = f"""\
|
||||
@ Source file '{src_filename}' is newer than data file '{cgout_filename}'.
|
||||
@ Annotations may not be correct.
|
||||
@ Original source files are all newer than data file '{cgout_filename}':
|
||||
{s}@ Annotations may not be correct.
|
||||
"""
|
||||
print(mk_warning(msg))
|
||||
|
||||
@ -798,10 +960,6 @@ def print_annotated_src_file(
|
||||
annotated_ccs: AnnotatedCcs,
|
||||
summary_cc: Cc,
|
||||
) -> None:
|
||||
# If the source file is more recent than the cgout file, issue warning.
|
||||
if os.stat(src_file.name).st_mtime_ns > os.stat(args.cgout_filename[0]).st_mtime_ns:
|
||||
warn_src_file_is_newer(src_file.name, args.cgout_filename[0])
|
||||
|
||||
printer = CcPrinter(events, summary_cc)
|
||||
printer.init_ccs(list(dict_line_cc.values()))
|
||||
# The starting fancy has already been printed by the caller.
|
||||
@ -884,52 +1042,101 @@ def print_annotated_src_file(
|
||||
print()
|
||||
|
||||
|
||||
# This (partially) consumes `dict_fl_dict_line_cc`.
|
||||
# This partially consumes `dict_mfl_dict_line_cc`, and fully consumes
|
||||
# `dict_mfl_olfs`.
|
||||
def print_annotated_src_files(
|
||||
ann_mfls: set[str],
|
||||
events: Events,
|
||||
ann_src_filenames: set[str],
|
||||
dict_fl_dict_line_cc: DictFlDictLineCc,
|
||||
dict_mfl_ofls: DictMflOfls,
|
||||
dict_mfl_dict_line_cc: DictMflDictLineCc,
|
||||
summary_cc: Cc,
|
||||
) -> AnnotatedCcs:
|
||||
annotated_ccs = AnnotatedCcs(events)
|
||||
|
||||
def add_dict_line_cc_to_cc(dict_line_cc: DictLineCc | None, accum_cc: Cc) -> None:
|
||||
if dict_line_cc:
|
||||
for line_cc in dict_line_cc.values():
|
||||
add_cc_to_cc(line_cc, accum_cc)
|
||||
def add_dict_line_cc_to_cc(dict_line_cc: DictLineCc, accum_cc: Cc) -> None:
|
||||
for line_cc in dict_line_cc.values():
|
||||
add_cc_to_cc(line_cc, accum_cc)
|
||||
|
||||
# Exclude the unknown ("???") file, which is unannotatable.
|
||||
ann_src_filenames.discard("???")
|
||||
dict_line_cc = dict_fl_dict_line_cc.pop("???", None)
|
||||
add_dict_line_cc_to_cc(dict_line_cc, annotated_ccs.files_unknown_cc)
|
||||
ann_mfls.discard("???")
|
||||
if "???" in dict_mfl_dict_line_cc:
|
||||
dict_line_cc = dict_mfl_dict_line_cc.pop("???")
|
||||
add_dict_line_cc_to_cc(dict_line_cc, annotated_ccs.files_unknown_cc)
|
||||
|
||||
def print_ann_fancy(src_filename: str) -> None:
|
||||
print_fancy(f"Annotated source file: {src_filename}")
|
||||
def print_ann_fancy(mfl: str) -> None:
|
||||
print_fancy(f"Annotated source file: {mfl}")
|
||||
|
||||
# This can raise an `OSError`.
|
||||
def all_ofl_contents_identical(ofls: list[str]) -> bool:
|
||||
for i in range(len(ofls) - 1):
|
||||
if not filecmp.cmp(ofls[i], ofls[i + 1], shallow=False):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
for mfl in sorted(ann_mfls):
|
||||
ofls = sorted(dict_mfl_ofls.pop(mfl))
|
||||
first_ofl = ofls[0]
|
||||
|
||||
for src_filename in sorted(ann_src_filenames):
|
||||
try:
|
||||
with open(src_filename, "r", encoding="utf-8") as src_file:
|
||||
dict_line_cc = dict_fl_dict_line_cc.pop(src_filename, None)
|
||||
assert dict_line_cc is not None
|
||||
print_ann_fancy(src_filename)
|
||||
print_annotated_src_file(
|
||||
events,
|
||||
dict_line_cc,
|
||||
src_file,
|
||||
annotated_ccs,
|
||||
summary_cc,
|
||||
if all_ofl_contents_identical(ofls):
|
||||
# All the Ofls that map to this Mfl are identical, which means we
|
||||
# can annotate, and it doesn't matter which Ofl we use.
|
||||
with open(first_ofl, "r", encoding="utf-8") as src_file:
|
||||
dict_line_cc = dict_mfl_dict_line_cc.pop(mfl)
|
||||
print_ann_fancy(mfl)
|
||||
|
||||
# Because all the Ofls are identical, we can treat their
|
||||
# mtimes as if they are all as early as the earliest one.
|
||||
# Therefore, we warn only if the earliest source file is
|
||||
# more recent than the cgout file.
|
||||
min_ofl_st_mtime_ns = min(
|
||||
[os.stat(ofl).st_mtime_ns for ofl in ofls]
|
||||
)
|
||||
|
||||
for cgout_filename in args.cgout_filename:
|
||||
if min_ofl_st_mtime_ns > os.stat(cgout_filename).st_mtime_ns:
|
||||
warn_ofls_are_all_newer(ofls, cgout_filename)
|
||||
|
||||
print_annotated_src_file(
|
||||
events,
|
||||
dict_line_cc,
|
||||
src_file,
|
||||
annotated_ccs,
|
||||
summary_cc,
|
||||
)
|
||||
else:
|
||||
dict_line_cc = dict_mfl_dict_line_cc.pop(mfl)
|
||||
add_dict_line_cc_to_cc(dict_line_cc, annotated_ccs.non_identical_cc)
|
||||
|
||||
# We could potentially do better here.
|
||||
# - Annotate until the first line where the src files diverge.
|
||||
# - Also, heuristic resyncing, e.g. by looking for matching
|
||||
# lines (of sufficient complexity) after a divergence.
|
||||
print_ann_fancy(mfl)
|
||||
print(
|
||||
"Unannotated because two or more of these original files are not "
|
||||
"identical:",
|
||||
*ofls,
|
||||
sep="\n- ",
|
||||
)
|
||||
print()
|
||||
except OSError:
|
||||
dict_line_cc = dict_fl_dict_line_cc.pop(src_filename, None)
|
||||
dict_line_cc = dict_mfl_dict_line_cc.pop(mfl)
|
||||
add_dict_line_cc_to_cc(dict_line_cc, annotated_ccs.unreadable_cc)
|
||||
|
||||
print_ann_fancy(src_filename)
|
||||
print("This file was unreadable")
|
||||
print_ann_fancy(mfl)
|
||||
print(
|
||||
"Unannotated because one or more of these original files are "
|
||||
"unreadable:",
|
||||
*ofls,
|
||||
sep="\n- ",
|
||||
)
|
||||
print()
|
||||
|
||||
# Sum the CCs remaining in `dict_fl_dict_line_cc`, which are all in files
|
||||
# Sum the CCs remaining in `dict_mfl_dict_line_cc`, which are all in files
|
||||
# below the threshold.
|
||||
for dict_line_cc in dict_fl_dict_line_cc.values():
|
||||
for dict_line_cc in dict_mfl_dict_line_cc.values():
|
||||
add_dict_line_cc_to_cc(dict_line_cc, annotated_ccs.below_threshold_cc)
|
||||
|
||||
return annotated_ccs
|
||||
@ -965,26 +1172,46 @@ def print_annotation_summary(
|
||||
|
||||
|
||||
def main() -> None:
|
||||
(
|
||||
desc,
|
||||
cmd,
|
||||
events,
|
||||
dict_fl_dcc,
|
||||
dict_fn_dcc,
|
||||
dict_fl_dict_line_cc,
|
||||
summary_cc,
|
||||
) = read_cgout_file()
|
||||
# Metadata, initialized to empty states.
|
||||
descs: list[str] = []
|
||||
cmds: list[str] = []
|
||||
events = Events()
|
||||
|
||||
# For tracking original filenames to modified filenames.
|
||||
dict_mfl_ofls: DictMflOfls = defaultdict(set)
|
||||
|
||||
# Different places where we accumulate CC data. Initialized to invalid
|
||||
# states prior to the number of events being known.
|
||||
dict_mfl_dcc: DictMnameDcc = defaultdict(None)
|
||||
dict_mfn_dcc: DictMnameDcc = defaultdict(None)
|
||||
dict_mfl_dict_line_cc: DictMflDictLineCc = defaultdict(None)
|
||||
summary_cc: Cc = []
|
||||
|
||||
for n, filename in enumerate(args.cgout_filename):
|
||||
is_first_file = n == 0
|
||||
read_cgout_file(
|
||||
filename,
|
||||
is_first_file,
|
||||
descs,
|
||||
cmds,
|
||||
events,
|
||||
dict_mfl_ofls,
|
||||
dict_mfl_dcc,
|
||||
dict_mfn_dcc,
|
||||
dict_mfl_dict_line_cc,
|
||||
summary_cc,
|
||||
)
|
||||
|
||||
# Each of the following calls prints a section of the output.
|
||||
print_metadata(desc, cmd, events)
|
||||
print_metadata(descs, cmds, events)
|
||||
print_summary(events, summary_cc)
|
||||
ann_src_filenames = print_name_summary(
|
||||
"File:function", events, dict_fl_dcc, summary_cc
|
||||
ann_mfls = print_mname_summary(
|
||||
"File:function", "< ", events, dict_mfl_dcc, summary_cc
|
||||
)
|
||||
print_name_summary("Function:file", events, dict_fn_dcc, summary_cc)
|
||||
print_mname_summary("Function:file", "> ", events, dict_mfn_dcc, summary_cc)
|
||||
if args.annotate:
|
||||
annotated_ccs = print_annotated_src_files(
|
||||
events, ann_src_filenames, dict_fl_dict_line_cc, summary_cc
|
||||
ann_mfls, events, dict_mfl_ofls, dict_mfl_dict_line_cc, summary_cc
|
||||
)
|
||||
|
||||
print_annotation_summary(events, annotated_ccs, summary_cc)
|
||||
|
||||
@ -66,7 +66,7 @@ class Args(Namespace):
|
||||
if regex is None:
|
||||
return lambda s: s
|
||||
|
||||
# Extract the parts of a `s/old/new/tail` regex. `(?<!\\)/` is an
|
||||
# Extract the parts of an `s/old/new/tail` regex. `(?<!\\)/` is an
|
||||
# example of negative lookbehind. It means "match a forward slash
|
||||
# unless preceded by a backslash".
|
||||
m = re.match(r"s/(.*)(?<!\\)/(.*)(?<!\\)/(g|i|gi|ig|)$", regex)
|
||||
@ -74,7 +74,7 @@ class Args(Namespace):
|
||||
raise ValueError
|
||||
|
||||
# Forward slashes must be escaped in an `s/old/new/` expression,
|
||||
# but we then must unescape them before using them with `re.sub`
|
||||
# but we then must unescape them before using them with `re.sub`.
|
||||
pat = m.group(1).replace(r"\/", r"/")
|
||||
repl = m.group(2).replace(r"\/", r"/")
|
||||
tail = m.group(3)
|
||||
@ -91,7 +91,11 @@ class Args(Namespace):
|
||||
|
||||
return lambda s: re.sub(re.compile(pat, flags=flags), repl, s, count=count)
|
||||
|
||||
p = ArgumentParser(description="Diff two Cachegrind output files.")
|
||||
desc = (
|
||||
"Diff two Cachegrind output files. Deprecated; use "
|
||||
"`cg_annotate --diff` instead."
|
||||
)
|
||||
p = ArgumentParser(description=desc)
|
||||
|
||||
p.add_argument("--version", action="version", version="%(prog)s-@VERSION@")
|
||||
|
||||
@ -304,8 +308,8 @@ def main() -> None:
|
||||
(cmd1, events1, dict_flfn_cc1, summary_cc1) = read_cgout_file(filename1)
|
||||
(cmd2, events2, dict_flfn_cc2, summary_cc2) = read_cgout_file(filename2)
|
||||
|
||||
if events1.num_events != events2.num_events:
|
||||
die("events don't match")
|
||||
if events1.events != events2.events:
|
||||
die("events in data files don't match")
|
||||
|
||||
# Subtract file 1's CCs from file 2's CCs, at the Flfn level.
|
||||
for flfn, flfn_cc1 in dict_flfn_cc1.items():
|
||||
|
||||
@ -51,7 +51,11 @@ class Args(Namespace):
|
||||
|
||||
@staticmethod
|
||||
def parse() -> Args:
|
||||
p = ArgumentParser(description="Merge multiple Cachegrind output files.")
|
||||
desc = (
|
||||
"Merge multiple Cachegrind output files. Deprecated; use "
|
||||
"`cg_annotate` with multiple Cachegrind output files instead."
|
||||
)
|
||||
p = ArgumentParser(description=desc)
|
||||
|
||||
p.add_argument("--version", action="version", version="%(prog)s-@VERSION@")
|
||||
|
||||
@ -272,8 +276,8 @@ def main() -> None:
|
||||
events1 = events_n
|
||||
else:
|
||||
assert events1
|
||||
if events1.num_events != events_n.num_events:
|
||||
die("events don't match")
|
||||
if events1.events != events_n.events:
|
||||
die("events in data files don't match")
|
||||
|
||||
def write_output(f: TextIO) -> None:
|
||||
# These assertions hold because the loop above executes at least twice.
|
||||
|
||||
@ -16,9 +16,17 @@ EXTRA_DIST = \
|
||||
ann-diff1.post.exp ann-diff1.stderr.exp ann-diff1.vgtest \
|
||||
ann-diff2.post.exp ann-diff2.stderr.exp ann-diff2.vgtest \
|
||||
ann-diff2a.cgout ann-diff2b.cgout \
|
||||
ann-diff2-aux/ann-diff2-basic.rs \
|
||||
ann-diff3.post.exp ann-diff3.stderr.exp ann-diff3.vgtest \
|
||||
ann-diff4.post.exp ann-diff4.stderr.exp ann-diff4.vgtest \
|
||||
ann-diff4a.cgout ann-diff4b.cgout \
|
||||
ann-diff4a-aux/w.rs ann-diff4a-aux/x.rs ann-diff4a-aux/y.rs \
|
||||
ann-diff4a-aux/z.rs \
|
||||
ann-diff4b-aux/w.rs ann-diff4b-aux/x.rs ann-diff4b-aux/y.rs \
|
||||
ann-merge1.post.exp ann-merge1.stderr.exp ann-merge1.vgtest \
|
||||
ann-merge1a.cgout ann-merge1b.cgout \
|
||||
ann-merge-x.rs ann-merge-y.rs \
|
||||
ann-merge2.post.exp ann-merge2.stderr.exp ann-merge2.vgtest \
|
||||
ann1a.post.exp ann1a.stderr.exp ann1a.vgtest ann1.cgout \
|
||||
ann1b.post.exp ann1b.stderr.exp ann1b.vgtest ann1b.cgout \
|
||||
ann2.post.exp ann2.stderr.exp ann2.vgtest ann2.cgout \
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate --mod-filename=s/a.c/A.c/ --mod-funcname s/MAIN/Main/ ann-diff1.cgout
|
||||
Files compared: ann1.cgout; ann1b.cgout
|
||||
Command: ./a.out; ./a.out
|
||||
Data file: ann-diff1.cgout
|
||||
Events recorded: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
|
||||
Events shown: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
|
||||
Event sort order: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
|
||||
Threshold: 0.1
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -22,17 +22,17 @@ Ir________________ I1mr ILmr Dr_________________ D1mr DLmr Dw D1mw DLmw
|
||||
--------------------------------------------------------------------------------
|
||||
Ir________________________ I1mr________ ILmr________ Dr_________________________ D1mr________ DLmr________ Dw__________ D1mw________ DLmw________ file:function
|
||||
|
||||
> 5,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) -2,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) a.c:MAIN
|
||||
< 5,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) -2,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) A.c:Main
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Function:file summary
|
||||
--------------------------------------------------------------------------------
|
||||
Ir________________________ I1mr________ ILmr________ Dr_________________________ D1mr________ DLmr________ Dw__________ D1mw________ DLmw________ function:file
|
||||
|
||||
> 5,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) -2,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) MAIN:a.c
|
||||
> 5,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) -2,000,000 (100.0%, 100.0%) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) 0 (n/a, n/a) Main:A.c
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: a.c
|
||||
-- Annotated source file: A.c
|
||||
--------------------------------------------------------------------------------
|
||||
Ir________________ I1mr ILmr Dr_________________ D1mr DLmr Dw D1mw DLmw
|
||||
|
||||
@ -45,6 +45,7 @@ Ir________________ I1mr ILmr Dr_________________ D1mr DLmr Dw D1mw DLmw
|
||||
|
||||
0 0 0 0 0 0 0 0 0 annotated: files known & above threshold & readable, line numbers known
|
||||
5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 0 0 0 0 0 0 0 0 unannotated: files known & above threshold & two or more non-identical
|
||||
0 0 0 0 0 0 0 0 0 unannotated: files known & above threshold & unreadable
|
||||
0 0 0 0 0 0 0 0 0 unannotated: files known & below threshold
|
||||
0 0 0 0 0 0 0 0 0 unannotated: files unknown
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the `ann{1,1b}.cgout` test files.
|
||||
# the post-processing of the cgout files.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
post: python3 ../cg_diff --mod-funcname="s/main/MAIN/" ann1.cgout ann1b.cgout > ann-diff1.cgout && python3 ../cg_annotate ann-diff1.cgout
|
||||
cleanup: rm ann-diff1.cgout
|
||||
|
||||
post: python3 ../cg_diff --mod-funcname="s/main/MAIN/" ann1.cgout ann1b.cgout > ann-diff1.cgout && python3 ../cg_annotate --mod-filename="s/a.c/A.c/" --mod-funcname s/MAIN/Main/ ann-diff1.cgout
|
||||
|
||||
cleanup: rm cachegrind.out ann-diff1.cgout
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate ann-diff2c.cgout
|
||||
Files compared: ann-diff2a.cgout; ann-diff2b.cgout
|
||||
Command: cmd1; cmd2
|
||||
Data file: ann-diff2c.cgout
|
||||
Events recorded: One Two
|
||||
Events shown: One Two
|
||||
Event sort order: One Two
|
||||
Threshold: 0.1
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -22,7 +22,7 @@ One___________ Two___________
|
||||
--------------------------------------------------------------------------------
|
||||
One___________________ Two___________________ file:function
|
||||
|
||||
> 2,100 (100.0%, 100.0%) 1,900 (100.0%, 100.0%) aux/ann-diff2-basic.rs:
|
||||
< 2,100 (100.0%, 100.0%) 1,900 (100.0%, 100.0%) aux/ann-diff2-basic.rs:
|
||||
1,000 (47.6%) 1,000 (52.6%) groffN
|
||||
1,000 (47.6%) 1,000 (52.6%) fN_ffN_fooN_F4_g5
|
||||
100 (4.8%) -100 (-5.3%) basic1
|
||||
@ -41,7 +41,8 @@ One___________ Two___________
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: aux/ann-diff2-basic.rs
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- aux/ann-diff2-basic.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotation summary
|
||||
@ -50,6 +51,7 @@ One___________ Two___________
|
||||
|
||||
0 0 annotated: files known & above threshold & readable, line numbers known
|
||||
0 0 annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 0 unannotated: files known & above threshold & two or more non-identical
|
||||
2,100 (100.0%) 1,900 (100.0%) unannotated: files known & above threshold & unreadable
|
||||
0 0 unannotated: files known & below threshold
|
||||
0 0 unannotated: files unknown
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the `ann-diff2{a,b}.cgout` test files.
|
||||
# the post-processing of the cgout files.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
post: python3 ../cg_diff --mod-filename="s/.*aux\//aux\//i" --mod-funcname="s/(f[a-z]*)[0-9]/\1N/g" ann-diff2a.cgout ann-diff2b.cgout > ann-diff2c.cgout && python3 ../cg_annotate ann-diff2c.cgout
|
||||
cleanup: rm ann-diff2c.cgout
|
||||
|
||||
cleanup: rm cachegrind.out ann-diff2c.cgout
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
desc: Description for ann-diff2a.cgout
|
||||
desc: Description for ann-diff2b.cgout
|
||||
cmd: cmd2
|
||||
events: One Two
|
||||
|
||||
|
||||
63
cachegrind/tests/ann-diff3.post.exp
Normal file
63
cachegrind/tests/ann-diff3.post.exp
Normal file
@ -0,0 +1,63 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate --diff --mod-filename=s/.*aux\//aux\//i --mod-funcname=s/(f[a-z]*)[0-9]/\1N/g ann-diff2a.cgout ann-diff2b.cgout
|
||||
Description 1:
|
||||
Description for ann-diff2a.cgout
|
||||
Description 2:
|
||||
Description for ann-diff2b.cgout
|
||||
Command 1: cmd1
|
||||
Command 2: cmd2
|
||||
Events recorded: One Two
|
||||
Events shown: One Two
|
||||
Event sort order: One Two
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Summary
|
||||
--------------------------------------------------------------------------------
|
||||
One___________ Two___________
|
||||
|
||||
2,100 (100.0%) 1,900 (100.0%) PROGRAM TOTALS
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- File:function summary
|
||||
--------------------------------------------------------------------------------
|
||||
One___________________ Two___________________ file:function
|
||||
|
||||
< 2,100 (100.0%, 100.0%) 1,900 (100.0%, 100.0%) aux/ann-diff2-basic.rs:
|
||||
1,000 (47.6%) 1,000 (52.6%) groffN
|
||||
1,000 (47.6%) 1,000 (52.6%) fN_ffN_fooN_F4_g5
|
||||
100 (4.8%) -100 (-5.3%) basic1
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Function:file summary
|
||||
--------------------------------------------------------------------------------
|
||||
One__________________ Two__________________ function:file
|
||||
|
||||
> 1,000 (47.6%, 47.6%) 1,000 (52.6%, 52.6%) groffN:aux/ann-diff2-basic.rs
|
||||
|
||||
> 1,000 (47.6%, 95.2%) 1,000 (52.6%, 105.3%) fN_ffN_fooN_F4_g5:aux/ann-diff2-basic.rs
|
||||
|
||||
> 100 (4.8%, 100.0%) -100 (-5.3%, 100.0%) basic1:aux/ann-diff2-basic.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: aux/ann-diff2-basic.rs
|
||||
--------------------------------------------------------------------------------
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- ann2-diff-AUX/ann-diff2-basic.rs
|
||||
- ann2-diff-Aux/ann-diff2-basic.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotation summary
|
||||
--------------------------------------------------------------------------------
|
||||
One___________ Two___________
|
||||
|
||||
0 0 annotated: files known & above threshold & readable, line numbers known
|
||||
0 0 annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 0 unannotated: files known & above threshold & two or more non-identical
|
||||
2,100 (100.0%) 1,900 (100.0%) unannotated: files known & above threshold & unreadable
|
||||
0 0 unannotated: files known & below threshold
|
||||
0 0 unannotated: files unknown
|
||||
|
||||
3
cachegrind/tests/ann-diff3.stderr.exp
Normal file
3
cachegrind/tests/ann-diff3.stderr.exp
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
I refs:
|
||||
8
cachegrind/tests/ann-diff3.vgtest
Normal file
8
cachegrind/tests/ann-diff3.vgtest
Normal file
@ -0,0 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the cgout files.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
post: python3 ../cg_annotate --diff --mod-filename="s/.*aux\//aux\//i" --mod-funcname="s/(f[a-z]*)[0-9]/\1N/g" ann-diff2a.cgout ann-diff2b.cgout
|
||||
|
||||
cleanup: rm cachegrind.out
|
||||
125
cachegrind/tests/ann-diff4.post.exp
Normal file
125
cachegrind/tests/ann-diff4.post.exp
Normal file
@ -0,0 +1,125 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate ann-diff4a.cgout ann-diff4b.cgout --mod-filename=s/ann-diff4[ab]/ann-diff4N/ --diff
|
||||
DescA
|
||||
DescB
|
||||
DescC
|
||||
Command 1: my-command
|
||||
Command 2: (same as Command 1)
|
||||
Events recorded: Ir
|
||||
Events shown: Ir
|
||||
Event sort order: Ir
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Summary
|
||||
--------------------------------------------------------------------------------
|
||||
Ir__________
|
||||
|
||||
700 (100.0%) PROGRAM TOTALS
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- File:function summary
|
||||
--------------------------------------------------------------------------------
|
||||
Ir___________________ file:function
|
||||
|
||||
< 600 (85.7%, 85.7%) ann-diff4N-aux/y.rs:b
|
||||
|
||||
< 200 (28.6%, 114.3%) ann-diff4N-aux/x.rs:a
|
||||
|
||||
< -200 (-28.6%, 85.7%) ann-diff4N-aux/w.rs:a
|
||||
|
||||
< 200 (28.6%, 114.3%) ann-diff4N-aux/no-such-file.rs:f
|
||||
|
||||
< -100 (-14.3%, 100.0%) ann-diff4N-aux/z.rs:c
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Function:file summary
|
||||
--------------------------------------------------------------------------------
|
||||
Ir___________________ function:file
|
||||
|
||||
> 600 (85.7%, 85.7%) b:ann-diff4N-aux/y.rs
|
||||
|
||||
> 200 (28.6%, 114.3%) f:ann-diff4N-aux/no-such-file.rs
|
||||
|
||||
> -100 (-14.3%, 100.0%) c:ann-diff4N-aux/z.rs
|
||||
|
||||
> 0 (0.0%, 100.0%) a:
|
||||
200 (28.6%) ann-diff4N-aux/x.rs
|
||||
-200 (-28.6%) ann-diff4N-aux/w.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-diff4N-aux/no-such-file.rs
|
||||
--------------------------------------------------------------------------------
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- ann-diff4a-aux/no-such-file.rs
|
||||
- ann-diff4b-aux/no-such-file.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-diff4N-aux/w.rs
|
||||
--------------------------------------------------------------------------------
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ Original source files are all newer than data file 'ann-diff4a.cgout':
|
||||
@ - ann-diff4a-aux/w.rs
|
||||
@ - ann-diff4b-aux/w.rs
|
||||
@ Annotations may not be correct.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ Original source files are all newer than data file 'ann-diff4b.cgout':
|
||||
@ - ann-diff4a-aux/w.rs
|
||||
@ - ann-diff4b-aux/w.rs
|
||||
@ Annotations may not be correct.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
Ir___________
|
||||
|
||||
-200 (-28.6%) one
|
||||
. two
|
||||
. three
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-diff4N-aux/x.rs
|
||||
--------------------------------------------------------------------------------
|
||||
Ir___________
|
||||
|
||||
100 (14.3%) <unknown (line 0)>
|
||||
|
||||
-200 (-28.6%) one
|
||||
300 (42.9%) two
|
||||
. three
|
||||
. four
|
||||
. five
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-diff4N-aux/y.rs
|
||||
--------------------------------------------------------------------------------
|
||||
Unannotated because two or more of these original files are not identical:
|
||||
- ann-diff4a-aux/y.rs
|
||||
- ann-diff4b-aux/y.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-diff4N-aux/z.rs
|
||||
--------------------------------------------------------------------------------
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- ann-diff4a-aux/z.rs
|
||||
- ann-diff4b-aux/z.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotation summary
|
||||
--------------------------------------------------------------------------------
|
||||
Ir___________
|
||||
|
||||
-100 (-14.3%) annotated: files known & above threshold & readable, line numbers known
|
||||
100 (14.3%) annotated: files known & above threshold & readable, line numbers unknown
|
||||
600 (85.7%) unannotated: files known & above threshold & two or more non-identical
|
||||
100 (14.3%) unannotated: files known & above threshold & unreadable
|
||||
0 unannotated: files known & below threshold
|
||||
0 unannotated: files unknown
|
||||
|
||||
3
cachegrind/tests/ann-diff4.stderr.exp
Normal file
3
cachegrind/tests/ann-diff4.stderr.exp
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
I refs:
|
||||
14
cachegrind/tests/ann-diff4.vgtest
Normal file
14
cachegrind/tests/ann-diff4.vgtest
Normal file
@ -0,0 +1,14 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the cgout files.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
# The `sleep` is to ensure the mtime of the second touched file is greater than
|
||||
# the mtime of the first touched file.
|
||||
#
|
||||
# Because only one of the two x.rs files is newer than the cgout files, we don't
|
||||
# get an mtime warning on x.rs. But both w.rs files are new than the cgout
|
||||
# files, so we do get an mtime warning on w.rs.
|
||||
post: touch ann-diff4a.cgout ann-diff4b.cgout && sleep 0.1 && touch ann-diff4a-aux/x.rs ann-diff4a-aux/w.rs ann-diff4b-aux/w.rs && python3 ../cg_annotate ann-diff4a.cgout ann-diff4b.cgout --mod-filename=s/ann-diff4[ab]/ann-diff4N/ --diff
|
||||
|
||||
cleanup: rm cachegrind.out
|
||||
3
cachegrind/tests/ann-diff4a-aux/w.rs
Normal file
3
cachegrind/tests/ann-diff4a-aux/w.rs
Normal file
@ -0,0 +1,3 @@
|
||||
one
|
||||
two
|
||||
three
|
||||
5
cachegrind/tests/ann-diff4a-aux/x.rs
Normal file
5
cachegrind/tests/ann-diff4a-aux/x.rs
Normal file
@ -0,0 +1,5 @@
|
||||
one
|
||||
two
|
||||
three
|
||||
four
|
||||
five
|
||||
5
cachegrind/tests/ann-diff4a-aux/y.rs
Normal file
5
cachegrind/tests/ann-diff4a-aux/y.rs
Normal file
@ -0,0 +1,5 @@
|
||||
ONE
|
||||
TWO
|
||||
THREE
|
||||
FOUR
|
||||
FIVE
|
||||
3
cachegrind/tests/ann-diff4a-aux/z.rs
Normal file
3
cachegrind/tests/ann-diff4a-aux/z.rs
Normal file
@ -0,0 +1,3 @@
|
||||
one
|
||||
two
|
||||
three
|
||||
30
cachegrind/tests/ann-diff4a.cgout
Normal file
30
cachegrind/tests/ann-diff4a.cgout
Normal file
@ -0,0 +1,30 @@
|
||||
desc: DescA
|
||||
desc: DescB
|
||||
desc: DescC
|
||||
cmd: my-command
|
||||
events: Ir
|
||||
|
||||
fl=ann-diff4a-aux/w.rs
|
||||
fn=a
|
||||
1 1000
|
||||
|
||||
fl=ann-diff4a-aux/x.rs
|
||||
fn=a
|
||||
0 1000
|
||||
1 1000
|
||||
2 1000
|
||||
|
||||
fl=ann-diff4a-aux/y.rs
|
||||
fn=b
|
||||
4 1000
|
||||
5 1000
|
||||
|
||||
fl=ann-diff4a-aux/z.rs
|
||||
fn=c
|
||||
1 1000
|
||||
|
||||
fl=ann-diff4a-aux/no-such-file.rs
|
||||
fn=f
|
||||
0 100
|
||||
|
||||
summary: 7100
|
||||
5
cachegrind/tests/ann-diff4b-aux/x.rs
Normal file
5
cachegrind/tests/ann-diff4b-aux/x.rs
Normal file
@ -0,0 +1,5 @@
|
||||
one
|
||||
two
|
||||
three
|
||||
four
|
||||
five
|
||||
6
cachegrind/tests/ann-diff4b-aux/y.rs
Normal file
6
cachegrind/tests/ann-diff4b-aux/y.rs
Normal file
@ -0,0 +1,6 @@
|
||||
ONE
|
||||
TWO
|
||||
THREE
|
||||
FOUR
|
||||
FIVE
|
||||
SIX
|
||||
31
cachegrind/tests/ann-diff4b.cgout
Normal file
31
cachegrind/tests/ann-diff4b.cgout
Normal file
@ -0,0 +1,31 @@
|
||||
desc: DescA
|
||||
desc: DescB
|
||||
desc: DescC
|
||||
cmd: my-command
|
||||
events: Ir
|
||||
|
||||
fl=ann-diff4b-aux/w.rs
|
||||
fn=a
|
||||
1 800
|
||||
|
||||
fl=ann-diff4b-aux/x.rs
|
||||
fn=a
|
||||
0 1100
|
||||
1 800
|
||||
2 1300
|
||||
|
||||
fl=ann-diff4b-aux/y.rs
|
||||
fn=b
|
||||
4 1200
|
||||
5 900
|
||||
6 500
|
||||
|
||||
fl=ann-diff4b-aux/z.rs
|
||||
fn=c
|
||||
1 900
|
||||
|
||||
fl=ann-diff4b-aux/no-such-file.rs
|
||||
fn=f
|
||||
0 300
|
||||
|
||||
summary: 7800
|
||||
@ -1,14 +1,14 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate ann-merge1c.cgout
|
||||
Description 1a
|
||||
Description 1b
|
||||
Command: Command 1
|
||||
Data file: ann-merge1c.cgout
|
||||
Events recorded: A
|
||||
Events shown: A
|
||||
Event sort order: A
|
||||
Threshold: 0.1
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -23,12 +23,12 @@ A__________
|
||||
--------------------------------------------------------------------------------
|
||||
A_________________ file:function
|
||||
|
||||
> 70 (81.4%, 81.4%) ann-merge-x.rs:
|
||||
< 70 (81.4%, 81.4%) ann-merge-x.rs:
|
||||
40 (46.5%) x1
|
||||
20 (23.3%) x3
|
||||
10 (11.6%) x2
|
||||
|
||||
> 16 (18.6%, 100.0%) ann-merge-y.rs:y1
|
||||
< 16 (18.6%, 100.0%) ann-merge-y.rs:y1
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Function:file summary
|
||||
@ -73,6 +73,7 @@ A__________
|
||||
|
||||
86 (100.0%) annotated: files known & above threshold & readable, line numbers known
|
||||
0 annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 unannotated: files known & above threshold & two or more non-identical
|
||||
0 unannotated: files known & above threshold & unreadable
|
||||
0 unannotated: files known & below threshold
|
||||
0 unannotated: files unknown
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the `ann{1,1b}.cgout` test files.
|
||||
# the post-processing of the cgout files.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
post: python3 ../cg_merge ann-merge1a.cgout ann-merge1b.cgout > ann-merge1c.cgout && python3 ../cg_annotate ann-merge1c.cgout
|
||||
cleanup: rm ann-merge1c.cgout
|
||||
|
||||
post: python3 ../cg_merge ann-merge1a.cgout ann-merge1b.cgout > ann-merge1c.cgout && python3 ../cg_annotate ann-merge1c.cgout
|
||||
|
||||
cleanup: rm cachegrind.out ann-merge1c.cgout
|
||||
|
||||
85
cachegrind/tests/ann-merge2.post.exp
Normal file
85
cachegrind/tests/ann-merge2.post.exp
Normal file
@ -0,0 +1,85 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate ann-merge1a.cgout ann-merge1b.cgout
|
||||
Description 1:
|
||||
Description 1a
|
||||
Description 1b
|
||||
Description 2:
|
||||
Description 2a
|
||||
Description 2b
|
||||
Command 1: Command 1
|
||||
Command 2: Command 2
|
||||
Events recorded: A
|
||||
Events shown: A
|
||||
Event sort order: A
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Summary
|
||||
--------------------------------------------------------------------------------
|
||||
A__________
|
||||
|
||||
86 (100.0%) PROGRAM TOTALS
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- File:function summary
|
||||
--------------------------------------------------------------------------------
|
||||
A_________________ file:function
|
||||
|
||||
< 70 (81.4%, 81.4%) ann-merge-x.rs:
|
||||
40 (46.5%) x1
|
||||
20 (23.3%) x3
|
||||
10 (11.6%) x2
|
||||
|
||||
< 16 (18.6%, 100.0%) ann-merge-y.rs:y1
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Function:file summary
|
||||
--------------------------------------------------------------------------------
|
||||
A_________________ function:file
|
||||
|
||||
> 40 (46.5%, 46.5%) x1:ann-merge-x.rs
|
||||
|
||||
> 20 (23.3%, 69.8%) x3:ann-merge-x.rs
|
||||
|
||||
> 16 (18.6%, 88.4%) y1:ann-merge-y.rs
|
||||
|
||||
> 10 (11.6%, 100.0%) x2:ann-merge-x.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-merge-x.rs
|
||||
--------------------------------------------------------------------------------
|
||||
A_________
|
||||
|
||||
20 (23.3%) one
|
||||
10 (11.6%) two
|
||||
10 (11.6%) three
|
||||
10 (11.6%) four
|
||||
20 (23.3%) five
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann-merge-y.rs
|
||||
--------------------------------------------------------------------------------
|
||||
A_______
|
||||
|
||||
8 (9.3%) one
|
||||
8 (9.3%) two
|
||||
. three
|
||||
. four
|
||||
. five
|
||||
. six
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotation summary
|
||||
--------------------------------------------------------------------------------
|
||||
A__________
|
||||
|
||||
86 (100.0%) annotated: files known & above threshold & readable, line numbers known
|
||||
0 annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 unannotated: files known & above threshold & two or more non-identical
|
||||
0 unannotated: files known & above threshold & unreadable
|
||||
0 unannotated: files known & below threshold
|
||||
0 unannotated: files unknown
|
||||
|
||||
3
cachegrind/tests/ann-merge2.stderr.exp
Normal file
3
cachegrind/tests/ann-merge2.stderr.exp
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
I refs:
|
||||
8
cachegrind/tests/ann-merge2.vgtest
Normal file
8
cachegrind/tests/ann-merge2.vgtest
Normal file
@ -0,0 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the cgout files.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
post: python3 ../cg_annotate ann-merge1a.cgout ann-merge1b.cgout
|
||||
|
||||
cleanup: rm cachegrind.out
|
||||
@ -1,15 +1,15 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate --show=Ir,I1mr,ILmr --show-percs=no ann1.cgout
|
||||
I1 cache: 32768 B, 64 B, 8-way associative
|
||||
D1 cache: 32768 B, 64 B, 8-way associative
|
||||
LL cache: 19922944 B, 64 B, 19-way associative
|
||||
Command: ./a.out
|
||||
Data file: ann1.cgout
|
||||
Events recorded: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
|
||||
Events shown: Ir I1mr ILmr
|
||||
Event sort order: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
|
||||
Threshold: 0.1
|
||||
Threshold: 0.1%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -24,26 +24,26 @@ Ir_______ I1mr ILmr
|
||||
--------------------------------------------------------------------------------
|
||||
Ir_______ I1mr ILmr file:function
|
||||
|
||||
> 5,000,015 1 1 a.c:main
|
||||
< 5,000,015 1 1 a.c:main
|
||||
|
||||
> 76,688 32 32 /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:
|
||||
< 76,688 32 32 /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:
|
||||
47,993 19 19 do_lookup_x
|
||||
28,534 11 11 _dl_lookup_symbol_x
|
||||
|
||||
> 28,391 11 9 /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c:
|
||||
< 28,391 11 9 /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c:
|
||||
28,136 7 7 __GI___tunables_init
|
||||
|
||||
> 25,408 47 47 /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S:strcmp
|
||||
< 25,408 47 47 /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S:strcmp
|
||||
|
||||
> 22,214 25 25 /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h:
|
||||
< 22,214 25 25 /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h:
|
||||
21,821 23 23 _dl_relocate_object
|
||||
|
||||
> 11,817 16 16 /build/glibc-OTsEL5/glibc-2.27/elf/do-rel.h:
|
||||
< 11,817 16 16 /build/glibc-OTsEL5/glibc-2.27/elf/do-rel.h:
|
||||
11,521 15 15 _dl_relocate_object
|
||||
|
||||
> 8,055 0 0 /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.h:__GI___tunables_init
|
||||
< 8,055 0 0 /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.h:__GI___tunables_init
|
||||
|
||||
> 6,939 5 5 /build/glibc-OTsEL5/glibc-2.27/elf/dl-misc.c:
|
||||
< 6,939 5 5 /build/glibc-OTsEL5/glibc-2.27/elf/dl-misc.c:
|
||||
6,898 2 2 _dl_name_match_p
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -74,37 +74,44 @@ Ir_______ I1mr ILmr
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/elf/dl-misc.c
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/elf/dl-misc.c
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.h
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.h
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/elf/do-rel.h
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/elf/do-rel.h
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: a.c
|
||||
@ -126,6 +133,7 @@ Ir_______ I1mr ILmr
|
||||
|
||||
5,000,015 1 1 annotated: files known & above threshold & readable, line numbers known
|
||||
0 0 0 annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 0 0 unannotated: files known & above threshold & two or more non-identical
|
||||
179,512 136 134 unannotated: files known & above threshold & unreadable
|
||||
49,754 770 758 unannotated: files known & below threshold
|
||||
472 45 38 unannotated: files unknown
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the `ann1.cgout` file.
|
||||
# the post-processing of the cgout file.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
post: touch ann1.cgout && python3 ../cg_annotate --show=Ir,I1mr,ILmr --show-percs=no ann1.cgout
|
||||
|
||||
cleanup: rm cachegrind.out
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate --sort=Dr --show=Dw,Dr,Ir --auto=no ann1.cgout
|
||||
I1 cache: 32768 B, 64 B, 8-way associative
|
||||
D1 cache: 32768 B, 64 B, 8-way associative
|
||||
LL cache: 19922944 B, 64 B, 19-way associative
|
||||
Command: ./a.out
|
||||
Data file: ann1.cgout
|
||||
Events recorded: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
|
||||
Events shown: Dw Dr Ir
|
||||
Event sort order: Dr
|
||||
Threshold: 0.1
|
||||
Threshold: 0.1%
|
||||
Annotation: off
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -24,19 +24,19 @@ Dw_____________ Dr________________ Ir________________
|
||||
--------------------------------------------------------------------------------
|
||||
Dw__________________ Dr______________________ Ir______________________ file:function
|
||||
|
||||
> 3 (0.0%, 0.0%) 4,000,004 (98.6%, 98.6%) 5,000,015 (95.6%, 95.6%) a.c:main
|
||||
< 3 (0.0%, 0.0%) 4,000,004 (98.6%, 98.6%) 5,000,015 (95.6%, 95.6%) a.c:main
|
||||
|
||||
> 7,668 (42.6%, 42.6%) 23,365 (0.6%, 99.1%) 76,688 (1.5%, 97.1%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:
|
||||
< 7,668 (42.6%, 42.6%) 23,365 (0.6%, 99.1%) 76,688 (1.5%, 97.1%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:
|
||||
4,543 (25.2%) 17,566 (0.4%) 47,993 (0.9%) do_lookup_x
|
||||
3,083 (17.1%) 5,750 (0.1%) 28,534 (0.5%) _dl_lookup_symbol_x
|
||||
|
||||
> 22 (0.1%, 42.7%) 5,577 (0.1%, 99.3%) 28,391 (0.5%, 97.6%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c:
|
||||
< 22 (0.1%, 42.7%) 5,577 (0.1%, 99.3%) 28,391 (0.5%, 97.6%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c:
|
||||
8 (0.0%) 5,521 (0.1%) 28,136 (0.5%) __GI___tunables_init
|
||||
|
||||
> 2,542 (14.1%, 56.8%) 5,343 (0.1%, 99.4%) 22,214 (0.4%, 98.0%) /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h:
|
||||
< 2,542 (14.1%, 56.8%) 5,343 (0.1%, 99.4%) 22,214 (0.4%, 98.0%) /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h:
|
||||
2,490 (13.8%) 5,219 (0.1%) 21,821 (0.4%) _dl_relocate_object
|
||||
|
||||
> 0 (0.0%, 56.8%) 5,158 (0.1%, 99.5%) 25,408 (0.5%, 98.5%) /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S:strcmp
|
||||
< 0 (0.0%, 56.8%) 5,158 (0.1%, 99.5%) 25,408 (0.5%, 98.5%) /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S:strcmp
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Function:file summary
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the `ann1.cgout` file.
|
||||
# the post-processing of the cgout file.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
post: touch ann1.cgout && python3 ../cg_annotate --sort=Dr --show=Dw,Dr,Ir --auto=no ann1.cgout
|
||||
|
||||
cleanup: rm cachegrind.out
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Metadata
|
||||
--------------------------------------------------------------------------------
|
||||
Invocation: ../cg_annotate --context 2 --annotate --show-percs=yes --threshold=0.5 ann2.cgout
|
||||
Command: ann2
|
||||
Data file: ann2.cgout
|
||||
Events recorded: A SomeCount VeryLongEventName
|
||||
Events shown: A SomeCount VeryLongEventName
|
||||
Event sort order: A SomeCount VeryLongEventName
|
||||
Threshold: 0.5
|
||||
Threshold: 0.5%
|
||||
Annotation: on
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -21,24 +21,24 @@ A_______________ SomeCount_______ VeryLongEventName
|
||||
--------------------------------------------------------------------------------
|
||||
A___________________________ SomeCount____________ VeryLongEventName__ file:function
|
||||
|
||||
> 86,590 (86.6%, 86.6%) 93,000 (93.0%, 93.0%) 0 (n/a, n/a) ann2-basic.rs:
|
||||
< 86,590 (86.6%, 86.6%) 93,000 (93.0%, 93.0%) 0 (n/a, n/a) ann2-basic.rs:
|
||||
68,081 (68.1%) 90,291 (90.3%) 0 f0
|
||||
15,000 (15.0%) 600 (0.6%) 0 f1
|
||||
2,000 (2.0%) 100 (0.1%) 0 f2
|
||||
500 (0.5%) 0 0 f6
|
||||
500 (0.5%) 0 0 f4
|
||||
|
||||
> 9,000 (9.0%, 95.6%) 6,000 (6.0%, 99.0%) 0 (n/a, n/a) ann2-could-not-be-found.rs:f1
|
||||
< 9,000 (9.0%, 95.6%) 6,000 (6.0%, 99.0%) 0 (n/a, n/a) ann2-could-not-be-found.rs:f1
|
||||
|
||||
> 2,000 (2.0%, 97.6%) 800 (0.8%, 99.8%) -1,000 (n/a, n/a) ann2-past-the-end.rs:
|
||||
< 2,000 (2.0%, 97.6%) 800 (0.8%, 99.8%) -1,000 (n/a, n/a) ann2-past-the-end.rs:
|
||||
1,000 (1.0%) 500 (0.5%) 0 <unspecified>
|
||||
1,000 (1.0%) 300 (0.3%) -1,000 (n/a) f1
|
||||
|
||||
> 1,000 (1.0%, 98.6%) 0 (0.0%, 99.8%) 0 (n/a, n/a) ann2-more-recent-than-cgout.rs:new
|
||||
< 1,000 (1.0%, 98.6%) 0 (0.0%, 99.8%) 0 (n/a, n/a) ann2-more-recent-than-cgout.rs:new
|
||||
|
||||
> 1,000 (1.0%, 99.6%) 0 (0.0%, 99.8%) 0 (n/a, n/a) ???:unknown
|
||||
< 1,000 (1.0%, 99.6%) 0 (0.0%, 99.8%) 0 (n/a, n/a) ???:unknown
|
||||
|
||||
> 10 (0.0%, 99.6%) 0 (0.0%, 99.8%) 1,000 (n/a, n/a) ann2-negatives.rs:
|
||||
< 10 (0.0%, 99.6%) 0 (0.0%, 99.8%) 1,000 (n/a, n/a) ann2-negatives.rs:
|
||||
-1,000,000 (-1000.0%) 0 150,000 (n/a) neg3
|
||||
500,000 (500.0%) 0 -150,000 (n/a) neg2a
|
||||
499,999 (500.0%) 0 0 neg2b
|
||||
@ -104,7 +104,8 @@ A_____________ SomeCount_____ VeryLongEventName
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann2-could-not-be-found.rs
|
||||
--------------------------------------------------------------------------------
|
||||
This file was unreadable
|
||||
Unannotated because one or more of these original files are unreadable:
|
||||
- ann2-could-not-be-found.rs
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Annotated source file: ann2-more-recent-than-cgout.rs
|
||||
@ -112,7 +113,8 @@ This file was unreadable
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ Source file 'ann2-more-recent-than-cgout.rs' is newer than data file 'ann2.cgout'.
|
||||
@ Original source files are all newer than data file 'ann2.cgout':
|
||||
@ - ann2-more-recent-than-cgout.rs
|
||||
@ Annotations may not be correct.
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
@ -176,6 +178,7 @@ A_____________ SomeCount_____ VeryLongEventName
|
||||
|
||||
84,500 (84.5%) 94,700 (94.7%) 990 (n/a) annotated: files known & above threshold & readable, line numbers known
|
||||
5,100 (5.1%) -900 (-0.9%) -990 (n/a) annotated: files known & above threshold & readable, line numbers unknown
|
||||
0 0 0 unannotated: files known & above threshold & two or more non-identical
|
||||
9,000 (9.0%) 6,000 (6.0%) 0 unannotated: files known & above threshold & unreadable
|
||||
400 (0.4%) 200 (0.2%) 0 unannotated: files known & below threshold
|
||||
1,000 (1.0%) 0 0 unannotated: files unknown
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# more details.
|
||||
#
|
||||
# The `prog` doesn't matter because we don't use its output. Instead we test
|
||||
# the post-processing of the `ann2.cgout` file.
|
||||
# the post-processing of the cgout file.
|
||||
prog: ../../tests/true
|
||||
vgopts: --cachegrind-out-file=cachegrind.out
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user