Skip to content

Commit cf24c73

Browse files
committed
Auto merge of rust-lang#126733 - ZhuUx:llvm-19-adapt, r=Zalathar
[Coverage][MCDC] Adapt mcdc to llvm 19 Related issue: rust-lang#126672 Also finish task 4 at rust-lang#124144 [llvm rust-lang#82448](llvm/llvm-project#82448) has introduced some break changes into mcdc, causing incompatibility between llvm 18 and 19. This draft adapts to that change and gives up supporting for llvm-18.
2 parents e6c46db + acd64fa commit cf24c73

31 files changed

+573
-572
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+25-49
Original file line numberDiff line numberDiff line change
@@ -1679,16 +1679,21 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16791679
&mut self,
16801680
fn_name: &'ll Value,
16811681
hash: &'ll Value,
1682-
bitmap_bytes: &'ll Value,
1682+
bitmap_bits: &'ll Value,
16831683
) {
1684-
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes);
1684+
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bits);
1685+
1686+
assert!(
1687+
crate::llvm_util::get_version() >= (19, 0, 0),
1688+
"MCDC intrinsics require LLVM 19 or later"
1689+
);
16851690

16861691
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCParametersIntrinsic(self.cx().llmod) };
16871692
let llty = self.cx.type_func(
16881693
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
16891694
self.cx.type_void(),
16901695
);
1691-
let args = &[fn_name, hash, bitmap_bytes];
1696+
let args = &[fn_name, hash, bitmap_bits];
16921697
let args = self.check_call("call", llty, llfn, args);
16931698

16941699
unsafe {
@@ -1708,28 +1713,25 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17081713
&mut self,
17091714
fn_name: &'ll Value,
17101715
hash: &'ll Value,
1711-
bitmap_bytes: &'ll Value,
17121716
bitmap_index: &'ll Value,
17131717
mcdc_temp: &'ll Value,
17141718
) {
17151719
debug!(
1716-
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
1717-
fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp
1720+
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?})",
1721+
fn_name, hash, bitmap_index, mcdc_temp
1722+
);
1723+
assert!(
1724+
crate::llvm_util::get_version() >= (19, 0, 0),
1725+
"MCDC intrinsics require LLVM 19 or later"
17181726
);
17191727

17201728
let llfn =
17211729
unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
17221730
let llty = self.cx.type_func(
1723-
&[
1724-
self.cx.type_ptr(),
1725-
self.cx.type_i64(),
1726-
self.cx.type_i32(),
1727-
self.cx.type_i32(),
1728-
self.cx.type_ptr(),
1729-
],
1731+
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_ptr()],
17301732
self.cx.type_void(),
17311733
);
1732-
let args = &[fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp];
1734+
let args = &[fn_name, hash, bitmap_index, mcdc_temp];
17331735
let args = self.check_call("call", llty, llfn, args);
17341736
unsafe {
17351737
let _ = llvm::LLVMRustBuildCall(
@@ -1745,41 +1747,15 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17451747
self.store(self.const_i32(0), mcdc_temp, self.tcx.data_layout.i32_align.abi);
17461748
}
17471749

1748-
pub(crate) fn mcdc_condbitmap_update(
1749-
&mut self,
1750-
fn_name: &'ll Value,
1751-
hash: &'ll Value,
1752-
cond_loc: &'ll Value,
1753-
mcdc_temp: &'ll Value,
1754-
bool_value: &'ll Value,
1755-
) {
1756-
debug!(
1757-
"mcdc_condbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
1758-
fn_name, hash, cond_loc, mcdc_temp, bool_value
1759-
);
1760-
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(self.cx().llmod) };
1761-
let llty = self.cx.type_func(
1762-
&[
1763-
self.cx.type_ptr(),
1764-
self.cx.type_i64(),
1765-
self.cx.type_i32(),
1766-
self.cx.type_ptr(),
1767-
self.cx.type_i1(),
1768-
],
1769-
self.cx.type_void(),
1750+
pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) {
1751+
debug!("mcdc_condbitmap_update() with args ({:?}, {:?})", cond_index, mcdc_temp);
1752+
assert!(
1753+
crate::llvm_util::get_version() >= (19, 0, 0),
1754+
"MCDC intrinsics require LLVM 19 or later"
17701755
);
1771-
let args = &[fn_name, hash, cond_loc, mcdc_temp, bool_value];
1772-
self.check_call("call", llty, llfn, args);
1773-
unsafe {
1774-
let _ = llvm::LLVMRustBuildCall(
1775-
self.llbuilder,
1776-
llty,
1777-
llfn,
1778-
args.as_ptr() as *const &llvm::Value,
1779-
args.len() as c_uint,
1780-
[].as_ptr(),
1781-
0 as c_uint,
1782-
);
1783-
}
1756+
let align = self.tcx.data_layout.i32_align.abi;
1757+
let current_tv_index = self.load(self.cx.type_i32(), mcdc_temp, align);
1758+
let new_tv_index = self.add(current_tv_index, cond_index);
1759+
self.store(new_tv_index, mcdc_temp, align);
17841760
}
17851761
}

compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ enum RegionKind {
111111
}
112112

113113
mod mcdc {
114-
use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo};
114+
use rustc_middle::mir::coverage::{ConditionId, ConditionInfo, DecisionInfo};
115115

116116
/// Must match the layout of `LLVMRustMCDCDecisionParameters`.
117117
#[repr(C)]
@@ -167,12 +167,13 @@ mod mcdc {
167167

168168
impl From<ConditionInfo> for BranchParameters {
169169
fn from(value: ConditionInfo) -> Self {
170+
let to_llvm_cond_id = |cond_id: Option<ConditionId>| {
171+
cond_id.and_then(|id| LLVMConditionId::try_from(id.as_usize()).ok()).unwrap_or(-1)
172+
};
173+
let ConditionInfo { condition_id, true_next_id, false_next_id } = value;
170174
Self {
171-
condition_id: value.condition_id.as_u32() as LLVMConditionId,
172-
condition_ids: [
173-
value.false_next_id.as_u32() as LLVMConditionId,
174-
value.true_next_id.as_u32() as LLVMConditionId,
175-
],
175+
condition_id: to_llvm_cond_id(Some(condition_id)),
176+
condition_ids: [to_llvm_cond_id(false_next_id), to_llvm_cond_id(true_next_id)],
176177
}
177178
}
178179
}

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+11-18
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,14 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
9898
};
9999

100100
// If there are no MC/DC bitmaps to set up, return immediately.
101-
if function_coverage_info.mcdc_bitmap_bytes == 0 {
101+
if function_coverage_info.mcdc_bitmap_bits == 0 {
102102
return;
103103
}
104104

105105
let fn_name = self.get_pgo_func_name_var(instance);
106106
let hash = self.const_u64(function_coverage_info.function_source_hash);
107-
let bitmap_bytes = self.const_u32(function_coverage_info.mcdc_bitmap_bytes);
108-
self.mcdc_parameters(fn_name, hash, bitmap_bytes);
107+
let bitmap_bits = self.const_u32(function_coverage_info.mcdc_bitmap_bits as u32);
108+
self.mcdc_parameters(fn_name, hash, bitmap_bits);
109109

110110
// Create pointers named `mcdc.addr.{i}` to stack-allocated condition bitmaps.
111111
let mut cond_bitmaps = vec![];
@@ -185,35 +185,28 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
185185
CoverageKind::ExpressionUsed { id } => {
186186
func_coverage.mark_expression_id_seen(id);
187187
}
188-
CoverageKind::CondBitmapUpdate { id, value, decision_depth } => {
188+
CoverageKind::CondBitmapUpdate { index, decision_depth } => {
189189
drop(coverage_map);
190-
assert_ne!(
191-
id.as_u32(),
192-
0,
193-
"ConditionId of evaluated conditions should never be zero"
194-
);
195190
let cond_bitmap = coverage_context
196191
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
197192
.expect("mcdc cond bitmap should have been allocated for updating");
198-
let cond_loc = bx.const_i32(id.as_u32() as i32 - 1);
199-
let bool_value = bx.const_bool(value);
200-
let fn_name = bx.get_pgo_func_name_var(instance);
201-
let hash = bx.const_u64(function_coverage_info.function_source_hash);
202-
bx.mcdc_condbitmap_update(fn_name, hash, cond_loc, cond_bitmap, bool_value);
193+
let cond_index = bx.const_i32(index as i32);
194+
bx.mcdc_condbitmap_update(cond_index, cond_bitmap);
203195
}
204196
CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
205197
drop(coverage_map);
206198
let cond_bitmap = coverage_context
207199
.try_get_mcdc_condition_bitmap(&instance, decision_depth)
208200
.expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
209-
let bitmap_bytes = function_coverage_info.mcdc_bitmap_bytes;
210-
assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range");
201+
assert!(
202+
bitmap_idx as usize <= function_coverage_info.mcdc_bitmap_bits,
203+
"bitmap index of the decision out of range"
204+
);
211205

212206
let fn_name = bx.get_pgo_func_name_var(instance);
213207
let hash = bx.const_u64(function_coverage_info.function_source_hash);
214-
let bitmap_bytes = bx.const_u32(bitmap_bytes);
215208
let bitmap_index = bx.const_u32(bitmap_idx);
216-
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_bytes, bitmap_index, cond_bitmap);
209+
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap);
217210
}
218211
}
219212
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,6 @@ unsafe extern "C" {
16141614
pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
16151615
pub fn LLVMRustGetInstrProfMCDCParametersIntrinsic(M: &Module) -> &Value;
16161616
pub fn LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(M: &Module) -> &Value;
1617-
pub fn LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(M: &Module) -> &Value;
16181617

16191618
pub fn LLVMRustBuildCall<'a>(
16201619
B: &Builder<'a>,

compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp

+9-36
Original file line numberDiff line numberDiff line change
@@ -88,38 +88,7 @@ struct LLVMRustMCDCParameters {
8888
LLVMRustMCDCBranchParameters BranchParameters;
8989
};
9090

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_LT(19, 0)
97-
static coverage::CounterMappingRegion::MCDCParameters
98-
fromRust(LLVMRustMCDCParameters Params) {
99-
auto parameter = coverage::CounterMappingRegion::MCDCParameters{};
100-
switch (Params.Tag) {
101-
case LLVMRustMCDCParametersTag::None:
102-
return parameter;
103-
case LLVMRustMCDCParametersTag::Decision:
104-
parameter.BitmapIdx =
105-
static_cast<unsigned>(Params.DecisionParameters.BitmapIdx),
106-
parameter.NumConditions =
107-
static_cast<unsigned>(Params.DecisionParameters.NumConditions);
108-
return parameter;
109-
case LLVMRustMCDCParametersTag::Branch:
110-
parameter.ID = static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
111-
Params.BranchParameters.ConditionID),
112-
parameter.FalseID =
113-
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
114-
Params.BranchParameters.ConditionIDs[0]),
115-
parameter.TrueID =
116-
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
117-
Params.BranchParameters.ConditionIDs[1]);
118-
return parameter;
119-
}
120-
report_fatal_error("Bad LLVMRustMCDCParametersTag!");
121-
}
122-
#else
91+
#if LLVM_VERSION_GE(19, 0)
12392
static coverage::mcdc::Parameters fromRust(LLVMRustMCDCParameters Params) {
12493
switch (Params.Tag) {
12594
case LLVMRustMCDCParametersTag::None:
@@ -214,13 +183,17 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
214183
RustMappingRegions, NumMappingRegions)) {
215184
MappingRegions.emplace_back(
216185
fromRust(Region.Count), fromRust(Region.FalseCount),
217-
#if LLVM_VERSION_LT(19, 0)
218-
// LLVM 19 may move this argument to last.
219-
fromRust(Region.MCDCParameters),
186+
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
187+
coverage::CounterMappingRegion::MCDCParameters{},
220188
#endif
221189
Region.FileID, Region.ExpandedFileID, // File IDs, then region info.
222190
Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
223-
fromRust(Region.Kind));
191+
fromRust(Region.Kind)
192+
#if LLVM_VERSION_GE(19, 0)
193+
,
194+
fromRust(Region.MCDCParameters)
195+
#endif
196+
);
224197
}
225198

226199
std::vector<coverage::CounterExpression> Expressions;

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -1539,23 +1539,21 @@ LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
15391539

15401540
extern "C" LLVMValueRef
15411541
LLVMRustGetInstrProfMCDCParametersIntrinsic(LLVMModuleRef M) {
1542+
#if LLVM_VERSION_GE(19, 0)
15421543
return wrap(llvm::Intrinsic::getDeclaration(
15431544
unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
1545+
#else
1546+
report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
1547+
#endif
15441548
}
15451549

15461550
extern "C" LLVMValueRef
15471551
LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(LLVMModuleRef M) {
1552+
#if LLVM_VERSION_GE(19, 0)
15481553
return wrap(llvm::Intrinsic::getDeclaration(
15491554
unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
1550-
}
1551-
1552-
extern "C" LLVMValueRef
1553-
LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(LLVMModuleRef M) {
1554-
#if LLVM_VERSION_LT(19, 0)
1555-
return wrap(llvm::Intrinsic::getDeclaration(
1556-
unwrap(M), llvm::Intrinsic::instrprof_mcdc_condbitmap_update));
15571555
#else
1558-
report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions");
1556+
report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
15591557
#endif
15601558
}
15611559

0 commit comments

Comments
 (0)