Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

coverage: Memoize and simplify counter expressions #125106

Merged
merged 3 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ impl Debug for CodeRegion {
}
}

#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
pub enum Op {
Subtract,
Add,
Expand Down
85 changes: 80 additions & 5 deletions compiler/rustc_mir_transform/src/coverage/counters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverage

/// The coverage counter or counter expression associated with a particular
/// BCB node or BCB edge.
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub(super) enum BcbCounter {
Counter { id: CounterId },
Expression { id: ExpressionId },
Expand All @@ -35,6 +35,13 @@ impl Debug for BcbCounter {
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
struct BcbExpression {
lhs: BcbCounter,
op: Op,
rhs: BcbCounter,
}

#[derive(Debug)]
pub(super) enum CounterIncrementSite {
Node { bcb: BasicCoverageBlock },
Expand All @@ -56,9 +63,13 @@ pub(super) struct CoverageCounters {
/// We currently don't iterate over this map, but if we do in the future,
/// switch it back to `FxIndexMap` to avoid query stability hazards.
bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,

/// Table of expression data, associating each expression ID with its
/// corresponding operator (+ or -) and its LHS/RHS operands.
expressions: IndexVec<ExpressionId, Expression>,
expressions: IndexVec<ExpressionId, BcbExpression>,
/// Remember expressions that have already been created (or simplified),
/// so that we don't create unnecessary duplicates.
expressions_memo: FxHashMap<BcbExpression, BcbCounter>,
}

impl CoverageCounters {
Expand All @@ -76,6 +87,7 @@ impl CoverageCounters {
bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
bcb_edge_counters: FxHashMap::default(),
expressions: IndexVec::new(),
expressions_memo: FxHashMap::default(),
};

MakeBcbCounters::new(&mut this, basic_coverage_blocks)
Expand All @@ -90,8 +102,57 @@ impl CoverageCounters {
}

fn make_expression(&mut self, lhs: BcbCounter, op: Op, rhs: BcbCounter) -> BcbCounter {
let expression = Expression { lhs: lhs.as_term(), op, rhs: rhs.as_term() };
let id = self.expressions.push(expression);
let new_expr = BcbExpression { lhs, op, rhs };
*self
.expressions_memo
.entry(new_expr)
.or_insert_with(|| Self::make_expression_inner(&mut self.expressions, new_expr))
}

/// This is an associated function so that we can call it while borrowing
/// `&mut self.expressions_memo`.
fn make_expression_inner(
expressions: &mut IndexVec<ExpressionId, BcbExpression>,
new_expr: BcbExpression,
) -> BcbCounter {
// Simplify expressions using basic algebra.
//
// Some of these cases might not actually occur in practice, depending
// on the details of how the instrumentor builds expressions.
let BcbExpression { lhs, op, rhs } = new_expr;

if let BcbCounter::Expression { id } = lhs {
let lhs_expr = &expressions[id];

// Simplify `(a - b) + b` to `a`.
if lhs_expr.op == Op::Subtract && op == Op::Add && lhs_expr.rhs == rhs {
return lhs_expr.lhs;
}
// Simplify `(a + b) - b` to `a`.
if lhs_expr.op == Op::Add && op == Op::Subtract && lhs_expr.rhs == rhs {
return lhs_expr.lhs;
}
// Simplify `(a + b) - a` to `b`.
if lhs_expr.op == Op::Add && op == Op::Subtract && lhs_expr.lhs == rhs {
return lhs_expr.rhs;
}
}

if let BcbCounter::Expression { id } = rhs {
let rhs_expr = &expressions[id];

// Simplify `a + (b - a)` to `b`.
if op == Op::Add && rhs_expr.op == Op::Subtract && lhs == rhs_expr.rhs {
return rhs_expr.lhs;
}
// Simplify `a - (a - b)` to `b`.
if op == Op::Subtract && rhs_expr.op == Op::Subtract && lhs == rhs_expr.lhs {
return rhs_expr.rhs;
}
}

// Simplification failed, so actually create the new expression.
let id = expressions.push(new_expr);
BcbCounter::Expression { id }
}

Expand Down Expand Up @@ -166,7 +227,21 @@ impl CoverageCounters {
}

pub(super) fn into_expressions(self) -> IndexVec<ExpressionId, Expression> {
self.expressions
let old_len = self.expressions.len();
let expressions = self
.expressions
.into_iter()
.map(|BcbExpression { lhs, op, rhs }| Expression {
lhs: lhs.as_term(),
op,
rhs: rhs.as_term(),
})
.collect::<IndexVec<ExpressionId, _>>();

// Expression IDs are indexes into this vector, so make sure we didn't
// accidentally invalidate them by changing its length.
assert_eq!(old_len, expressions.len());
expressions
}
}

Expand Down
42 changes: 17 additions & 25 deletions tests/coverage/abort.cov-map
Original file line number Diff line number Diff line change
@@ -1,45 +1,37 @@
Function name: abort::main
Raw bytes (105): 0x[01, 01, 12, 01, 47, 05, 09, 03, 0d, 42, 11, 03, 0d, 11, 3e, 42, 11, 03, 0d, 3b, 15, 11, 3e, 42, 11, 03, 0d, 15, 36, 3b, 15, 11, 3e, 42, 11, 03, 0d, 05, 09, 0d, 01, 0e, 01, 01, 1b, 03, 02, 0b, 00, 18, 42, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 3e, 02, 0a, 00, 0b, 3b, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 36, 00, 31, 00, 32, 33, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 47, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0e, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 0a, 00, 0b, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 31, 00, 32, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 18
- expression 0 operands: lhs = Counter(0), rhs = Expression(17, Add)
Number of expressions: 10
- expression 0 operands: lhs = Counter(0), rhs = Expression(9, Add)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 3 operands: lhs = Expression(16, Sub), rhs = Counter(4)
- expression 3 operands: lhs = Expression(8, Sub), rhs = Counter(4)
- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 5 operands: lhs = Counter(4), rhs = Expression(15, Sub)
- expression 6 operands: lhs = Expression(16, Sub), rhs = Counter(4)
- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 6 operands: lhs = Expression(8, Sub), rhs = Counter(5)
- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 8 operands: lhs = Expression(14, Add), rhs = Counter(5)
- expression 9 operands: lhs = Counter(4), rhs = Expression(15, Sub)
- expression 10 operands: lhs = Expression(16, Sub), rhs = Counter(4)
- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 12 operands: lhs = Counter(5), rhs = Expression(13, Sub)
- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(5)
- expression 14 operands: lhs = Counter(4), rhs = Expression(15, Sub)
- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(4)
- expression 16 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 17 operands: lhs = Counter(1), rhs = Counter(2)
- expression 8 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 9 operands: lhs = Counter(1), rhs = Counter(2)
Number of file 0 mappings: 13
- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 27)
- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
= (c0 + (c1 + c2))
- Code(Expression(16, Sub)) at (prev + 1, 12) to (start + 0, 25)
- Code(Expression(8, Sub)) at (prev + 1, 12) to (start + 0, 25)
= ((c0 + (c1 + c2)) - c3)
- Code(Counter(4)) at (prev + 0, 26) to (start + 2, 10)
- Code(Expression(15, Sub)) at (prev + 2, 10) to (start + 0, 11)
- Code(Expression(3, Sub)) at (prev + 2, 10) to (start + 0, 11)
= (((c0 + (c1 + c2)) - c3) - c4)
- Code(Expression(14, Add)) at (prev + 2, 12) to (start + 0, 25)
= (c4 + (((c0 + (c1 + c2)) - c3) - c4))
- Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 0, 25)
= ((c0 + (c1 + c2)) - c3)
- Code(Counter(5)) at (prev + 0, 26) to (start + 0, 49)
- Code(Expression(13, Sub)) at (prev + 0, 49) to (start + 0, 50)
= ((c4 + (((c0 + (c1 + c2)) - c3) - c4)) - c5)
- Code(Expression(12, Add)) at (prev + 4, 12) to (start + 0, 25)
= (c5 + ((c4 + (((c0 + (c1 + c2)) - c3) - c4)) - c5))
- Code(Expression(6, Sub)) at (prev + 0, 49) to (start + 0, 50)
= (((c0 + (c1 + c2)) - c3) - c5)
- Code(Expression(8, Sub)) at (prev + 4, 12) to (start + 0, 25)
= ((c0 + (c1 + c2)) - c3)
- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 49)
- Code(Counter(2)) at (prev + 0, 49) to (start + 0, 50)
- Code(Expression(17, Add)) at (prev + 1, 9) to (start + 0, 23)
- Code(Expression(9, Add)) at (prev + 1, 9) to (start + 0, 23)
= (c1 + c2)
- Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2)

Expand Down
16 changes: 6 additions & 10 deletions tests/coverage/async.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 25)

Function name: async::c::{closure#0}
Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 09, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02]
Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 09, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 9, 25) to (start + 1, 14)
- Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10)
- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 2, 1) to (start + 0, 2)
= (c1 + (c0 - c1))
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)

Function name: async::d
Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 14]
Expand Down Expand Up @@ -188,19 +186,17 @@ Number of file 0 mappings: 9
= ((c1 + c2) + c3)

Function name: async::j::c
Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 37, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06]
Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 37, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 01, 02, 05, 00, 06]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 55, 5) to (start + 1, 18)
- Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14)
- Code(Expression(0, Sub)) at (prev + 10, 13) to (start + 0, 14)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 2, 5) to (start + 0, 6)
= (c1 + (c0 - c1))
- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6)

Function name: async::j::d
Raw bytes (9): 0x[01, 01, 00, 01, 01, 46, 05, 00, 17]
Expand Down
16 changes: 6 additions & 10 deletions tests/coverage/async2.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 23)

Function name: async2::async_func::{closure#0}
Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 0d, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02]
Raw bytes (24): 0x[01, 01, 00, 04, 01, 0d, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Zero
Number of expressions: 0
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 13, 23) to (start + 3, 9)
- Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
- Code(Expression(0, Add)) at (prev + 1, 1) to (start + 0, 2)
= (c1 + Zero)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)

Function name: async2::async_func_just_println
Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 24]
Expand All @@ -44,15 +42,13 @@ Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 25, 1) to (start + 7, 2)

Function name: async2::non_async_func
Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 05, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02]
Raw bytes (24): 0x[01, 01, 00, 04, 01, 05, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 1
- expression 0 operands: lhs = Counter(1), rhs = Zero
Number of expressions: 0
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 9)
- Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
- Code(Expression(0, Add)) at (prev + 1, 1) to (start + 0, 2)
= (c1 + Zero)
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)

16 changes: 6 additions & 10 deletions tests/coverage/async_block.cov-map
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
Function name: async_block::main
Raw bytes (38): 0x[01, 01, 02, 01, 05, 03, 05, 06, 01, 05, 01, 00, 0b, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 13, 05, 00, 14, 01, 16, 05, 07, 0a, 02, 06, 06, 03, 01, 00, 02]
Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 05, 01, 00, 0b, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 13, 05, 00, 14, 01, 16, 05, 07, 0a, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(1)
Number of file 0 mappings: 6
- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 11)
- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 19)
= (c0 + c1)
- Code(Counter(1)) at (prev + 0, 20) to (start + 1, 22)
- Code(Counter(1)) at (prev + 7, 10) to (start + 2, 6)
- Code(Expression(1, Sub)) at (prev + 3, 1) to (start + 0, 2)
= ((c0 + c1) - c1)
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)

Function name: async_block::main::{closure#0}
Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 07, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 07, 03, 09, 00, 0a]
Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 07, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 7, 28) to (start + 1, 23)
- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
- Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 3, 9) to (start + 0, 10)
= (c1 + (c0 - c1))
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)

24 changes: 9 additions & 15 deletions tests/coverage/branch/generics.cov-map
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
Function name: generics::print_size::<()>
Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02]
Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 5
- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
Expand All @@ -13,16 +12,14 @@ Number of file 0 mappings: 5
- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 2, 6)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
= (c1 + (c0 - c1))
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)

Function name: generics::print_size::<u32>
Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02]
Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 5
- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
Expand All @@ -31,16 +28,14 @@ Number of file 0 mappings: 5
- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 2, 6)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
= (c1 + (c0 - c1))
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)

Function name: generics::print_size::<u64>
Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02]
Raw bytes (33): 0x[01, 01, 01, 01, 05, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 5
- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36)
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36)
Expand All @@ -49,6 +44,5 @@ Number of file 0 mappings: 5
- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 2, 6)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
= (c1 + (c0 - c1))
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)

Loading
Loading