Skip to content

Commit 0909ca8

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 9afe713 + 3d24cf9 commit 0909ca8

29 files changed

+539
-712
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+16-53
Original file line numberDiff line numberDiff line change
@@ -1763,18 +1763,18 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17631763
&mut self,
17641764
fn_name: &'ll Value,
17651765
hash: &'ll Value,
1766-
bitmap_bytes: &'ll Value,
1766+
bitmap_bits: &'ll Value,
17671767
) {
1768-
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes);
1768+
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bits);
17691769

1770-
assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
1770+
assert!(llvm_util::get_version() >= (19, 0, 0), "MCDC intrinsics require LLVM 19 or later");
17711771

17721772
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCParametersIntrinsic(self.cx().llmod) };
17731773
let llty = self.cx.type_func(
17741774
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
17751775
self.cx.type_void(),
17761776
);
1777-
let args = &[fn_name, hash, bitmap_bytes];
1777+
let args = &[fn_name, hash, bitmap_bits];
17781778
let args = self.check_call("call", llty, llfn, args);
17791779

17801780
unsafe {
@@ -1794,29 +1794,22 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17941794
&mut self,
17951795
fn_name: &'ll Value,
17961796
hash: &'ll Value,
1797-
bitmap_bytes: &'ll Value,
17981797
bitmap_index: &'ll Value,
17991798
mcdc_temp: &'ll Value,
18001799
) {
18011800
debug!(
1802-
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
1803-
fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp
1801+
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?})",
1802+
fn_name, hash, bitmap_index, mcdc_temp
18041803
);
1805-
assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
1804+
assert!(llvm_util::get_version() >= (19, 0, 0), "MCDC intrinsics require LLVM 19 or later");
18061805

18071806
let llfn =
18081807
unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
18091808
let llty = self.cx.type_func(
1810-
&[
1811-
self.cx.type_ptr(),
1812-
self.cx.type_i64(),
1813-
self.cx.type_i32(),
1814-
self.cx.type_i32(),
1815-
self.cx.type_ptr(),
1816-
],
1809+
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_ptr()],
18171810
self.cx.type_void(),
18181811
);
1819-
let args = &[fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp];
1812+
let args = &[fn_name, hash, bitmap_index, mcdc_temp];
18201813
let args = self.check_call("call", llty, llfn, args);
18211814
unsafe {
18221815
let _ = llvm::LLVMRustBuildCall(
@@ -1832,42 +1825,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
18321825
self.store(self.const_i32(0), mcdc_temp, self.tcx.data_layout.i32_align.abi);
18331826
}
18341827

1835-
pub(crate) fn mcdc_condbitmap_update(
1836-
&mut self,
1837-
fn_name: &'ll Value,
1838-
hash: &'ll Value,
1839-
cond_loc: &'ll Value,
1840-
mcdc_temp: &'ll Value,
1841-
bool_value: &'ll Value,
1842-
) {
1843-
debug!(
1844-
"mcdc_condbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
1845-
fn_name, hash, cond_loc, mcdc_temp, bool_value
1846-
);
1847-
assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
1848-
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(self.cx().llmod) };
1849-
let llty = self.cx.type_func(
1850-
&[
1851-
self.cx.type_ptr(),
1852-
self.cx.type_i64(),
1853-
self.cx.type_i32(),
1854-
self.cx.type_ptr(),
1855-
self.cx.type_i1(),
1856-
],
1857-
self.cx.type_void(),
1858-
);
1859-
let args = &[fn_name, hash, cond_loc, mcdc_temp, bool_value];
1860-
self.check_call("call", llty, llfn, args);
1861-
unsafe {
1862-
let _ = llvm::LLVMRustBuildCall(
1863-
self.llbuilder,
1864-
llty,
1865-
llfn,
1866-
args.as_ptr() as *const &llvm::Value,
1867-
args.len() as c_uint,
1868-
[].as_ptr(),
1869-
0 as c_uint,
1870-
);
1871-
}
1828+
pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) {
1829+
debug!("mcdc_condbitmap_update() with args ({:?}, {:?})", cond_index, mcdc_temp);
1830+
assert!(llvm_util::get_version() >= (19, 0, 0), "MCDC intrinsics require LLVM 19 or later");
1831+
let align = self.tcx.data_layout.i32_align.abi;
1832+
let current_tv_index = self.load(self.cx.type_i32(), mcdc_temp, align);
1833+
let new_tv_index = self.add(current_tv_index, cond_index);
1834+
self.store(new_tv_index, mcdc_temp, align);
18721835
}
18731836
}

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)]
@@ -166,12 +166,13 @@ mod mcdc {
166166

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

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

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

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

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

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

213207
let fn_name = bx.get_pgo_func_name_var(instance);
214208
let hash = bx.const_u64(function_coverage_info.function_source_hash);
215-
let bitmap_bytes = bx.const_u32(bitmap_bytes);
216209
let bitmap_index = bx.const_u32(bitmap_idx);
217-
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_bytes, bitmap_index, cond_bitmap);
210+
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap);
218211
}
219212
}
220213
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,6 @@ unsafe extern "C" {
16401640
pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
16411641
pub fn LLVMRustGetInstrProfMCDCParametersIntrinsic(M: &Module) -> &Value;
16421642
pub fn LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(M: &Module) -> &Value;
1643-
pub fn LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(M: &Module) -> &Value;
16441643

16451644
pub fn LLVMRustBuildCall<'a>(
16461645
B: &Builder<'a>,

compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp

+8-35
Original file line numberDiff line numberDiff line change
@@ -95,38 +95,7 @@ struct LLVMRustMCDCParameters {
9595
LLVMRustMCDCBranchParameters BranchParameters;
9696
};
9797

98-
// LLVM representations for `MCDCParameters` evolved from LLVM 18 to 19.
99-
// Look at representations in 18
100-
// https://github.com/rust-lang/llvm-project/blob/66a2881a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L253-L263
101-
// and representations in 19
102-
// https://github.com/llvm/llvm-project/blob/843cc474faefad1d639f4c44c1cf3ad7dbda76c8/llvm/include/llvm/ProfileData/Coverage/MCDCTypes.h
103-
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
104-
static coverage::CounterMappingRegion::MCDCParameters
105-
fromRust(LLVMRustMCDCParameters Params) {
106-
auto parameter = coverage::CounterMappingRegion::MCDCParameters{};
107-
switch (Params.Tag) {
108-
case LLVMRustMCDCParametersTag::None:
109-
return parameter;
110-
case LLVMRustMCDCParametersTag::Decision:
111-
parameter.BitmapIdx =
112-
static_cast<unsigned>(Params.DecisionParameters.BitmapIdx),
113-
parameter.NumConditions =
114-
static_cast<unsigned>(Params.DecisionParameters.NumConditions);
115-
return parameter;
116-
case LLVMRustMCDCParametersTag::Branch:
117-
parameter.ID = static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
118-
Params.BranchParameters.ConditionID),
119-
parameter.FalseID =
120-
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
121-
Params.BranchParameters.ConditionIDs[0]),
122-
parameter.TrueID =
123-
static_cast<coverage::CounterMappingRegion::MCDCConditionID>(
124-
Params.BranchParameters.ConditionIDs[1]);
125-
return parameter;
126-
}
127-
report_fatal_error("Bad LLVMRustMCDCParametersTag!");
128-
}
129-
#elif LLVM_VERSION_GE(19, 0)
98+
#if LLVM_VERSION_GE(19, 0)
13099
static coverage::mcdc::Parameters fromRust(LLVMRustMCDCParameters Params) {
131100
switch (Params.Tag) {
132101
case LLVMRustMCDCParametersTag::None:
@@ -222,12 +191,16 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
222191
MappingRegions.emplace_back(
223192
fromRust(Region.Count), fromRust(Region.FalseCount),
224193
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
225-
// LLVM 19 may move this argument to last.
226-
fromRust(Region.MCDCParameters),
194+
coverage::CounterMappingRegion::MCDCParameters{},
227195
#endif
228196
Region.FileID, Region.ExpandedFileID, // File IDs, then region info.
229197
Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
230-
fromRust(Region.Kind));
198+
fromRust(Region.Kind)
199+
#if LLVM_VERSION_GE(19, 0)
200+
,
201+
fromRust(Region.MCDCParameters)
202+
#endif
203+
);
231204
}
232205

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

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+4-14
Original file line numberDiff line numberDiff line change
@@ -1552,31 +1552,21 @@ LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
15521552

15531553
extern "C" LLVMValueRef
15541554
LLVMRustGetInstrProfMCDCParametersIntrinsic(LLVMModuleRef M) {
1555-
#if LLVM_VERSION_GE(18, 0)
1555+
#if LLVM_VERSION_GE(19, 0)
15561556
return wrap(llvm::Intrinsic::getDeclaration(
15571557
unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
15581558
#else
1559-
report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions");
1559+
report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
15601560
#endif
15611561
}
15621562

15631563
extern "C" LLVMValueRef
15641564
LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(LLVMModuleRef M) {
1565-
#if LLVM_VERSION_GE(18, 0)
1565+
#if LLVM_VERSION_GE(19, 0)
15661566
return wrap(llvm::Intrinsic::getDeclaration(
15671567
unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
15681568
#else
1569-
report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions");
1570-
#endif
1571-
}
1572-
1573-
extern "C" LLVMValueRef
1574-
LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(LLVMModuleRef M) {
1575-
#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
1576-
return wrap(llvm::Intrinsic::getDeclaration(
1577-
unwrap(M), llvm::Intrinsic::instrprof_mcdc_condbitmap_update));
1578-
#else
1579-
report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions");
1569+
report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
15801570
#endif
15811571
}
15821572

0 commit comments

Comments
 (0)