Auto merge of #114399 - Zalathar:no-renumber, r=jackh726

coverage: Don't bother renumbering expressions on the Rust side

The LLVM API that we use to encode coverage mappings already has its own code for removing unused coverage expressions and renumbering the rest.

This lets us get rid of our own complex renumbering code, making it easier to change our coverage code in other ways.

---

Now that we have tests for coverage mappings (#114843), I've been able to verify that this PR doesn't make the coverage mappings worse, thanks to an explicit simplification step.
This commit is contained in:
bors 2023-09-21 17:29:30 +00:00
commit 24b45c3bdc
6 changed files with 258 additions and 316 deletions

View File

@ -1,4 +1,4 @@
use rustc_middle::mir::coverage::{CounterId, MappedExpressionIndex};
use rustc_middle::mir::coverage::{CounterId, ExpressionId, Operand};
/// Must match the layout of `LLVMRustCounterKind`.
#[derive(Copy, Clone, Debug)]
@ -30,11 +30,8 @@ pub struct Counter {
}
impl Counter {
/// Constructs a new `Counter` of kind `Zero`. For this `CounterKind`, the
/// `id` is not used.
pub fn zero() -> Self {
Self { kind: CounterKind::Zero, id: 0 }
}
/// A `Counter` of kind `Zero`. For this counter kind, the `id` is not used.
pub(crate) const ZERO: Self = Self { kind: CounterKind::Zero, id: 0 };
/// Constructs a new `Counter` of kind `CounterValueReference`.
pub fn counter_value_reference(counter_id: CounterId) -> Self {
@ -42,20 +39,16 @@ impl Counter {
}
/// Constructs a new `Counter` of kind `Expression`.
pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self {
Self { kind: CounterKind::Expression, id: mapped_expression_index.into() }
pub(crate) fn expression(expression_id: ExpressionId) -> Self {
Self { kind: CounterKind::Expression, id: expression_id.as_u32() }
}
/// Returns true if the `Counter` kind is `Zero`.
pub fn is_zero(&self) -> bool {
matches!(self.kind, CounterKind::Zero)
}
/// An explicitly-named function to get the ID value, making it more obvious
/// that the stored value is now 0-based.
pub fn zero_based_id(&self) -> u32 {
debug_assert!(!self.is_zero(), "`id` is undefined for CounterKind::Zero");
self.id
pub(crate) fn from_operand(operand: Operand) -> Self {
match operand {
Operand::Zero => Self::ZERO,
Operand::Counter(id) => Self::counter_value_reference(id),
Operand::Expression(id) => Self::expression(id),
}
}
}
@ -81,6 +74,11 @@ pub struct CounterExpression {
}
impl CounterExpression {
/// The dummy expression `(0 - 0)` has a representation of all zeroes,
/// making it marginally more efficient to initialize than `(0 + 0)`.
pub(crate) const DUMMY: Self =
Self { lhs: Counter::ZERO, kind: ExprKind::Subtract, rhs: Counter::ZERO };
pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self {
Self { kind, lhs, rhs }
}
@ -172,7 +170,7 @@ impl CounterMappingRegion {
) -> Self {
Self {
counter,
false_counter: Counter::zero(),
false_counter: Counter::ZERO,
file_id,
expanded_file_id: 0,
start_line,
@ -220,8 +218,8 @@ impl CounterMappingRegion {
end_col: u32,
) -> Self {
Self {
counter: Counter::zero(),
false_counter: Counter::zero(),
counter: Counter::ZERO,
false_counter: Counter::ZERO,
file_id,
expanded_file_id,
start_line,
@ -243,8 +241,8 @@ impl CounterMappingRegion {
end_col: u32,
) -> Self {
Self {
counter: Counter::zero(),
false_counter: Counter::zero(),
counter: Counter::ZERO,
false_counter: Counter::ZERO,
file_id,
expanded_file_id: 0,
start_line,
@ -268,7 +266,7 @@ impl CounterMappingRegion {
) -> Self {
Self {
counter,
false_counter: Counter::zero(),
false_counter: Counter::ZERO,
file_id,
expanded_file_id: 0,
start_line,

View File

@ -1,10 +1,8 @@
use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::bug;
use rustc_middle::mir::coverage::{
CodeRegion, CounterId, ExpressionId, MappedExpressionIndex, Op, Operand,
};
use rustc_data_structures::fx::FxIndexSet;
use rustc_index::IndexVec;
use rustc_middle::mir::coverage::{CodeRegion, CounterId, ExpressionId, Op, Operand};
use rustc_middle::ty::Instance;
use rustc_middle::ty::TyCtxt;
@ -128,6 +126,58 @@ impl<'tcx> FunctionCoverage<'tcx> {
self.unreachable_regions.push(region)
}
/// Perform some simplifications to make the final coverage mappings
/// slightly smaller.
///
/// This method mainly exists to preserve the simplifications that were
/// already being performed by the Rust-side expression renumbering, so that
/// the resulting coverage mappings don't get worse.
pub(crate) fn simplify_expressions(&mut self) {
// The set of expressions that either were optimized out entirely, or
// have zero as both of their operands, and will therefore always have
// a value of zero. Other expressions that refer to these as operands
// can have those operands replaced with `Operand::Zero`.
let mut zero_expressions = FxIndexSet::default();
// For each expression, perform simplifications based on lower-numbered
// expressions, and then update the set of always-zero expressions if
// necessary.
// (By construction, expressions can only refer to other expressions
// that have lower IDs, so one simplification pass is sufficient.)
for (id, maybe_expression) in self.expressions.iter_enumerated_mut() {
let Some(expression) = maybe_expression else {
// If an expression is missing, it must have been optimized away,
// so any operand that refers to it can be replaced with zero.
zero_expressions.insert(id);
continue;
};
// If an operand refers to an expression that is always zero, then
// that operand can be replaced with `Operand::Zero`.
let maybe_set_operand_to_zero = |operand: &mut Operand| match &*operand {
Operand::Expression(id) if zero_expressions.contains(id) => {
*operand = Operand::Zero;
}
_ => (),
};
maybe_set_operand_to_zero(&mut expression.lhs);
maybe_set_operand_to_zero(&mut expression.rhs);
// Coverage counter values cannot be negative, so if an expression
// involves subtraction from zero, assume that its RHS must also be zero.
// (Do this after simplifications that could set the LHS to zero.)
if let Expression { lhs: Operand::Zero, op: Op::Subtract, .. } = expression {
expression.rhs = Operand::Zero;
}
// After the above simplifications, if both operands are zero, then
// we know that this expression is always zero too.
if let Expression { lhs: Operand::Zero, rhs: Operand::Zero, .. } = expression {
zero_expressions.insert(id);
}
}
}
/// Return the source hash, generated from the HIR node structure, and used to indicate whether
/// or not the source code structure changed between different compilations.
pub fn source_hash(&self) -> u64 {
@ -146,8 +196,14 @@ impl<'tcx> FunctionCoverage<'tcx> {
self.instance
);
let counter_expressions = self.counter_expressions();
// Expression IDs are indices into `self.expressions`, and on the LLVM
// side they will be treated as indices into `counter_expressions`, so
// the two vectors should correspond 1:1.
assert_eq!(self.expressions.len(), counter_expressions.len());
let counter_regions = self.counter_regions();
let (counter_expressions, expression_regions) = self.expressions_with_regions();
let expression_regions = self.expression_regions();
let unreachable_regions = self.unreachable_regions();
let counter_regions =
@ -163,149 +219,53 @@ impl<'tcx> FunctionCoverage<'tcx> {
})
}
fn expressions_with_regions(
&self,
) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &CodeRegion)>) {
let mut counter_expressions = Vec::with_capacity(self.expressions.len());
let mut expression_regions = Vec::with_capacity(self.expressions.len());
let mut new_indexes = IndexVec::from_elem_n(None, self.expressions.len());
/// Convert this function's coverage expression data into a form that can be
/// passed through FFI to LLVM.
fn counter_expressions(&self) -> Vec<CounterExpression> {
// We know that LLVM will optimize out any unused expressions before
// producing the final coverage map, so there's no need to do the same
// thing on the Rust side unless we're confident we can do much better.
// (See `CounterExpressionsMinimizer` in `CoverageMappingWriter.cpp`.)
// This closure converts any `Expression` operand (`lhs` or `rhs` of the `Op::Add` or
// `Op::Subtract` operation) into its native `llvm::coverage::Counter::CounterKind` type
// and value.
//
// Expressions will be returned from this function in a sequential vector (array) of
// `CounterExpression`, so the expression IDs must be mapped from their original,
// potentially sparse set of indexes.
//
// An `Expression` as an operand will have already been encountered as an `Expression` with
// operands, so its new_index will already have been generated (as a 1-up index value).
// (If an `Expression` as an operand does not have a corresponding new_index, it was
// probably optimized out, after the expression was injected into the MIR, so it will
// get a `CounterKind::Zero` instead.)
//
// In other words, an `Expression`s at any given index can include other expressions as
// operands, but expression operands can only come from the subset of expressions having
// `expression_index`s lower than the referencing `Expression`. Therefore, it is
// reasonable to look up the new index of an expression operand while the `new_indexes`
// vector is only complete up to the current `ExpressionIndex`.
type NewIndexes = IndexSlice<ExpressionId, Option<MappedExpressionIndex>>;
let id_to_counter = |new_indexes: &NewIndexes, operand: Operand| match operand {
Operand::Zero => Some(Counter::zero()),
Operand::Counter(id) => Some(Counter::counter_value_reference(id)),
Operand::Expression(id) => {
self.expressions
.get(id)
.expect("expression id is out of range")
.as_ref()
// If an expression was optimized out, assume it would have produced a count
// of zero. This ensures that expressions dependent on optimized-out
// expressions are still valid.
.map_or(Some(Counter::zero()), |_| new_indexes[id].map(Counter::expression))
}
};
for (original_index, expression) in
self.expressions.iter_enumerated().filter_map(|(original_index, entry)| {
// Option::map() will return None to filter out missing expressions. This may happen
// if, for example, a MIR-instrumented expression is removed during an optimization.
entry.as_ref().map(|expression| (original_index, expression))
self.expressions
.iter()
.map(|expression| match expression {
None => {
// This expression ID was allocated, but we never saw the
// actual expression, so it must have been optimized out.
// Replace it with a dummy expression, and let LLVM take
// care of omitting it from the expression list.
CounterExpression::DUMMY
}
&Some(Expression { lhs, op, rhs, .. }) => {
// Convert the operands and operator as normal.
CounterExpression::new(
Counter::from_operand(lhs),
match op {
Op::Add => ExprKind::Add,
Op::Subtract => ExprKind::Subtract,
},
Counter::from_operand(rhs),
)
}
})
{
let optional_region = &expression.region;
let Expression { lhs, op, rhs, .. } = *expression;
.collect::<Vec<_>>()
}
if let Some(Some((lhs_counter, mut rhs_counter))) = id_to_counter(&new_indexes, lhs)
.map(|lhs_counter| {
id_to_counter(&new_indexes, rhs).map(|rhs_counter| (lhs_counter, rhs_counter))
})
{
if lhs_counter.is_zero() && op.is_subtract() {
// The left side of a subtraction was probably optimized out. As an example,
// a branch condition might be evaluated as a constant expression, and the
// branch could be removed, dropping unused counters in the process.
//
// Since counters are unsigned, we must assume the result of the expression
// can be no more and no less than zero. An expression known to evaluate to zero
// does not need to be added to the coverage map.
//
// Coverage test `loops_branches.rs` includes multiple variations of branches
// based on constant conditional (literal `true` or `false`), and demonstrates
// that the expected counts are still correct.
debug!(
"Expression subtracts from zero (assume unreachable): \
original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}",
original_index, lhs, op, rhs, optional_region,
);
rhs_counter = Counter::zero();
}
debug_assert!(
lhs_counter.is_zero()
// Note: with `as usize` the ID _could_ overflow/wrap if `usize = u16`
|| ((lhs_counter.zero_based_id() as usize)
<= usize::max(self.counters.len(), self.expressions.len())),
"lhs id={} > both counters.len()={} and expressions.len()={}
({:?} {:?} {:?})",
lhs_counter.zero_based_id(),
self.counters.len(),
self.expressions.len(),
lhs_counter,
op,
rhs_counter,
);
debug_assert!(
rhs_counter.is_zero()
// Note: with `as usize` the ID _could_ overflow/wrap if `usize = u16`
|| ((rhs_counter.zero_based_id() as usize)
<= usize::max(self.counters.len(), self.expressions.len())),
"rhs id={} > both counters.len()={} and expressions.len()={}
({:?} {:?} {:?})",
rhs_counter.zero_based_id(),
self.counters.len(),
self.expressions.len(),
lhs_counter,
op,
rhs_counter,
);
// Both operands exist. `Expression` operands exist in `self.expressions` and have
// been assigned a `new_index`.
let mapped_expression_index =
MappedExpressionIndex::from(counter_expressions.len());
let expression = CounterExpression::new(
lhs_counter,
match op {
Op::Add => ExprKind::Add,
Op::Subtract => ExprKind::Subtract,
},
rhs_counter,
);
debug!(
"Adding expression {:?} = {:?}, region: {:?}",
mapped_expression_index, expression, optional_region
);
counter_expressions.push(expression);
new_indexes[original_index] = Some(mapped_expression_index);
if let Some(region) = optional_region {
expression_regions.push((Counter::expression(mapped_expression_index), region));
}
} else {
bug!(
"expression has one or more missing operands \
original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}",
original_index,
lhs,
op,
rhs,
optional_region,
);
}
}
(counter_expressions, expression_regions.into_iter())
fn expression_regions(&self) -> Vec<(Counter, &CodeRegion)> {
// Find all of the expression IDs that weren't optimized out AND have
// an attached code region, and return the corresponding mapping as a
// counter/region pair.
self.expressions
.iter_enumerated()
.filter_map(|(id, expression)| {
let code_region = expression.as_ref()?.region.as_ref()?;
Some((Counter::expression(id), code_region))
})
.collect::<Vec<_>>()
}
fn unreachable_regions(&self) -> impl Iterator<Item = (Counter, &CodeRegion)> {
self.unreachable_regions.iter().map(|region| (Counter::zero(), region))
self.unreachable_regions.iter().map(|region| (Counter::ZERO, region))
}
}

View File

@ -60,8 +60,11 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
// Encode coverage mappings and generate function records
let mut function_data = Vec::new();
for (instance, function_coverage) in function_coverage_map {
for (instance, mut function_coverage) in function_coverage_map {
debug!("Generate function coverage for {}, {:?}", cx.codegen_unit.name(), instance);
function_coverage.simplify_expressions();
let function_coverage = function_coverage;
let mangled_function_name = tcx.symbol_name(instance).name;
let source_hash = function_coverage.source_hash();
let is_used = function_coverage.is_used();

View File

@ -45,16 +45,6 @@ impl ExpressionId {
}
}
rustc_index::newtype_index! {
/// MappedExpressionIndex values ascend from zero, and are recalculated indexes based on their
/// array position in the LLVM coverage map "Expressions" array, which is assembled during the
/// "mapgen" process. They cannot be computed algorithmically, from the other `newtype_index`s.
#[derive(HashStable)]
#[max = 0xFFFF_FFFF]
#[debug_format = "MappedExpressionIndex({})"]
pub struct MappedExpressionIndex {}
}
/// Operand of a coverage-counter expression.
///
/// Operands can be a constant zero value, an actual coverage counter, or another

View File

@ -479,7 +479,6 @@ TrivialTypeTraversalImpls! {
::rustc_target::asm::InlineAsmRegOrRegClass,
crate::mir::coverage::CounterId,
crate::mir::coverage::ExpressionId,
crate::mir::coverage::MappedExpressionIndex,
crate::mir::Local,
crate::mir::Promoted,
crate::traits::Reveal,

View File

@ -1,62 +1,58 @@
Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
Raw bytes (262): 0x[01, 01, 36, 05, 09, 0a, 02, 00, 00, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, d3, 01, d7, 01, 0d, 00, 11, 15, ca, 01, 00, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, ca, 01, 15, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, c6, 01, 1d, ca, 01, 15, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, be, 01, c2, 01, 00, 00, c6, 01, 1d, ca, 01, 15, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, bb, 01, 11, be, 01, c2, 01, 00, 00, c6, 01, 1d, ca, 01, 15, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, 25, b3, 01, b6, 01, 19, bb, 01, 11, be, 01, c2, 01, 00, 00, c6, 01, 1d, ca, 01, 15, cf, 01, 19, d3, 01, d7, 01, 0d, 00, 11, 15, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, ca, 01, 03, 0d, 00, 0e, cf, 01, 00, 12, 00, 17, 2b, 01, 10, 00, 14, c6, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, c2, 01, 01, 12, 00, 13, bb, 01, 01, 11, 00, 22, b6, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, af, 01, 01, 05, 00, 06]
Raw bytes (251): 0x[01, 01, 32, 05, 09, 00, 02, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, c3, 01, c7, 01, 0d, 00, 11, 15, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, af, 01, 11, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 25, a7, 01, aa, 01, 19, af, 01, 11, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, ba, 01, 03, 0d, 00, 0e, bf, 01, 00, 12, 00, 17, 27, 01, 10, 00, 14, b6, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b2, 01, 01, 12, 00, 13, af, 01, 01, 11, 00, 22, aa, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, a3, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => global file 1
Number of expressions: 54
Number of expressions: 50
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
- expression 1 operands: lhs = Expression(2, Sub), rhs = Expression(0, Sub)
- expression 2 operands: lhs = Zero, rhs = Zero
- expression 3 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 4 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 5 operands: lhs = Counter(3), rhs = Zero
- expression 6 operands: lhs = Counter(4), rhs = Counter(5)
- expression 7 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 8 operands: lhs = Counter(3), rhs = Zero
- expression 9 operands: lhs = Counter(4), rhs = Counter(5)
- expression 10 operands: lhs = Expression(50, Sub), rhs = Zero
- expression 11 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 12 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 13 operands: lhs = Counter(3), rhs = Zero
- expression 14 operands: lhs = Counter(4), rhs = Counter(5)
- expression 15 operands: lhs = Expression(50, Sub), rhs = Counter(5)
- expression 16 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 17 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 18 operands: lhs = Counter(3), rhs = Zero
- expression 19 operands: lhs = Counter(4), rhs = Counter(5)
- expression 20 operands: lhs = Expression(49, Sub), rhs = Counter(7)
- expression 21 operands: lhs = Expression(50, Sub), rhs = Counter(5)
- expression 22 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 23 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 24 operands: lhs = Counter(3), rhs = Zero
- expression 25 operands: lhs = Counter(4), rhs = Counter(5)
- expression 26 operands: lhs = Expression(47, Sub), rhs = Expression(48, Sub)
- expression 27 operands: lhs = Zero, rhs = Zero
- expression 28 operands: lhs = Expression(49, Sub), rhs = Counter(7)
- expression 29 operands: lhs = Expression(50, Sub), rhs = Counter(5)
- expression 30 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 31 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 32 operands: lhs = Counter(3), rhs = Zero
- expression 33 operands: lhs = Counter(4), rhs = Counter(5)
- expression 34 operands: lhs = Expression(46, Add), rhs = Counter(4)
- expression 35 operands: lhs = Expression(47, Sub), rhs = Expression(48, Sub)
- expression 36 operands: lhs = Zero, rhs = Zero
- expression 37 operands: lhs = Expression(49, Sub), rhs = Counter(7)
- expression 38 operands: lhs = Expression(50, Sub), rhs = Counter(5)
- expression 39 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 40 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 41 operands: lhs = Counter(3), rhs = Zero
- expression 42 operands: lhs = Counter(4), rhs = Counter(5)
- expression 43 operands: lhs = Counter(9), rhs = Expression(44, Add)
- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(6)
- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(4)
- expression 46 operands: lhs = Expression(47, Sub), rhs = Expression(48, Sub)
- expression 47 operands: lhs = Zero, rhs = Zero
- expression 48 operands: lhs = Expression(49, Sub), rhs = Counter(7)
- expression 49 operands: lhs = Expression(50, Sub), rhs = Counter(5)
- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(6)
- expression 51 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
- expression 52 operands: lhs = Counter(3), rhs = Zero
- expression 53 operands: lhs = Counter(4), rhs = Counter(5)
- expression 1 operands: lhs = Zero, rhs = Expression(0, Sub)
- expression 2 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 3 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 4 operands: lhs = Counter(3), rhs = Zero
- expression 5 operands: lhs = Counter(4), rhs = Counter(5)
- expression 6 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 7 operands: lhs = Counter(3), rhs = Zero
- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
- expression 9 operands: lhs = Expression(46, Sub), rhs = Zero
- expression 10 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 11 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 12 operands: lhs = Counter(3), rhs = Zero
- expression 13 operands: lhs = Counter(4), rhs = Counter(5)
- expression 14 operands: lhs = Expression(46, Sub), rhs = Counter(5)
- expression 15 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 16 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 17 operands: lhs = Counter(3), rhs = Zero
- expression 18 operands: lhs = Counter(4), rhs = Counter(5)
- expression 19 operands: lhs = Expression(45, Sub), rhs = Counter(7)
- expression 20 operands: lhs = Expression(46, Sub), rhs = Counter(5)
- expression 21 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 22 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 23 operands: lhs = Counter(3), rhs = Zero
- expression 24 operands: lhs = Counter(4), rhs = Counter(5)
- expression 25 operands: lhs = Zero, rhs = Expression(44, Sub)
- expression 26 operands: lhs = Expression(45, Sub), rhs = Counter(7)
- expression 27 operands: lhs = Expression(46, Sub), rhs = Counter(5)
- expression 28 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 29 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 30 operands: lhs = Counter(3), rhs = Zero
- expression 31 operands: lhs = Counter(4), rhs = Counter(5)
- expression 32 operands: lhs = Expression(43, Add), rhs = Counter(4)
- expression 33 operands: lhs = Zero, rhs = Expression(44, Sub)
- expression 34 operands: lhs = Expression(45, Sub), rhs = Counter(7)
- expression 35 operands: lhs = Expression(46, Sub), rhs = Counter(5)
- expression 36 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 37 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 38 operands: lhs = Counter(3), rhs = Zero
- expression 39 operands: lhs = Counter(4), rhs = Counter(5)
- expression 40 operands: lhs = Counter(9), rhs = Expression(41, Add)
- expression 41 operands: lhs = Expression(42, Sub), rhs = Counter(6)
- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(4)
- expression 43 operands: lhs = Zero, rhs = Expression(44, Sub)
- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(7)
- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(5)
- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(6)
- expression 47 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
- expression 48 operands: lhs = Counter(3), rhs = Zero
- expression 49 operands: lhs = Counter(4), rhs = Counter(5)
Number of file 0 mappings: 20
- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16)
- Code(Counter(1)) at (prev + 2, 16) to (start + 0, 21)
@ -65,91 +61,87 @@ Number of file 0 mappings: 20
- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 15)
= (c1 - c2)
- Code(Expression(1, Add)) at (prev + 1, 13) to (start + 0, 30)
= ((Zero - Zero) + (c1 - c2))
= (Zero + (c1 - c2))
- Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31)
- Code(Zero) at (prev + 1, 16) to (start + 1, 10)
- Code(Expression(50, Sub)) at (prev + 3, 13) to (start + 0, 14)
- Code(Expression(46, Sub)) at (prev + 3, 13) to (start + 0, 14)
= (((c3 + Zero) + (c4 + c5)) - c6)
- Code(Expression(51, Add)) at (prev + 0, 18) to (start + 0, 23)
- Code(Expression(47, Add)) at (prev + 0, 18) to (start + 0, 23)
= ((c3 + Zero) + (c4 + c5))
- Code(Expression(10, Add)) at (prev + 1, 16) to (start + 0, 20)
- Code(Expression(9, Add)) at (prev + 1, 16) to (start + 0, 20)
= ((((c3 + Zero) + (c4 + c5)) - c6) + Zero)
- Code(Expression(49, Sub)) at (prev + 1, 20) to (start + 0, 25)
- Code(Expression(45, Sub)) at (prev + 1, 20) to (start + 0, 25)
= ((((c3 + Zero) + (c4 + c5)) - c6) - c5)
- Code(Zero) at (prev + 1, 27) to (start + 0, 31)
- Code(Zero) at (prev + 0, 32) to (start + 0, 34)
- Code(Expression(48, Sub)) at (prev + 1, 18) to (start + 0, 19)
- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 19)
= (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)
- Code(Expression(46, Add)) at (prev + 1, 17) to (start + 0, 34)
= ((Zero - Zero) + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7))
- Code(Expression(45, Sub)) at (prev + 0, 34) to (start + 0, 35)
= (((Zero - Zero) + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4)
- Code(Expression(43, Add)) at (prev + 1, 17) to (start + 0, 34)
= (Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7))
- Code(Expression(42, Sub)) at (prev + 0, 34) to (start + 0, 35)
= ((Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4)
- Code(Zero) at (prev + 1, 20) to (start + 1, 14)
- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
- Code(Expression(43, Add)) at (prev + 1, 5) to (start + 0, 6)
= (c9 + ((((Zero - Zero) + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4) + c6))
- Code(Expression(40, Add)) at (prev + 1, 5) to (start + 0, 6)
= (c9 + (((Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4) + c6))
Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
Raw bytes (266): 0x[01, 01, 38, 01, 05, 02, 09, 0e, 12, 00, 00, 02, 09, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, d7, 01, db, 01, 05, 0d, 11, 15, ce, 01, 00, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, ce, 01, 11, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, ca, 01, 1d, ce, 01, 11, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, c2, 01, c6, 01, 00, 00, ca, 01, 1d, ce, 01, 11, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, bf, 01, 15, c2, 01, c6, 01, 00, 00, ca, 01, 1d, ce, 01, 11, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, ba, 01, df, 01, bf, 01, 15, c2, 01, c6, 01, 00, 00, ca, 01, 1d, ce, 01, 11, d3, 01, 19, d7, 01, db, 01, 05, 0d, 11, 15, 19, 25, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 12, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, ce, 01, 02, 0d, 00, 0e, d3, 01, 00, 12, 00, 17, 33, 01, 10, 00, 15, 00, 00, 16, 01, 0e, ca, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, c6, 01, 01, 12, 00, 13, bf, 01, 01, 11, 00, 22, ba, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, b7, 01, 01, 05, 00, 06]
Raw bytes (255): 0x[01, 01, 34, 01, 05, 02, 09, 00, 0e, 02, 09, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, c7, 01, cb, 01, 05, 0d, 11, 15, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, b3, 01, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, ae, 01, cf, 01, b3, 01, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, 19, 25, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, be, 01, 02, 0d, 00, 0e, c3, 01, 00, 12, 00, 17, 2f, 01, 10, 00, 15, 00, 00, 16, 01, 0e, ba, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b6, 01, 01, 12, 00, 13, b3, 01, 01, 11, 00, 22, ae, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, ab, 01, 01, 05, 00, 06]
Number of files: 1
- file 0 => global file 1
Number of expressions: 56
Number of expressions: 52
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(2)
- expression 2 operands: lhs = Expression(3, Sub), rhs = Expression(4, Sub)
- expression 3 operands: lhs = Zero, rhs = Zero
- expression 4 operands: lhs = Expression(0, Sub), rhs = Counter(2)
- expression 5 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 6 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 7 operands: lhs = Counter(1), rhs = Counter(3)
- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
- expression 9 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 10 operands: lhs = Counter(1), rhs = Counter(3)
- expression 11 operands: lhs = Counter(4), rhs = Counter(5)
- expression 12 operands: lhs = Expression(51, Sub), rhs = Zero
- expression 13 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 14 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 15 operands: lhs = Counter(1), rhs = Counter(3)
- expression 16 operands: lhs = Counter(4), rhs = Counter(5)
- expression 17 operands: lhs = Expression(51, Sub), rhs = Counter(4)
- expression 18 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 19 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 20 operands: lhs = Counter(1), rhs = Counter(3)
- expression 21 operands: lhs = Counter(4), rhs = Counter(5)
- expression 22 operands: lhs = Expression(50, Sub), rhs = Counter(7)
- expression 23 operands: lhs = Expression(51, Sub), rhs = Counter(4)
- expression 24 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 25 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 26 operands: lhs = Counter(1), rhs = Counter(3)
- expression 27 operands: lhs = Counter(4), rhs = Counter(5)
- expression 28 operands: lhs = Expression(48, Sub), rhs = Expression(49, Sub)
- expression 29 operands: lhs = Zero, rhs = Zero
- expression 30 operands: lhs = Expression(50, Sub), rhs = Counter(7)
- expression 31 operands: lhs = Expression(51, Sub), rhs = Counter(4)
- expression 32 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 33 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 34 operands: lhs = Counter(1), rhs = Counter(3)
- expression 35 operands: lhs = Counter(4), rhs = Counter(5)
- expression 36 operands: lhs = Expression(47, Add), rhs = Counter(5)
- expression 37 operands: lhs = Expression(48, Sub), rhs = Expression(49, Sub)
- expression 38 operands: lhs = Zero, rhs = Zero
- expression 39 operands: lhs = Expression(50, Sub), rhs = Counter(7)
- expression 40 operands: lhs = Expression(51, Sub), rhs = Counter(4)
- expression 41 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 42 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 43 operands: lhs = Counter(1), rhs = Counter(3)
- expression 44 operands: lhs = Counter(4), rhs = Counter(5)
- expression 45 operands: lhs = Expression(46, Sub), rhs = Expression(55, Add)
- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(5)
- expression 47 operands: lhs = Expression(48, Sub), rhs = Expression(49, Sub)
- expression 48 operands: lhs = Zero, rhs = Zero
- expression 49 operands: lhs = Expression(50, Sub), rhs = Counter(7)
- expression 50 operands: lhs = Expression(51, Sub), rhs = Counter(4)
- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(6)
- expression 52 operands: lhs = Expression(53, Add), rhs = Expression(54, Add)
- expression 53 operands: lhs = Counter(1), rhs = Counter(3)
- expression 54 operands: lhs = Counter(4), rhs = Counter(5)
- expression 55 operands: lhs = Counter(6), rhs = Counter(9)
- expression 2 operands: lhs = Zero, rhs = Expression(3, Sub)
- expression 3 operands: lhs = Expression(0, Sub), rhs = Counter(2)
- expression 4 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 5 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 6 operands: lhs = Counter(1), rhs = Counter(3)
- expression 7 operands: lhs = Counter(4), rhs = Counter(5)
- expression 8 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 9 operands: lhs = Counter(1), rhs = Counter(3)
- expression 10 operands: lhs = Counter(4), rhs = Counter(5)
- expression 11 operands: lhs = Expression(47, Sub), rhs = Zero
- expression 12 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 13 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 14 operands: lhs = Counter(1), rhs = Counter(3)
- expression 15 operands: lhs = Counter(4), rhs = Counter(5)
- expression 16 operands: lhs = Expression(47, Sub), rhs = Counter(4)
- expression 17 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 18 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 19 operands: lhs = Counter(1), rhs = Counter(3)
- expression 20 operands: lhs = Counter(4), rhs = Counter(5)
- expression 21 operands: lhs = Expression(46, Sub), rhs = Counter(7)
- expression 22 operands: lhs = Expression(47, Sub), rhs = Counter(4)
- expression 23 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 24 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 25 operands: lhs = Counter(1), rhs = Counter(3)
- expression 26 operands: lhs = Counter(4), rhs = Counter(5)
- expression 27 operands: lhs = Zero, rhs = Expression(45, Sub)
- expression 28 operands: lhs = Expression(46, Sub), rhs = Counter(7)
- expression 29 operands: lhs = Expression(47, Sub), rhs = Counter(4)
- expression 30 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 31 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 32 operands: lhs = Counter(1), rhs = Counter(3)
- expression 33 operands: lhs = Counter(4), rhs = Counter(5)
- expression 34 operands: lhs = Expression(44, Add), rhs = Counter(5)
- expression 35 operands: lhs = Zero, rhs = Expression(45, Sub)
- expression 36 operands: lhs = Expression(46, Sub), rhs = Counter(7)
- expression 37 operands: lhs = Expression(47, Sub), rhs = Counter(4)
- expression 38 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 39 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 40 operands: lhs = Counter(1), rhs = Counter(3)
- expression 41 operands: lhs = Counter(4), rhs = Counter(5)
- expression 42 operands: lhs = Expression(43, Sub), rhs = Expression(51, Add)
- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(5)
- expression 44 operands: lhs = Zero, rhs = Expression(45, Sub)
- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(7)
- expression 46 operands: lhs = Expression(47, Sub), rhs = Counter(4)
- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(6)
- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
- expression 49 operands: lhs = Counter(1), rhs = Counter(3)
- expression 50 operands: lhs = Counter(4), rhs = Counter(5)
- expression 51 operands: lhs = Counter(6), rhs = Counter(9)
Number of file 0 mappings: 20
- Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17)
- Code(Zero) at (prev + 1, 18) to (start + 1, 10)
@ -157,31 +149,31 @@ Number of file 0 mappings: 20
= (c0 - c1)
- Code(Zero) at (prev + 1, 23) to (start + 0, 27)
- Code(Zero) at (prev + 0, 28) to (start + 0, 30)
- Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 15)
- Code(Expression(3, Sub)) at (prev + 1, 14) to (start + 0, 15)
= ((c0 - c1) - c2)
- Code(Expression(2, Add)) at (prev + 1, 13) to (start + 0, 30)
= ((Zero - Zero) + ((c0 - c1) - c2))
= (Zero + ((c0 - c1) - c2))
- Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31)
- Code(Expression(51, Sub)) at (prev + 2, 13) to (start + 0, 14)
- Code(Expression(47, Sub)) at (prev + 2, 13) to (start + 0, 14)
= (((c1 + c3) + (c4 + c5)) - c6)
- Code(Expression(52, Add)) at (prev + 0, 18) to (start + 0, 23)
- Code(Expression(48, Add)) at (prev + 0, 18) to (start + 0, 23)
= ((c1 + c3) + (c4 + c5))
- Code(Expression(12, Add)) at (prev + 1, 16) to (start + 0, 21)
- Code(Expression(11, Add)) at (prev + 1, 16) to (start + 0, 21)
= ((((c1 + c3) + (c4 + c5)) - c6) + Zero)
- Code(Zero) at (prev + 0, 22) to (start + 1, 14)
- Code(Expression(50, Sub)) at (prev + 2, 20) to (start + 0, 25)
- Code(Expression(46, Sub)) at (prev + 2, 20) to (start + 0, 25)
= ((((c1 + c3) + (c4 + c5)) - c6) - c4)
- Code(Zero) at (prev + 1, 27) to (start + 0, 31)
- Code(Zero) at (prev + 0, 32) to (start + 0, 34)
- Code(Expression(49, Sub)) at (prev + 1, 18) to (start + 0, 19)
- Code(Expression(45, Sub)) at (prev + 1, 18) to (start + 0, 19)
= (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)
- Code(Expression(47, Add)) at (prev + 1, 17) to (start + 0, 34)
= ((Zero - Zero) + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7))
- Code(Expression(46, Sub)) at (prev + 0, 34) to (start + 0, 35)
= (((Zero - Zero) + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5)
- Code(Expression(44, Add)) at (prev + 1, 17) to (start + 0, 34)
= (Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7))
- Code(Expression(43, Sub)) at (prev + 0, 34) to (start + 0, 35)
= ((Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5)
- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
- Code(Expression(45, Add)) at (prev + 1, 5) to (start + 0, 6)
= ((((Zero - Zero) + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5) + (c6 + c9))
- Code(Expression(42, Add)) at (prev + 1, 5) to (start + 0, 6)
= (((Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5) + (c6 + c9))
Function name: loops_branches::main
Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02]