Skip to content

Commit 976a931

Browse files
Lambdariszhuyunxing
authored andcommitted
coverage. Change assign statements cl does not support on c++17 and fix code according to reviews
1 parent b2754ec commit 976a931

File tree

11 files changed

+181
-116
lines changed

11 files changed

+181
-116
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{
2525
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
2626
TyAndLayout,
2727
};
28-
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance};
28+
use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt};
2929
use rustc_span::def_id::DefId;
3030
use rustc_span::Span;
3131
use rustc_target::abi::{
@@ -1737,6 +1737,41 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
17371737
) {
17381738
unimplemented!();
17391739
}
1740+
1741+
fn mcdc_parameters(
1742+
&mut self,
1743+
_fn_name: Self::Value,
1744+
_hash: Self::Value,
1745+
_bitmap_bytes: Self::Value,
1746+
) -> Self::Value {
1747+
unimplemented!();
1748+
}
1749+
1750+
fn mcdc_tvbitmap_update(
1751+
&mut self,
1752+
_fn_name: Self::Value,
1753+
_hash: Self::Value,
1754+
_bitmap_bytes: Self::Value,
1755+
_bitmap_index: Self::Value,
1756+
_mcdc_temp: Self::Value,
1757+
) {
1758+
unimplemented!();
1759+
}
1760+
1761+
fn mcdc_condbitmap_update(
1762+
&mut self,
1763+
_fn_name: Self::Value,
1764+
_hash: Self::Value,
1765+
_cond_loc: Self::Value,
1766+
_mcdc_temp: Self::Value,
1767+
_bool_value: Self::Value,
1768+
) {
1769+
unimplemented!();
1770+
}
1771+
1772+
fn mcdc_condbitmap_reset(&mut self, _mcdc_temp: Self::Value) {
1773+
unimplemented!();
1774+
}
17401775
}
17411776

17421777
impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {

compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub mod mcdc {
115115

116116
/// Must match the layout of `LLVMRustMCDCDecisionParameters`.
117117
#[repr(C)]
118-
#[derive(Clone, Copy, Debug)]
118+
#[derive(Clone, Copy, Debug, Default)]
119119
pub struct DecisionParameters {
120120
bitmap_idx: u32,
121121
conditions_num: u16,
@@ -126,19 +126,47 @@ pub mod mcdc {
126126

127127
/// Must match the layout of `LLVMRustMCDCBranchParameters`.
128128
#[repr(C)]
129-
#[derive(Clone, Copy, Debug)]
129+
#[derive(Clone, Copy, Debug, Default)]
130130
pub struct BranchParameters {
131131
condition_id: LLVMConditionId,
132132
condition_ids: [LLVMConditionId; 2],
133133
}
134134

135-
/// Same layout with `LLVMRustMCDCParameters`
136135
#[repr(C, u8)]
137-
#[derive(Clone, Copy, Debug)]
138-
pub enum Parameters {
136+
pub enum ParameterTag {
139137
None,
140-
Decision(DecisionParameters),
141-
Branch(BranchParameters),
138+
Decision,
139+
Branch,
140+
}
141+
/// Same layout with `LLVMRustMCDCParameters`
142+
#[repr(C)]
143+
#[derive(Clone, Copy, Debug)]
144+
pub struct Parameters {
145+
tag: ParameterTag,
146+
decision_params: DecisionParameters,
147+
branch_params: BranchParameters,
148+
}
149+
150+
impl Parameters {
151+
pub fn none() -> Self {
152+
Self {
153+
tag: ParameterTag::None,
154+
decision_params: Default::default(),
155+
branch_params: Default::default(),
156+
}
157+
}
158+
pub fn decision(decision_params: DecisionParameters) -> Self {
159+
Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() }
160+
}
161+
pub fn branch(branch_params: BranchParameters) -> Self {
162+
Self { tag: ParameterTag::Branch, decision_params: Default, branch_params }
163+
}
164+
}
165+
166+
impl Default for Parameters {
167+
fn default() -> Self {
168+
Self::none()
169+
}
142170
}
143171

144172
impl From<ConditionInfo> for BranchParameters {
@@ -287,14 +315,9 @@ impl CounterMappingRegion {
287315
end_line: u32,
288316
end_col: u32,
289317
) -> Self {
290-
let mcdc_params = condition_info
291-
.map(mcdc::BranchParameters::from)
292-
.map(mcdc::Parameters::Branch)
293-
.unwrap_or(mcdc::Parameters::None);
294-
let kind = match mcdc_params {
295-
mcdc::Parameters::None => RegionKind::BranchRegion,
296-
mcdc::Parameters::Branch(_) => RegionKind::MCDCBranchRegion,
297-
_ => unreachable!("invalid mcdc params for branch"),
318+
let (kind, mcdc_params) = match condition_info {
319+
Some(info) => (RegionKind::MCDCBranchRegion, mcdc::Parameters::branch(info.into())),
320+
None => (RegionKind::BranchRegion, Default::default()),
298321
};
299322
Self {
300323
counter,

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,20 +188,20 @@ fn ensure_mcdc_parameters<'ll, 'tcx>(
188188
instance: Instance<'tcx>,
189189
function_coverage_info: &FunctionCoverageInfo,
190190
) {
191-
if bx
192-
.coverage_context()
193-
.is_some_and(|cx| !cx.mcdc_condition_bitmap_map.borrow().contains_key(&instance))
194-
{
195-
let fn_name = bx.get_pgo_func_name_var(instance);
196-
let hash = bx.const_u64(function_coverage_info.function_source_hash);
197-
let bitmap_bytes = bx.const_u32(function_coverage_info.mcdc_bitmap_bytes);
198-
let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes);
199-
bx.coverage_context()
200-
.unwrap()
201-
.mcdc_condition_bitmap_map
202-
.borrow_mut()
203-
.insert(instance, cond_bitmap);
191+
let Some(cx) = bx.coverage_context() else { return };
192+
if cx.mcdc_condition_bitmap_map.borrow().contains_key(&instance) {
193+
return;
204194
}
195+
196+
let fn_name = bx.get_pgo_func_name_var(instance);
197+
let hash = bx.const_u64(function_coverage_info.function_source_hash);
198+
let bitmap_bytes = bx.const_u32(function_coverage_info.mcdc_bitmap_bytes);
199+
let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes);
200+
bx.coverage_context()
201+
.expect("already checked above")
202+
.mcdc_condition_bitmap_map
203+
.borrow_mut()
204+
.insert(instance, cond_bitmap);
205205
}
206206

207207
/// Calls llvm::createPGOFuncNameVar() with the given function instance's

compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -82,38 +82,64 @@ struct LLVMRustMCDCBranchParameters {
8282
int16_t ConditionIDs[2];
8383
};
8484

85-
union LLVMRustMCDCParametersPayload {
86-
LLVMRustMCDCDecisionParameters DecisionParameters;
87-
LLVMRustMCDCBranchParameters BranchParameters;
88-
};
89-
9085
struct LLVMRustMCDCParameters {
9186
LLVMRustMCDCParametersTag Tag;
92-
LLVMRustMCDCParametersPayload Payload;
87+
LLVMRustMCDCDecisionParameters DecisionParameters;
88+
LLVMRustMCDCBranchParameters BranchParameters;
9389
};
9490

91+
// LLVM representations for `MCDCParameters` evolved from LLVM 18 to 19.
92+
// Look at representations in 18
93+
// https://github.com/rust-lang/llvm-project/blob/66a2881a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L253-L263
94+
// and representations in 19
95+
// https://github.com/llvm/llvm-project/blob/843cc474faefad1d639f4c44c1cf3ad7dbda76c8/llvm/include/llvm/ProfileData/Coverage/MCDCTypes.h
96+
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
9597
static coverage::CounterMappingRegion::MCDCParameters
9698
fromRust(LLVMRustMCDCParameters Params) {
99+
auto parameter = coverage::CounterMappingRegion::MCDCParameters{};
97100
switch (Params.Tag) {
98101
case LLVMRustMCDCParametersTag::None:
99-
return coverage::CounterMappingRegion::MCDCParameters{};
102+
return parameter;
100103
case LLVMRustMCDCParametersTag::Decision:
101-
return coverage::CounterMappingRegion::MCDCParameters{
102-
.BitmapIdx =
103-
static_cast<unsigned>(Params.Payload.DecisionParameters.BitmapIdx),
104-
.NumConditions = static_cast<unsigned>(
105-
Params.Payload.DecisionParameters.NumConditions)};
104+
parameter.BitmapIdx =
105+
static_cast<unsigned>(Params.Payload.DecisionParameters.BitmapIdx),
106+
parameter.NumConditions =
107+
static_cast<unsigned>(Params.Payload.DecisionParameters.NumConditions);
108+
return parameter;
106109
case LLVMRustMCDCParametersTag::Branch:
107-
return coverage::CounterMappingRegion::MCDCParameters{
108-
.ID = static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
109-
Params.Payload.BranchParameters.ConditionID),
110-
.FalseID = static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
110+
parameter.ID = static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
111+
Params.Payload.BranchParameters.ConditionID),
112+
parameter.FalseID =
113+
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
111114
Params.Payload.BranchParameters.ConditionIDs[0]),
112-
.TrueID = static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
113-
Params.Payload.BranchParameters.ConditionIDs[1])};
115+
parameter.TrueID =
116+
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
117+
Params.Payload.BranchParameters.ConditionIDs[1]);
118+
return parameter;
119+
}
120+
report_fatal_error("Bad LLVMRustMCDCParametersTag!");
121+
}
122+
#elif LLVM_VERSION_GE(19, 0)
123+
static coverage::mcdc::MCDCParameters fromRust(LLVMRustMCDCParameters Params) {
124+
switch (Params.Tag) {
125+
case LLVMRustMCDCParametersTag::None:
126+
return coverage::mcdc::MCDCParameters;
127+
case LLVMRustMCDCParametersTag::Decision:
128+
return coverage::mcdc::DecisionParameters(
129+
Params.Payload.DecisionParameters.BitmapIdx,
130+
Params.Payload.DecisionParameters.NumConditions);
131+
case LLVMRustMCDCParametersTag::Branch:
132+
return coverage::mcdc::BranchParameters(
133+
static_cast<coverage::mcdc::ConditionID>(
134+
Params.Payload.BranchParameters.ConditionID),
135+
{static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
136+
Params.Payload.BranchParameters.ConditionIDs[0]),
137+
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
138+
Params.Payload.BranchParameters.ConditionIDs[1])});
114139
}
115140
report_fatal_error("Bad LLVMRustMCDCParametersTag!");
116141
}
142+
#endif
117143

118144
// FFI equivalent of struct `llvm::coverage::CounterMappingRegion`
119145
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L211-L304
@@ -188,7 +214,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
188214
RustMappingRegions, NumMappingRegions)) {
189215
MappingRegions.emplace_back(
190216
fromRust(Region.Count), fromRust(Region.FalseCount),
191-
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
217+
#if LLVM_VERSION_GE(18, 0)
192218
fromRust(Region.MCDCParameters),
193219
#endif
194220
Region.FileID, Region.ExpandedFileID, // File IDs, then region info.

compiler/rustc_middle/src/mir/coverage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ impl MappingKind {
225225
let two = |a, b| Some(a).into_iter().chain(Some(b));
226226
match *self {
227227
Self::Code(term) => one(term),
228-
Self::Branch { true_term, false_term, .. } => two(true_term, false_term),
228+
Self::Branch { true_term, false_term } => two(true_term, false_term),
229229
Self::MCDCBranch { true_term, false_term, .. } => two(true_term, false_term),
230230
Self::MCDCDecision(_) => zero(),
231231
}

compiler/rustc_mir_transform/src/coverage/mod.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,27 +142,24 @@ fn create_mappings<'tcx>(
142142

143143
mappings.extend(coverage_spans.all_bcb_mappings().filter_map(
144144
|BcbMapping { kind: bcb_mapping_kind, span }| {
145-
let kind = match bcb_mapping_kind {
146-
BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(*bcb)),
145+
let kind = match *bcb_mapping_kind {
146+
BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)),
147147
BcbMappingKind::Branch { true_bcb, false_bcb, condition_info } => {
148148
if condition_info.condition_id == ConditionId::NONE {
149149
MappingKind::Branch {
150-
true_term: term_for_bcb(*true_bcb),
151-
false_term: term_for_bcb(*false_bcb),
150+
true_term: term_for_bcb(true_bcb),
151+
false_term: term_for_bcb(false_bcb),
152152
}
153153
} else {
154154
MappingKind::MCDCBranch {
155-
true_term: term_for_bcb(*true_bcb),
156-
false_term: term_for_bcb(*false_bcb),
157-
mcdc_params: *condition_info,
155+
true_term: term_for_bcb(true_bcb),
156+
false_term: term_for_bcb(false_bcb),
157+
mcdc_params: condition_info,
158158
}
159159
}
160160
}
161161
BcbMappingKind::Decision { bitmap_idx, conditions_num, .. } => {
162-
MappingKind::MCDCDecision(DecisionInfo {
163-
bitmap_idx: *bitmap_idx,
164-
conditions_num: *conditions_num,
165-
})
162+
MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num })
166163
}
167164
};
168165
let code_region = make_code_region(source_map, file_name, *span, body_span)?;
@@ -236,12 +233,10 @@ fn inject_mcdc_statements<'tcx>(
236233
return;
237234
}
238235

239-
// Inject test vector update first because inject statement always inject new statement at head.
236+
// Inject test vector update first because `inject_statement` always insert new statement at head.
240237
for (end_bcbs, bitmap_idx) in
241238
coverage_spans.all_bcb_mappings().filter_map(|mapping| match &mapping.kind {
242-
BcbMappingKind::Decision { end_bcbs: end_bcb, bitmap_idx, .. } => {
243-
Some((end_bcb, *bitmap_idx))
244-
}
239+
BcbMappingKind::Decision { end_bcbs, bitmap_idx, .. } => Some((end_bcbs, *bitmap_idx)),
245240
_ => None,
246241
})
247242
{

compiler/rustc_mir_transform/src/coverage/spans.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,18 @@ pub(super) fn generate_coverage_spans(
100100
};
101101
let mut test_vector_bitmap_bytes = 0;
102102
for BcbMapping { kind, span: _ } in &mappings {
103-
match kind {
104-
BcbMappingKind::Code(bcb) => insert(*bcb),
103+
match *kind {
104+
BcbMappingKind::Code(bcb) => insert(bcb),
105105
BcbMappingKind::Branch { true_bcb, false_bcb, .. } => {
106-
insert(*true_bcb);
107-
insert(*false_bcb);
106+
insert(true_bcb);
107+
insert(false_bcb);
108108
}
109109
BcbMappingKind::Decision { bitmap_idx, conditions_num, .. } => {
110110
// `bcb_has_mappings` is used for inject coverage counters
111111
// but they are not needed for decision BCBs.
112112
// While the length of test vector bitmap should be calculated here.
113113
test_vector_bitmap_bytes = test_vector_bitmap_bytes
114-
.max(bitmap_idx + (1_u32 << *conditions_num as u32).div_ceil(8));
114+
.max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8));
115115
}
116116
}
117117
}

compiler/rustc_session/src/options.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -945,32 +945,20 @@ mod parse {
945945
pub(crate) fn parse_coverage_options(slot: &mut CoverageOptions, v: Option<&str>) -> bool {
946946
let Some(v) = v else { return true };
947947

948-
let set_branch_option = |slot: &mut CoverageOptions, option: &str| {
948+
for option in v.split(',') {
949949
match option {
950-
"no-branch" => slot.branch = false,
950+
"no-branch" => {
951+
slot.branch = false;
952+
slot.mcdc = false;
953+
}
951954
"branch" => slot.branch = true,
952955
"mcdc" => {
956+
slot.branch = true;
953957
slot.mcdc = true;
954-
slot.branch = true
955958
}
956959
_ => return false,
957960
}
958-
true
959-
};
960-
961-
// Once an option is parsed we removed it from the array so that conflicting options such as "branch,no-branch" could be detected.
962-
let mut parsers_set: [Option<&dyn Fn(&mut CoverageOptions, &str) -> bool>; 1] =
963-
[Some(&set_branch_option)];
964-
965-
for option in v.split(',') {
966-
if !parsers_set
967-
.iter_mut()
968-
.any(|p| p.is_some_and(|parser| parser(slot, option)).then(|| p.take()).is_some())
969-
{
970-
return false;
971-
}
972961
}
973-
974962
true
975963
}
976964

src/doc/unstable-book/src/compiler-flags/coverage-options.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ This option controls details of the coverage instrumentation performed by
55

66
Multiple options can be passed, separated by commas. Valid options are:
77

8-
- `no-branch`, `branch` or `mcdc`: `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation, which is same as do not pass `branch` or `mcdc`
8+
- `no-branch`, `branch` or `mcdc`: `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation as well as mcdc instrumentation, which is same as do not pass `branch` or `mcdc`.

src/tools/coverage-dump/src/covfun.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ pub(crate) fn dump_covfun_mappings(
7575
println!(" true = {}", expression_resolver.format_term(r#true));
7676
println!(" false = {}", expression_resolver.format_term(r#false));
7777
}
78-
79-
MappingKind::MCDCDecision { .. } => {}
8078
_ => (),
8179
}
8280
}

0 commit comments

Comments
 (0)