about summary refs log tree commit diff
path: root/compiler/rustc_mir/src/transform/coverage/counters.rs
diff options
context:
space:
mode:
authorRich Kadel <richkadel@google.com>2020-10-23 00:45:07 -0700
committerRich Kadel <richkadel@google.com>2020-11-05 18:24:12 -0800
commitc7ae4c2cb6d7e58ad0f9c12047e3d747c26a9d71 (patch)
treefdbb5014c0353a7a29a61b07364575b04d81362a /compiler/rustc_mir/src/transform/coverage/counters.rs
parentc7747cc772f4b4c30ede3616678d7a3bc2c89bf7 (diff)
downloadrust-c7ae4c2cb6d7e58ad0f9c12047e3d747c26a9d71.tar.gz
rust-c7ae4c2cb6d7e58ad0f9c12047e3d747c26a9d71.zip
Splitting transform/instrument_coverage.rs into transform/coverage/...
Diffstat (limited to 'compiler/rustc_mir/src/transform/coverage/counters.rs')
-rw-r--r--compiler/rustc_mir/src/transform/coverage/counters.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs
new file mode 100644
index 00000000000..511ad937c24
--- /dev/null
+++ b/compiler/rustc_mir/src/transform/coverage/counters.rs
@@ -0,0 +1,54 @@
+use rustc_middle::mir::coverage::*;
+
+/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
+/// `Coverage` statements.
+pub(crate) struct CoverageCounters {
+    function_source_hash: u64,
+    next_counter_id: u32,
+    num_expressions: u32,
+}
+
+impl CoverageCounters {
+    pub fn new(function_source_hash: u64) -> Self {
+        Self {
+            function_source_hash,
+            next_counter_id: CounterValueReference::START.as_u32(),
+            num_expressions: 0,
+        }
+    }
+
+    pub fn make_counter(&mut self) -> CoverageKind {
+        CoverageKind::Counter {
+            function_source_hash: self.function_source_hash,
+            id: self.next_counter(),
+        }
+    }
+
+    pub fn make_expression(
+        &mut self,
+        lhs: ExpressionOperandId,
+        op: Op,
+        rhs: ExpressionOperandId,
+    ) -> CoverageKind {
+        let id = self.next_expression();
+        CoverageKind::Expression { id, lhs, op, rhs }
+    }
+
+    /// Counter IDs start from one and go up.
+    fn next_counter(&mut self) -> CounterValueReference {
+        assert!(self.next_counter_id < u32::MAX - self.num_expressions);
+        let next = self.next_counter_id;
+        self.next_counter_id += 1;
+        CounterValueReference::from(next)
+    }
+
+    /// Expression IDs start from u32::MAX and go down because a Expression can reference
+    /// (add or subtract counts) of both Counter regions and Expression regions. The counter
+    /// expression operand IDs must be unique across both types.
+    fn next_expression(&mut self) -> InjectedExpressionId {
+        assert!(self.next_counter_id < u32::MAX - self.num_expressions);
+        let next = u32::MAX - self.num_expressions;
+        self.num_expressions += 1;
+        InjectedExpressionId::from(next)
+    }
+}