Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support MCDC Coverage with LLVM backend. #123358

Closed
wants to merge 21 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3f791cb
mcdc-coverage: Add `mcdc` and `no-mcdc` options for `-Zcoverage-options`
RenjiSann Mar 8, 2024
1782978
mcdc-coverage: Update ffi RegionKind to match LLVM's
RenjiSann Mar 13, 2024
5c5cd19
mcdc-coverage: Add FFI for getting Bitmap IPSK, Bump CoverageMappingV…
RenjiSann Mar 13, 2024
f789616
mcdc-coverage: Add utils for instrprof.mcdc.parameters intrinsic
RenjiSann Mar 14, 2024
7b321ca
mcdc-coverage: Add FFI MCDC Params for coverage mappings encoding
RenjiSann Mar 19, 2024
7d1dc67
mcdc-coverage: Add MCDCBlockMarker and MCDCDecisionMarker to the MIR
RenjiSann Mar 19, 2024
5bdabd0
mcdc-coverage: Add Data in BranchInfo for MCDC Tracability
RenjiSann Mar 19, 2024
e8b9b7c
mcdc-coverage: Add CoverageKind::MCDCBitmapRequire
RenjiSann Mar 20, 2024
7669154
mcdc-coverage: Generate `mcdc.parameters` intrinsic call at the begin…
RenjiSann Mar 21, 2024
1e2afe6
mcdc-coverage: allocate a condition bitmap on the function stackframe…
RenjiSann Mar 21, 2024
a30b4bb
mcdc-coverage: rename Decision marker to MCDCDecisionEntryMarker, add…
RenjiSann Mar 26, 2024
f831496
mcdc-coverage: Refactor Decision markers creation, add outcome marker…
RenjiSann Mar 26, 2024
6e7e2c5
mcdc-coverage: Add CoverageKinds for Bitmap manipulations.
RenjiSann Mar 27, 2024
20cdc51
mcdc-coverage: Add doc comments, move too many conditions error
RenjiSann Mar 27, 2024
cb55ae4
mcdc-coverage: Remove MCDCBlockMarker, Rename DecisionMarkerId, Add C…
RenjiSann Mar 27, 2024
9fea26a
mcdc-coverage: Refactor the MCDC info building
RenjiSann Mar 27, 2024
25768f8
mcdc-coverage: Add FFI equivalents of MCDC bitmap update intrinsics
RenjiSann Mar 28, 2024
83b8166
mcdc-coverage(codegen): Add MCDCCondBitmap(Reset|Update) Handling in …
RenjiSann Mar 28, 2024
33de2bb
mcdc-coverage(instrumentation): Rename Id names, Start instrumentatio…
RenjiSann Mar 29, 2024
e00df5d
mcdc-coverage(codegen): Add MCDCTestVectorBitmapUpdate codegen implem…
RenjiSann Apr 3, 2024
e112dc8
mcdc-coverage(mappings): Add variants for MCDCDecision and MCDCBranch…
RenjiSann Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
mcdc-coverage: Add FFI MCDC Params for coverage mappings encoding
RenjiSann committed Apr 2, 2024

Verified

This commit was signed with the committer’s verified signature.
commit 7b321ca0916474b4f1ffbd2fd555cae002c91d50
68 changes: 67 additions & 1 deletion compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
Original file line number Diff line number Diff line change
@@ -102,6 +102,7 @@ pub enum RegionKind {

/// A DecisionRegion represents a top-level boolean expression and is
/// associated with a variable length bitmap index and condition number.
/// FIXME(dprn): Remove unused variables.
#[allow(dead_code)]
MCDCDecisionRegion = 5,

@@ -110,6 +111,28 @@ pub enum RegionKind {
MCDCBranchRegion = 6,
}

/// This struct provides LLVM's representation of "MCDCParameters" that may be defined for a
/// Coverage Mapping Region.
///
/// Correspond to struct `llvm::coverage::CounterMappingRegion::MCDCParameters`
///
/// Must match The layout of `LLVMRustMCDCParameters`
#[derive(Copy, Clone, Debug, Default)]
#[repr(C)]
pub struct MCDCParameters {
/// Byte Index of Bitmap Coverage Object for a Decision Region.
bitmap_idx: u32,

/// Number of Conditions used for a Decision Region.
num_conditions: u32,

/// IDs used to represent a branch region and other branch regions
/// evaluated based on True and False branches.
id: u32,
true_id: u32,
false_id: u32,
}

/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
/// coverage map, in accordance with the
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
@@ -155,6 +178,8 @@ pub struct CounterMappingRegion {
end_col: u32,

kind: RegionKind,

mcdc_params: MCDCParameters,
}

impl CounterMappingRegion {
@@ -181,6 +206,7 @@ impl CounterMappingRegion {
start_col,
end_line,
end_col,
None,
),
}
}
@@ -203,9 +229,11 @@ impl CounterMappingRegion {
end_line,
end_col,
kind: RegionKind::CodeRegion,
mcdc_params: Default::default(),
}
}

/// - `mcdc_params` should be None when MCDC is disabled.
pub(crate) fn branch_region(
counter: Counter,
false_counter: Counter,
@@ -214,7 +242,13 @@ impl CounterMappingRegion {
start_col: u32,
end_line: u32,
end_col: u32,
mcdc_params: Option<MCDCParameters>,
) -> Self {
let (kind, mcdc_params) = match mcdc_params {
None => (RegionKind::BranchRegion, Default::default()),
Some(params) => (RegionKind::MCDCBranchRegion, params),
};

Self {
counter,
false_counter,
@@ -224,7 +258,36 @@ impl CounterMappingRegion {
start_col,
end_line,
end_col,
kind: RegionKind::BranchRegion,
kind,
mcdc_params,
}
}

#[allow(dead_code)]
pub(crate) fn decision_region(
bitmap_idx: u32,
num_conditions: u32,
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter: Counter::ZERO,
false_counter: Counter::ZERO,
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::MCDCDecisionRegion,
mcdc_params: MCDCParameters {
bitmap_idx,
num_conditions,
.. Default::default()
},
}
}

@@ -249,6 +312,7 @@ impl CounterMappingRegion {
end_line,
end_col,
kind: RegionKind::ExpansionRegion,
mcdc_params: Default::default(),
}
}

@@ -272,6 +336,7 @@ impl CounterMappingRegion {
end_line,
end_col,
kind: RegionKind::SkippedRegion,
mcdc_params: Default::default(),
}
}

@@ -296,6 +361,7 @@ impl CounterMappingRegion {
end_line,
end_col: (1_u32 << 31) | end_col,
kind: RegionKind::GapRegion,
mcdc_params: Default::default(),
}
}
}
27 changes: 26 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
Original file line number Diff line number Diff line change
@@ -68,6 +68,30 @@ fromRust(LLVMRustCounterMappingRegionKind Kind) {
report_fatal_error("Bad LLVMRustCounterMappingRegionKind!");
}

// FFI equivalent of struct `llvm::coverage::CounterMappingRegion::MCDCParameters`
// https://github.com/rust-lang/llvm-project/blob/66a2881a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L253-L263
struct LLVMRustMCDCParameters {
/// Byte Index of Bitmap Coverage Object for a Decision Region.
uint32_t BitmapIdx = 0;

/// Number of Conditions used for a Decision Region.
uint32_t NumConditions = 0;

/// IDs used to represent a branch region and other branch regions
/// evaluated based on True and False branches.
uint32_t ID = 0;
uint32_t TrueID = 0;
uint32_t FalseID = 0;
};

static coverage::CounterMappingRegion::MCDCParameters
fromRust(LLVMRustMCDCParameters MCDCParams) {
return coverage::CounterMappingRegion::MCDCParameters{
MCDCParams.BitmapIdx, MCDCParams.NumConditions,
MCDCParams.ID, MCDCParams.TrueID, MCDCParams.FalseID
};
}

Comment on lines +71 to +94
Copy link
Contributor

@Zalathar Zalathar Apr 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good example of how we should be passing data from Rust to C++. I think something like this is what we should be using in #123409.

However, the fields should be declared as unsigned, so that they exactly match the type declarations that LLVM uses in MCDCParameters. And the corresponding struct on the Rust side should use libc::c_uint to match.

That makes it easier to verify that the FFI mapping has been done correctly.

// FFI equivalent of struct `llvm::coverage::CounterMappingRegion`
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L211-L304
struct LLVMRustCounterMappingRegion {
@@ -80,6 +104,7 @@ struct LLVMRustCounterMappingRegion {
uint32_t LineEnd;
uint32_t ColumnEnd;
LLVMRustCounterMappingRegionKind Kind;
LLVMRustMCDCParameters MCDCParams;
};

// FFI equivalent of enum `llvm::coverage::CounterExpression::ExprKind`
@@ -146,7 +171,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
MappingRegions.emplace_back(
fromRust(Region.Count), fromRust(Region.FalseCount),
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
coverage::CounterMappingRegion::MCDCParameters{},
fromRust(Region.MCDCParams),
#endif
Region.FileID, Region.ExpandedFileID,
Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,