Skip to content

Commit aa9747d

Browse files
committed
optimized replacement of counters with expressions plus new BCB graphviz
1 parent dcb4b24 commit aa9747d

File tree

53 files changed

+1778
-709
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1778
-709
lines changed

compiler/rustc_codegen_ssa/src/coverageinfo/map.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ pub struct FunctionCoverage {
3838
impl FunctionCoverage {
3939
pub fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
4040
let coverageinfo = tcx.coverageinfo(instance.def_id());
41+
debug!(
42+
"FunctionCoverage::new(instance={:?}) has coverageinfo={:?}",
43+
instance, coverageinfo
44+
);
4145
Self {
4246
source_hash: 0, // will be set with the first `add_counter()`
4347
counters: IndexVec::from_elem_n(None, coverageinfo.num_counters as usize),
@@ -150,13 +154,41 @@ impl FunctionCoverage {
150154
self.counters
151155
.get(index)
152156
.unwrap() // pre-validated
157+
// TODO(richkadel): is it really pre-validated?
158+
// What if I add some counters that never get added to the map, and they are
159+
// larger than the number of counters in the MIR (as seems to happen with expressions below?)
153160
.as_ref()
154161
.map(|_| Counter::counter_value_reference(index))
155162
} else {
156163
let index = self.expression_index(u32::from(id));
164+
// TODO(richkadel): remove this debug
165+
debug!(
166+
"id_to_counter expression id={:?}, self.expressions.get(index={:?}) = {:?}",
167+
id,
168+
index,
169+
self.expressions.get(index)
170+
);
157171
self.expressions
158172
.get(index)
173+
// TODO(richkadel): Now some tests generate segfault, and other tests hit this out of range error
174+
// Some expressions reference blocks that ended up not needing counters.
175+
// Can we assume the expression is no longer relevant? If not, then instrument_counters
176+
// transform pass will need to figure this out earlier (MAYBE IT SHOULD ANYWAY?)
177+
// and if the counter is needed for an expression that can no longer be resolved,
178+
// create a new make_counter() right there?
179+
//
180+
// MUST FIX!
181+
//
182+
// It looks like the segfault is at:
183+
//
184+
// /usr/local/google/home/richkadel/rust/src/llvm-project/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp:93
185+
// AdjustedExpressionIDs[ID] = 1;
186+
//
187+
// I think we have expressions with operand IDs that don't exist as either counters or expressions, and that's breaking
188+
// the LLVM code.
189+
// TODO(richkadel): replace expect() with unwrap_or()?
159190
.expect("expression id is out of range")
191+
// .unwrap_or(&None)
160192
.as_ref()
161193
.map(|_| Counter::expression(new_indexes[index]))
162194
}
@@ -198,6 +230,12 @@ impl FunctionCoverage {
198230
if let Some(region) = optional_region {
199231
expression_regions.push((Counter::expression(mapped_expression_index), region));
200232
}
233+
} else {
234+
debug!(
235+
"Ignoring expression with one or more missing operands: \
236+
original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}",
237+
original_index, lhs, op, rhs, optional_region,
238+
)
201239
}
202240
}
203241
(counter_expressions, expression_regions.into_iter())

compiler/rustc_graphviz/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ where
643643
}
644644
if options.contains(&RenderOption::DarkTheme) {
645645
graph_attrs.push(r#"bgcolor="black""#);
646+
graph_attrs.push(r#"fontcolor="white""#);
646647
content_attrs.push(r#"color="white""#);
647648
content_attrs.push(r#"fontcolor="white""#);
648649
}

compiler/rustc_middle/src/mir/coverage.rs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,28 @@ impl From<CounterValueReference> for ExpressionOperandId {
6464
}
6565
}
6666

67+
impl From<&mut CounterValueReference> for ExpressionOperandId {
68+
#[inline]
69+
fn from(v: &mut CounterValueReference) -> ExpressionOperandId {
70+
ExpressionOperandId::from(v.as_u32())
71+
}
72+
}
73+
6774
impl From<InjectedExpressionIndex> for ExpressionOperandId {
6875
#[inline]
6976
fn from(v: InjectedExpressionIndex) -> ExpressionOperandId {
7077
ExpressionOperandId::from(v.as_u32())
7178
}
7279
}
7380

74-
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
81+
impl From<&mut InjectedExpressionIndex> for ExpressionOperandId {
82+
#[inline]
83+
fn from(v: &mut InjectedExpressionIndex) -> ExpressionOperandId {
84+
ExpressionOperandId::from(v.as_u32())
85+
}
86+
}
87+
88+
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
7589
pub enum CoverageKind {
7690
Counter {
7791
function_source_hash: u64,
@@ -88,14 +102,51 @@ pub enum CoverageKind {
88102

89103
impl CoverageKind {
90104
pub fn as_operand_id(&self) -> ExpressionOperandId {
105+
use CoverageKind::*;
91106
match *self {
92-
CoverageKind::Counter { id, .. } => ExpressionOperandId::from(id),
93-
CoverageKind::Expression { id, .. } => ExpressionOperandId::from(id),
94-
CoverageKind::Unreachable => {
107+
Counter { id, .. } => ExpressionOperandId::from(id),
108+
Expression { id, .. } => ExpressionOperandId::from(id),
109+
Unreachable => {
95110
bug!("Unreachable coverage cannot be part of an expression")
96111
}
97112
}
98113
}
114+
115+
pub fn is_counter(&self) -> bool {
116+
match self {
117+
Self::Counter { .. } => true,
118+
_ => false,
119+
}
120+
}
121+
122+
pub fn is_expression(&self) -> bool {
123+
match self {
124+
Self::Expression { .. } => true,
125+
_ => false,
126+
}
127+
}
128+
129+
pub fn is_unreachable(&self) -> bool {
130+
*self == Self::Unreachable
131+
}
132+
}
133+
134+
impl Debug for CoverageKind {
135+
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
136+
use CoverageKind::*;
137+
match self {
138+
Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()),
139+
Expression { id, lhs, op, rhs } => write!(
140+
fmt,
141+
"Expression({:?}) = {} {} {}",
142+
id.index(),
143+
lhs.index(),
144+
if *op == Op::Add { "+" } else { "-" },
145+
rhs.index(),
146+
),
147+
Unreachable => write!(fmt, "Unreachable"),
148+
}
149+
}
99150
}
100151

101152
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, PartialEq, Eq, PartialOrd, Ord)]

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,21 +1601,10 @@ impl Debug for Statement<'_> {
16011601
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
16021602
}
16031603
Coverage(box ref coverage) => {
1604-
let rgn = &coverage.code_region;
1605-
match coverage.kind {
1606-
CoverageKind::Counter { id, .. } => {
1607-
write!(fmt, "Coverage::Counter({:?}) for {:?}", id.index(), rgn)
1608-
}
1609-
CoverageKind::Expression { id, lhs, op, rhs } => write!(
1610-
fmt,
1611-
"Coverage::Expression({:?}) = {} {} {} for {:?}",
1612-
id.index(),
1613-
lhs.index(),
1614-
if op == coverage::Op::Add { "+" } else { "-" },
1615-
rhs.index(),
1616-
rgn
1617-
),
1618-
CoverageKind::Unreachable => write!(fmt, "Coverage::Unreachable for {:?}", rgn),
1604+
if let Some(rgn) = &coverage.code_region {
1605+
write!(fmt, "Coverage::{:?} for {:?}", coverage.kind, rgn)
1606+
} else {
1607+
write!(fmt, "Coverage::{:?}", coverage.kind)
16191608
}
16201609
}
16211610
Nop => write!(fmt, "nop"),

0 commit comments

Comments
 (0)