Skip to content

Commit 4169d0f

Browse files
committed
Narrow trait CoverageInfoBuilderMethods down to just one method
This effectively inlines most of `FunctionCx::codegen_coverage` into the LLVM implementation of `CoverageInfoBuilderMethods`.
1 parent 6dab6dc commit 4169d0f

File tree

5 files changed

+69
-102
lines changed

5 files changed

+69
-102
lines changed

compiler/rustc_codegen_gcc/src/coverageinfo.rs

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,15 @@
11
use gccjit::RValue;
22
use rustc_codegen_ssa::traits::{CoverageInfoBuilderMethods, CoverageInfoMethods};
33
use rustc_hir::def_id::DefId;
4-
use rustc_middle::mir::coverage::{
5-
CodeRegion,
6-
CounterValueReference,
7-
ExpressionOperandId,
8-
InjectedExpressionId,
9-
Op,
10-
};
4+
use rustc_middle::mir::Coverage;
115
use rustc_middle::ty::Instance;
126

137
use crate::builder::Builder;
148
use crate::context::CodegenCx;
159

1610
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
17-
fn set_function_source_hash(
18-
&mut self,
19-
_instance: Instance<'tcx>,
20-
_function_source_hash: u64,
21-
) -> bool {
22-
unimplemented!();
23-
}
24-
25-
fn add_coverage_counter(&mut self, _instance: Instance<'tcx>, _id: CounterValueReference, _region: CodeRegion) -> bool {
26-
// TODO(antoyo)
27-
false
28-
}
29-
30-
fn add_coverage_counter_expression(&mut self, _instance: Instance<'tcx>, _id: InjectedExpressionId, _lhs: ExpressionOperandId, _op: Op, _rhs: ExpressionOperandId, _region: Option<CodeRegion>) -> bool {
31-
// TODO(antoyo)
32-
false
33-
}
34-
35-
fn add_coverage_unreachable(&mut self, _instance: Instance<'tcx>, _region: CodeRegion) -> bool {
11+
fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) {
3612
// TODO(antoyo)
37-
false
3813
}
3914
}
4015

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+57-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ use rustc_hir::def_id::DefId;
1717
use rustc_llvm::RustString;
1818
use rustc_middle::bug;
1919
use rustc_middle::mir::coverage::{
20-
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
20+
CodeRegion, CounterValueReference, CoverageKind, ExpressionOperandId, InjectedExpressionId, Op,
2121
};
22+
use rustc_middle::mir::Coverage;
2223
use rustc_middle::ty;
23-
use rustc_middle::ty::layout::FnAbiOf;
24+
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
2425
use rustc_middle::ty::subst::InternalSubsts;
2526
use rustc_middle::ty::Instance;
2627

@@ -94,6 +95,54 @@ impl<'ll, 'tcx> CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
9495
}
9596

9697
impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
98+
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage) {
99+
let bx = self;
100+
101+
let Coverage { kind, code_region } = coverage.clone();
102+
match kind {
103+
CoverageKind::Counter { function_source_hash, id } => {
104+
if bx.set_function_source_hash(instance, function_source_hash) {
105+
// If `set_function_source_hash()` returned true, the coverage map is enabled,
106+
// so continue adding the counter.
107+
if let Some(code_region) = code_region {
108+
// Note: Some counters do not have code regions, but may still be referenced
109+
// from expressions. In that case, don't add the counter to the coverage map,
110+
// but do inject the counter intrinsic.
111+
bx.add_coverage_counter(instance, id, code_region);
112+
}
113+
114+
let coverageinfo = bx.tcx().coverageinfo(instance.def);
115+
116+
let fn_name = bx.get_pgo_func_name_var(instance);
117+
let hash = bx.const_u64(function_source_hash);
118+
let num_counters = bx.const_u32(coverageinfo.num_counters);
119+
let index = bx.const_u32(id.zero_based_index());
120+
debug!(
121+
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
122+
fn_name, hash, num_counters, index,
123+
);
124+
bx.instrprof_increment(fn_name, hash, num_counters, index);
125+
}
126+
}
127+
CoverageKind::Expression { id, lhs, op, rhs } => {
128+
bx.add_coverage_counter_expression(instance, id, lhs, op, rhs, code_region);
129+
}
130+
CoverageKind::Unreachable => {
131+
bx.add_coverage_unreachable(
132+
instance,
133+
code_region.expect("unreachable regions always have code regions"),
134+
);
135+
}
136+
}
137+
}
138+
}
139+
140+
// These methods used to be part of trait `CoverageInfoBuilderMethods`, but
141+
// after moving most coverage code out of SSA they are now just ordinary methods.
142+
impl<'tcx> Builder<'_, '_, 'tcx> {
143+
/// Returns true if the function source hash was added to the coverage map (even if it had
144+
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
145+
/// not enabled (a coverage map is not being generated).
97146
fn set_function_source_hash(
98147
&mut self,
99148
instance: Instance<'tcx>,
@@ -115,6 +164,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
115164
}
116165
}
117166

167+
/// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
168+
/// is not enabled (a coverage map is not being generated).
118169
fn add_coverage_counter(
119170
&mut self,
120171
instance: Instance<'tcx>,
@@ -137,6 +188,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
137188
}
138189
}
139190

191+
/// Returns true if the expression was added to the coverage map; false if
192+
/// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
140193
fn add_coverage_counter_expression(
141194
&mut self,
142195
instance: Instance<'tcx>,
@@ -163,6 +216,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
163216
}
164217
}
165218

219+
/// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
220+
/// is not enabled (a coverage map is not being generated).
166221
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool {
167222
if let Some(coverage_context) = self.coverage_context() {
168223
debug!(
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,20 @@
11
use crate::traits::*;
22

3-
use rustc_middle::mir::coverage::*;
43
use rustc_middle::mir::Coverage;
54
use rustc_middle::mir::SourceScope;
65

76
use super::FunctionCx;
87

98
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10-
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage, scope: SourceScope) {
9+
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: &Coverage, scope: SourceScope) {
1110
// Determine the instance that coverage data was originally generated for.
1211
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
1312
self.monomorphize(inlined)
1413
} else {
1514
self.instance
1615
};
1716

18-
let Coverage { kind, code_region } = coverage;
19-
match kind {
20-
CoverageKind::Counter { function_source_hash, id } => {
21-
if bx.set_function_source_hash(instance, function_source_hash) {
22-
// If `set_function_source_hash()` returned true, the coverage map is enabled,
23-
// so continue adding the counter.
24-
if let Some(code_region) = code_region {
25-
// Note: Some counters do not have code regions, but may still be referenced
26-
// from expressions. In that case, don't add the counter to the coverage map,
27-
// but do inject the counter intrinsic.
28-
bx.add_coverage_counter(instance, id, code_region);
29-
}
30-
31-
let coverageinfo = bx.tcx().coverageinfo(instance.def);
32-
33-
let fn_name = bx.get_pgo_func_name_var(instance);
34-
let hash = bx.const_u64(function_source_hash);
35-
let num_counters = bx.const_u32(coverageinfo.num_counters);
36-
let index = bx.const_u32(id.zero_based_index());
37-
debug!(
38-
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
39-
fn_name, hash, num_counters, index,
40-
);
41-
bx.instrprof_increment(fn_name, hash, num_counters, index);
42-
}
43-
}
44-
CoverageKind::Expression { id, lhs, op, rhs } => {
45-
bx.add_coverage_counter_expression(instance, id, lhs, op, rhs, code_region);
46-
}
47-
CoverageKind::Unreachable => {
48-
bx.add_coverage_unreachable(
49-
instance,
50-
code_region.expect("unreachable regions always have code regions"),
51-
);
52-
}
53-
}
17+
// Handle the coverage info in a backend-specific way.
18+
bx.add_coverage(instance, coverage);
5419
}
5520
}

compiler/rustc_codegen_ssa/src/mir/statement.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6565
}
6666
}
6767
mir::StatementKind::Coverage(box ref coverage) => {
68-
self.codegen_coverage(bx, coverage.clone(), statement.source_info.scope);
68+
self.codegen_coverage(bx, coverage, statement.source_info.scope);
6969
}
7070
mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
7171
let op_val = self.codegen_operand(bx, op);
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::BackendTypes;
22
use rustc_hir::def_id::DefId;
3-
use rustc_middle::mir::coverage::*;
3+
use rustc_middle::mir::Coverage;
44
use rustc_middle::ty::Instance;
55

66
pub trait CoverageInfoMethods<'tcx>: BackendTypes {
@@ -21,37 +21,9 @@ pub trait CoverageInfoMethods<'tcx>: BackendTypes {
2121
}
2222

2323
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
24-
/// Returns true if the function source hash was added to the coverage map (even if it had
25-
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
26-
/// not enabled (a coverage map is not being generated).
27-
fn set_function_source_hash(
28-
&mut self,
29-
instance: Instance<'tcx>,
30-
function_source_hash: u64,
31-
) -> bool;
32-
33-
/// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
34-
/// is not enabled (a coverage map is not being generated).
35-
fn add_coverage_counter(
36-
&mut self,
37-
instance: Instance<'tcx>,
38-
index: CounterValueReference,
39-
region: CodeRegion,
40-
) -> bool;
41-
42-
/// Returns true if the expression was added to the coverage map; false if
43-
/// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
44-
fn add_coverage_counter_expression(
45-
&mut self,
46-
instance: Instance<'tcx>,
47-
id: InjectedExpressionId,
48-
lhs: ExpressionOperandId,
49-
op: Op,
50-
rhs: ExpressionOperandId,
51-
region: Option<CodeRegion>,
52-
) -> bool;
53-
54-
/// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
55-
/// is not enabled (a coverage map is not being generated).
56-
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool;
24+
/// Handle the MIR coverage info in a backend-specific way.
25+
///
26+
/// This can potentially be a no-op in backends that don't support
27+
/// coverage instrumentation.
28+
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage);
5729
}

0 commit comments

Comments
 (0)