Replace ExpressionOperandId
with enum Operand
Because the three kinds of operand are now distinguished explicitly, we no longer need fiddly code to disambiguate counter IDs and expression IDs based on the total number of counters/expressions in a function. This does increase the size of operands from 4 bytes to 8 bytes, but that shouldn't be a big deal since they are mostly stored inside boxed structures, and the current coverage code is not particularly size-optimized anyway.
This commit is contained in:
parent
5a808d40f4
commit
1a014d42f4
11 changed files with 96 additions and 147 deletions
|
@ -3,17 +3,17 @@ pub use super::ffi::*;
|
|||
use rustc_index::{IndexSlice, IndexVec};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::coverage::{
|
||||
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId,
|
||||
InjectedExpressionIndex, MappedExpressionIndex, Op,
|
||||
CodeRegion, CounterValueReference, InjectedExpressionId, InjectedExpressionIndex,
|
||||
MappedExpressionIndex, Op, Operand,
|
||||
};
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Expression {
|
||||
lhs: ExpressionOperandId,
|
||||
lhs: Operand,
|
||||
op: Op,
|
||||
rhs: ExpressionOperandId,
|
||||
rhs: Operand,
|
||||
region: Option<CodeRegion>,
|
||||
}
|
||||
|
||||
|
@ -105,16 +105,16 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
|||
pub fn add_counter_expression(
|
||||
&mut self,
|
||||
expression_id: InjectedExpressionId,
|
||||
lhs: ExpressionOperandId,
|
||||
lhs: Operand,
|
||||
op: Op,
|
||||
rhs: ExpressionOperandId,
|
||||
rhs: Operand,
|
||||
region: Option<CodeRegion>,
|
||||
) {
|
||||
debug!(
|
||||
"add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}",
|
||||
expression_id, lhs, op, rhs, region
|
||||
);
|
||||
let expression_index = self.expression_index(u32::from(expression_id));
|
||||
let expression_index = self.expression_index(expression_id);
|
||||
debug_assert!(
|
||||
expression_index.as_usize() < self.expressions.len(),
|
||||
"expression_index {} is out of range for expressions.len() = {}
|
||||
|
@ -186,10 +186,7 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
|||
|
||||
// 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. Operand ID value `0` maps to `CounterKind::Zero`; values in the known range
|
||||
// of injected LLVM counters map to `CounterKind::CounterValueReference` (and the value
|
||||
// matches the injected counter index); and any other value is converted into a
|
||||
// `CounterKind::Expression` with the expression's `new_index`.
|
||||
// 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,
|
||||
|
@ -206,17 +203,13 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
|||
// `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`.
|
||||
let id_to_counter = |new_indexes: &IndexSlice<
|
||||
InjectedExpressionIndex,
|
||||
Option<MappedExpressionIndex>,
|
||||
>,
|
||||
id: ExpressionOperandId| {
|
||||
if id == ExpressionOperandId::ZERO {
|
||||
Some(Counter::zero())
|
||||
} else if id.index() < self.counters.len() {
|
||||
type NewIndexes = IndexSlice<InjectedExpressionIndex, Option<MappedExpressionIndex>>;
|
||||
let id_to_counter = |new_indexes: &NewIndexes, operand: Operand| match operand {
|
||||
Operand::Zero => Some(Counter::zero()),
|
||||
Operand::Counter(id) => {
|
||||
debug_assert!(
|
||||
id.index() > 0,
|
||||
"ExpressionOperandId indexes for counters are 1-based, but this id={}",
|
||||
"Operand::Counter indexes for counters are 1-based, but this id={}",
|
||||
id.index()
|
||||
);
|
||||
// Note: Some codegen-injected Counters may be only referenced by `Expression`s,
|
||||
|
@ -224,8 +217,9 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
|||
let index = CounterValueReference::from(id.index());
|
||||
// Note, the conversion to LLVM `Counter` adjusts the index to be zero-based.
|
||||
Some(Counter::counter_value_reference(index))
|
||||
} else {
|
||||
let index = self.expression_index(u32::from(id));
|
||||
}
|
||||
Operand::Expression(id) => {
|
||||
let index = self.expression_index(id);
|
||||
self.expressions
|
||||
.get(index)
|
||||
.expect("expression id is out of range")
|
||||
|
@ -341,8 +335,9 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
|||
self.unreachable_regions.iter().map(|region| (Counter::zero(), region))
|
||||
}
|
||||
|
||||
fn expression_index(&self, id_descending_from_max: u32) -> InjectedExpressionIndex {
|
||||
debug_assert!(id_descending_from_max >= self.counters.len() as u32);
|
||||
fn expression_index(&self, id: InjectedExpressionId) -> InjectedExpressionIndex {
|
||||
debug_assert!(id.as_usize() >= self.counters.len());
|
||||
let id_descending_from_max = id.as_u32();
|
||||
InjectedExpressionIndex::from(u32::MAX - id_descending_from_max)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_llvm::RustString;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::coverage::{
|
||||
CodeRegion, CounterValueReference, CoverageKind, ExpressionOperandId, InjectedExpressionId, Op,
|
||||
CodeRegion, CounterValueReference, CoverageKind, InjectedExpressionId, Op, Operand,
|
||||
};
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::ty;
|
||||
|
@ -203,9 +203,9 @@ impl<'tcx> Builder<'_, '_, 'tcx> {
|
|||
&mut self,
|
||||
instance: Instance<'tcx>,
|
||||
id: InjectedExpressionId,
|
||||
lhs: ExpressionOperandId,
|
||||
lhs: Operand,
|
||||
op: Op,
|
||||
rhs: ExpressionOperandId,
|
||||
rhs: Operand,
|
||||
region: Option<CodeRegion>,
|
||||
) -> bool {
|
||||
if let Some(coverage_context) = self.coverage_context() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue