Skip to content

Commit 4896daa

Browse files
committed
Auto merge of rust-lang#114331 - matthiaskrgr:rollup-rnrmwcx, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#100455 (Implement RefUnwindSafe for Backtrace) - rust-lang#113428 (coverage: Replace `ExpressionOperandId` with enum `Operand`) - rust-lang#114283 (Use parking lot's rwlock even without parallel-rustc) - rust-lang#114288 (Improve diagnostic for wrong borrow on binary operations) - rust-lang#114296 (interpret: fix alignment handling for Repeat expressions) - rust-lang#114306 ([rustc_data_structures][perf] Simplify base_n::push_str.) - rust-lang#114320 (Cover statements for stable_mir) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 828bdc2 + 41364c7 commit 4896daa

30 files changed

+815
-326
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
1+
use rustc_middle::mir::coverage::{CounterId, MappedExpressionIndex};
22

33
/// Must match the layout of `LLVMRustCounterKind`.
44
#[derive(Copy, Clone, Debug)]
@@ -36,11 +36,9 @@ impl Counter {
3636
Self { kind: CounterKind::Zero, id: 0 }
3737
}
3838

39-
/// Constructs a new `Counter` of kind `CounterValueReference`, and converts
40-
/// the given 1-based counter_id to the required 0-based equivalent for
41-
/// the `Counter` encoding.
42-
pub fn counter_value_reference(counter_id: CounterValueReference) -> Self {
43-
Self { kind: CounterKind::CounterValueReference, id: counter_id.zero_based_index() }
39+
/// Constructs a new `Counter` of kind `CounterValueReference`.
40+
pub fn counter_value_reference(counter_id: CounterId) -> Self {
41+
Self { kind: CounterKind::CounterValueReference, id: counter_id.as_u32() }
4442
}
4543

4644
/// Constructs a new `Counter` of kind `Expression`.

compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs

+25-62
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,22 @@ pub use super::ffi::*;
33
use rustc_index::{IndexSlice, IndexVec};
44
use rustc_middle::bug;
55
use rustc_middle::mir::coverage::{
6-
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId,
7-
InjectedExpressionIndex, MappedExpressionIndex, Op,
6+
CodeRegion, CounterId, ExpressionId, MappedExpressionIndex, Op, Operand,
87
};
98
use rustc_middle::ty::Instance;
109
use rustc_middle::ty::TyCtxt;
1110

1211
#[derive(Clone, Debug, PartialEq)]
1312
pub struct Expression {
14-
lhs: ExpressionOperandId,
13+
lhs: Operand,
1514
op: Op,
16-
rhs: ExpressionOperandId,
15+
rhs: Operand,
1716
region: Option<CodeRegion>,
1817
}
1918

2019
/// Collects all of the coverage regions associated with (a) injected counters, (b) counter
2120
/// expressions (additions or subtraction), and (c) unreachable regions (always counted as zero),
22-
/// for a given Function. Counters and counter expressions have non-overlapping `id`s because they
23-
/// can both be operands in an expression. This struct also stores the `function_source_hash`,
21+
/// for a given Function. This struct also stores the `function_source_hash`,
2422
/// computed during instrumentation, and forwarded with counters.
2523
///
2624
/// Note, it may be important to understand LLVM's definitions of `unreachable` regions versus "gap
@@ -34,8 +32,8 @@ pub struct FunctionCoverage<'tcx> {
3432
instance: Instance<'tcx>,
3533
source_hash: u64,
3634
is_used: bool,
37-
counters: IndexVec<CounterValueReference, Option<CodeRegion>>,
38-
expressions: IndexVec<InjectedExpressionIndex, Option<Expression>>,
35+
counters: IndexVec<CounterId, Option<CodeRegion>>,
36+
expressions: IndexVec<ExpressionId, Option<Expression>>,
3937
unreachable_regions: Vec<CodeRegion>,
4038
}
4139

@@ -82,48 +80,36 @@ impl<'tcx> FunctionCoverage<'tcx> {
8280
}
8381

8482
/// Adds a code region to be counted by an injected counter intrinsic.
85-
pub fn add_counter(&mut self, id: CounterValueReference, region: CodeRegion) {
83+
pub fn add_counter(&mut self, id: CounterId, region: CodeRegion) {
8684
if let Some(previous_region) = self.counters[id].replace(region.clone()) {
8785
assert_eq!(previous_region, region, "add_counter: code region for id changed");
8886
}
8987
}
9088

9189
/// Both counters and "counter expressions" (or simply, "expressions") can be operands in other
92-
/// expressions. Expression IDs start from `u32::MAX` and go down, so the range of expression
93-
/// IDs will not overlap with the range of counter IDs. Counters and expressions can be added in
94-
/// any order, and expressions can still be assigned contiguous (though descending) IDs, without
95-
/// knowing what the last counter ID will be.
96-
///
97-
/// When storing the expression data in the `expressions` vector in the `FunctionCoverage`
98-
/// struct, its vector index is computed, from the given expression ID, by subtracting from
99-
/// `u32::MAX`.
100-
///
101-
/// Since the expression operands (`lhs` and `rhs`) can reference either counters or
102-
/// expressions, an operand that references an expression also uses its original ID, descending
103-
/// from `u32::MAX`. Theses operands are translated only during code generation, after all
104-
/// counters and expressions have been added.
90+
/// expressions. These are tracked as separate variants of `Operand`, so there is no ambiguity
91+
/// between operands that are counter IDs and operands that are expression IDs.
10592
pub fn add_counter_expression(
10693
&mut self,
107-
expression_id: InjectedExpressionId,
108-
lhs: ExpressionOperandId,
94+
expression_id: ExpressionId,
95+
lhs: Operand,
10996
op: Op,
110-
rhs: ExpressionOperandId,
97+
rhs: Operand,
11198
region: Option<CodeRegion>,
11299
) {
113100
debug!(
114101
"add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}",
115102
expression_id, lhs, op, rhs, region
116103
);
117-
let expression_index = self.expression_index(u32::from(expression_id));
118104
debug_assert!(
119-
expression_index.as_usize() < self.expressions.len(),
120-
"expression_index {} is out of range for expressions.len() = {}
105+
expression_id.as_usize() < self.expressions.len(),
106+
"expression_id {} is out of range for expressions.len() = {}
121107
for {:?}",
122-
expression_index.as_usize(),
108+
expression_id.as_usize(),
123109
self.expressions.len(),
124110
self,
125111
);
126-
if let Some(previous_expression) = self.expressions[expression_index].replace(Expression {
112+
if let Some(previous_expression) = self.expressions[expression_id].replace(Expression {
127113
lhs,
128114
op,
129115
rhs,
@@ -186,14 +172,11 @@ impl<'tcx> FunctionCoverage<'tcx> {
186172

187173
// This closure converts any `Expression` operand (`lhs` or `rhs` of the `Op::Add` or
188174
// `Op::Subtract` operation) into its native `llvm::coverage::Counter::CounterKind` type
189-
// and value. Operand ID value `0` maps to `CounterKind::Zero`; values in the known range
190-
// of injected LLVM counters map to `CounterKind::CounterValueReference` (and the value
191-
// matches the injected counter index); and any other value is converted into a
192-
// `CounterKind::Expression` with the expression's `new_index`.
175+
// and value.
193176
//
194177
// Expressions will be returned from this function in a sequential vector (array) of
195178
// `CounterExpression`, so the expression IDs must be mapped from their original,
196-
// potentially sparse set of indexes, originally in reverse order from `u32::MAX`.
179+
// potentially sparse set of indexes.
197180
//
198181
// An `Expression` as an operand will have already been encountered as an `Expression` with
199182
// operands, so its new_index will already have been generated (as a 1-up index value).
@@ -206,34 +189,19 @@ impl<'tcx> FunctionCoverage<'tcx> {
206189
// `expression_index`s lower than the referencing `Expression`. Therefore, it is
207190
// reasonable to look up the new index of an expression operand while the `new_indexes`
208191
// vector is only complete up to the current `ExpressionIndex`.
209-
let id_to_counter = |new_indexes: &IndexSlice<
210-
InjectedExpressionIndex,
211-
Option<MappedExpressionIndex>,
212-
>,
213-
id: ExpressionOperandId| {
214-
if id == ExpressionOperandId::ZERO {
215-
Some(Counter::zero())
216-
} else if id.index() < self.counters.len() {
217-
debug_assert!(
218-
id.index() > 0,
219-
"ExpressionOperandId indexes for counters are 1-based, but this id={}",
220-
id.index()
221-
);
222-
// Note: Some codegen-injected Counters may be only referenced by `Expression`s,
223-
// and may not have their own `CodeRegion`s,
224-
let index = CounterValueReference::from(id.index());
225-
// Note, the conversion to LLVM `Counter` adjusts the index to be zero-based.
226-
Some(Counter::counter_value_reference(index))
227-
} else {
228-
let index = self.expression_index(u32::from(id));
192+
type NewIndexes = IndexSlice<ExpressionId, Option<MappedExpressionIndex>>;
193+
let id_to_counter = |new_indexes: &NewIndexes, operand: Operand| match operand {
194+
Operand::Zero => Some(Counter::zero()),
195+
Operand::Counter(id) => Some(Counter::counter_value_reference(id)),
196+
Operand::Expression(id) => {
229197
self.expressions
230-
.get(index)
198+
.get(id)
231199
.expect("expression id is out of range")
232200
.as_ref()
233201
// If an expression was optimized out, assume it would have produced a count
234202
// of zero. This ensures that expressions dependent on optimized-out
235203
// expressions are still valid.
236-
.map_or(Some(Counter::zero()), |_| new_indexes[index].map(Counter::expression))
204+
.map_or(Some(Counter::zero()), |_| new_indexes[id].map(Counter::expression))
237205
}
238206
};
239207

@@ -340,9 +308,4 @@ impl<'tcx> FunctionCoverage<'tcx> {
340308
fn unreachable_regions(&self) -> impl Iterator<Item = (Counter, &CodeRegion)> {
341309
self.unreachable_regions.iter().map(|region| (Counter::zero(), region))
342310
}
343-
344-
fn expression_index(&self, id_descending_from_max: u32) -> InjectedExpressionIndex {
345-
debug_assert!(id_descending_from_max >= self.counters.len() as u32);
346-
InjectedExpressionIndex::from(u32::MAX - id_descending_from_max)
347-
}
348311
}

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ use rustc_hir as hir;
1616
use rustc_hir::def_id::DefId;
1717
use rustc_llvm::RustString;
1818
use rustc_middle::bug;
19-
use rustc_middle::mir::coverage::{
20-
CodeRegion, CounterValueReference, CoverageKind, ExpressionOperandId, InjectedExpressionId, Op,
21-
};
19+
use rustc_middle::mir::coverage::{CodeRegion, CounterId, CoverageKind, ExpressionId, Op, Operand};
2220
use rustc_middle::mir::Coverage;
2321
use rustc_middle::ty;
2422
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
@@ -33,7 +31,7 @@ mod ffi;
3331
pub(crate) mod map_data;
3432
pub mod mapgen;
3533

36-
const UNUSED_FUNCTION_COUNTER_ID: CounterValueReference = CounterValueReference::START;
34+
const UNUSED_FUNCTION_COUNTER_ID: CounterId = CounterId::START;
3735

3836
const VAR_ALIGN_BYTES: usize = 8;
3937

@@ -125,7 +123,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
125123
let fn_name = bx.get_pgo_func_name_var(instance);
126124
let hash = bx.const_u64(function_source_hash);
127125
let num_counters = bx.const_u32(coverageinfo.num_counters);
128-
let index = bx.const_u32(id.zero_based_index());
126+
let index = bx.const_u32(id.as_u32());
129127
debug!(
130128
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
131129
fn_name, hash, num_counters, index,
@@ -178,7 +176,7 @@ impl<'tcx> Builder<'_, '_, 'tcx> {
178176
fn add_coverage_counter(
179177
&mut self,
180178
instance: Instance<'tcx>,
181-
id: CounterValueReference,
179+
id: CounterId,
182180
region: CodeRegion,
183181
) -> bool {
184182
if let Some(coverage_context) = self.coverage_context() {
@@ -202,10 +200,10 @@ impl<'tcx> Builder<'_, '_, 'tcx> {
202200
fn add_coverage_counter_expression(
203201
&mut self,
204202
instance: Instance<'tcx>,
205-
id: InjectedExpressionId,
206-
lhs: ExpressionOperandId,
203+
id: ExpressionId,
204+
lhs: Operand,
207205
op: Op,
208-
rhs: ExpressionOperandId,
206+
rhs: Operand,
209207
region: Option<CodeRegion>,
210208
) -> bool {
211209
if let Some(coverage_context) = self.coverage_context() {

compiler/rustc_const_eval/src/interpret/step.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
208208
let rest_ptr = first_ptr.offset(elem_size, self)?;
209209
// For the alignment of `rest_ptr`, we crucially do *not* use `first.align` as
210210
// that place might be more aligned than its type mandates (a `u8` array could
211-
// be 4-aligned if it sits at the right spot in a struct). Instead we use
212-
// `first.layout.align`, i.e., the alignment given by the type.
211+
// be 4-aligned if it sits at the right spot in a struct). We have to also factor
212+
// in element size.
213213
self.mem_copy_repeatedly(
214214
first_ptr,
215-
first.align,
215+
dest.align,
216216
rest_ptr,
217-
first.layout.align.abi,
217+
dest.align.restrict_for_offset(elem_size),
218218
elem_size,
219219
length - 1,
220220
/*nonoverlapping:*/ true,

compiler/rustc_data_structures/src/base_n.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,21 @@ const BASE_64: &[u8; MAX_BASE] =
1616
pub fn push_str(mut n: u128, base: usize, output: &mut String) {
1717
debug_assert!(base >= 2 && base <= MAX_BASE);
1818
let mut s = [0u8; 128];
19-
let mut index = 0;
19+
let mut index = s.len();
2020

2121
let base = base as u128;
2222

2323
loop {
24+
index -= 1;
2425
s[index] = BASE_64[(n % base) as usize];
25-
index += 1;
2626
n /= base;
2727

2828
if n == 0 {
2929
break;
3030
}
3131
}
32-
s[0..index].reverse();
3332

34-
output.push_str(str::from_utf8(&s[0..index]).unwrap());
33+
output.push_str(str::from_utf8(&s[index..]).unwrap());
3534
}
3635

3736
#[inline]

compiler/rustc_data_structures/src/sync/vec.rs

+7-21
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,23 @@ impl<I: Idx, T: Copy> AppendOnlyIndexVec<I, T> {
4343

4444
#[derive(Default)]
4545
pub struct AppendOnlyVec<T: Copy> {
46-
#[cfg(not(parallel_compiler))]
47-
vec: elsa::vec::FrozenVec<T>,
48-
#[cfg(parallel_compiler)]
49-
vec: elsa::sync::LockFreeFrozenVec<T>,
46+
vec: parking_lot::RwLock<Vec<T>>,
5047
}
5148

5249
impl<T: Copy> AppendOnlyVec<T> {
5350
pub fn new() -> Self {
54-
Self {
55-
#[cfg(not(parallel_compiler))]
56-
vec: elsa::vec::FrozenVec::new(),
57-
#[cfg(parallel_compiler)]
58-
vec: elsa::sync::LockFreeFrozenVec::new(),
59-
}
51+
Self { vec: Default::default() }
6052
}
6153

6254
pub fn push(&self, val: T) -> usize {
63-
#[cfg(not(parallel_compiler))]
64-
let i = self.vec.len();
65-
#[cfg(not(parallel_compiler))]
66-
self.vec.push(val);
67-
#[cfg(parallel_compiler)]
68-
let i = self.vec.push(val);
69-
i
55+
let mut v = self.vec.write();
56+
let n = v.len();
57+
v.push(val);
58+
n
7059
}
7160

7261
pub fn get(&self, i: usize) -> Option<T> {
73-
#[cfg(not(parallel_compiler))]
74-
return self.vec.get_copy(i);
75-
#[cfg(parallel_compiler)]
76-
return self.vec.get(i);
62+
self.vec.read().get(i).copied()
7763
}
7864

7965
pub fn iter_enumerated(&self) -> impl Iterator<Item = (usize, T)> + '_ {

0 commit comments

Comments
 (0)