Skip to content

Commit 1221e43

Browse files
committed
Auto merge of #111984 - matthiaskrgr:rollup-6u7ynyv, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #111384 (Fix linking Mac Catalyst by including LC_BUILD_VERSION in object files) - #111899 (CGU cleanups) - #111940 (Clarify safety concern of `io::Read::read` is only relevant in unsafe code) - #111947 (Add test for RPIT defined with different hidden types with different substs) - #111951 (Correct comment on privately uninhabited pattern.) Failed merges: - #111954 (improve error message for calling a method on a raw pointer with an unknown pointee) r? `@ghost` `@rustbot` modify labels: rollup
2 parents be72f25 + dd74ae0 commit 1221e43

File tree

14 files changed

+424
-289
lines changed

14 files changed

+424
-289
lines changed

compiler/rustc_codegen_ssa/src/back/metadata.rs

+32
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
188188
};
189189

190190
let mut file = write::Object::new(binary_format, architecture, endianness);
191+
if sess.target.is_like_osx {
192+
if let Some(build_version) = macho_object_build_version_for_target(&sess.target) {
193+
file.set_macho_build_version(build_version)
194+
}
195+
}
191196
let e_flags = match architecture {
192197
Architecture::Mips => {
193198
let arch = match sess.target.options.cpu.as_ref() {
@@ -258,6 +263,33 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
258263
Some(file)
259264
}
260265

266+
/// Apple's LD, when linking for Mac Catalyst, requires object files to
267+
/// contain information about what they were built for (LC_BUILD_VERSION):
268+
/// the platform (macOS/watchOS etc), minimum OS version, and SDK version.
269+
/// This returns a `MachOBuildVersion` if necessary for the target.
270+
fn macho_object_build_version_for_target(
271+
target: &Target,
272+
) -> Option<object::write::MachOBuildVersion> {
273+
if !target.llvm_target.ends_with("-macabi") {
274+
return None;
275+
}
276+
/// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz"
277+
/// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200
278+
fn pack_version((major, minor): (u32, u32)) -> u32 {
279+
(major << 16) | (minor << 8)
280+
}
281+
282+
let platform = object::macho::PLATFORM_MACCATALYST;
283+
let min_os = (14, 0);
284+
let sdk = (16, 2);
285+
286+
let mut build_version = object::write::MachOBuildVersion::default();
287+
build_version.platform = platform;
288+
build_version.minos = pack_version(min_os);
289+
build_version.sdk = pack_version(sdk);
290+
Some(build_version)
291+
}
292+
261293
pub enum MetadataPosition {
262294
First,
263295
Last,

compiler/rustc_middle/src/mir/mono.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,7 @@ impl<'tcx> CodegenUnit<'tcx> {
334334
}
335335

336336
pub fn modify_size_estimate(&mut self, delta: usize) {
337-
assert!(self.size_estimate.is_some());
338-
if let Some(size_estimate) = self.size_estimate {
339-
self.size_estimate = Some(size_estimate + delta);
340-
}
337+
*self.size_estimate.as_mut().unwrap() += delta;
341338
}
342339

343340
pub fn contains_item(&self, item: &MonoItem<'tcx>) -> bool {

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,8 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
491491
AdtDefinedHere { adt_def_span, ty, variants }
492492
};
493493

494-
// Emit an extra note if the first uncovered witness is
495-
// visibly uninhabited anywhere in the current crate.
494+
// Emit an extra note if the first uncovered witness would be uninhabited
495+
// if we disregard visibility.
496496
let witness_1_is_privately_uninhabited =
497497
if cx.tcx.features().exhaustive_patterns
498498
&& let Some(witness_1) = witnesses.get(0)

compiler/rustc_monomorphize/src/partitioning/default.rs

+113-37
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cmp;
12
use std::collections::hash_map::Entry;
23

34
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -14,10 +15,7 @@ use rustc_span::symbol::Symbol;
1415

1516
use super::PartitioningCx;
1617
use crate::collector::InliningMap;
17-
use crate::partitioning::merging;
18-
use crate::partitioning::{
19-
MonoItemPlacement, Partition, PostInliningPartitioning, PreInliningPartitioning,
20-
};
18+
use crate::partitioning::{MonoItemPlacement, Partition, PlacedRootMonoItems};
2119

2220
pub struct DefaultPartitioning;
2321

@@ -26,7 +24,7 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
2624
&mut self,
2725
cx: &PartitioningCx<'_, 'tcx>,
2826
mono_items: &mut I,
29-
) -> PreInliningPartitioning<'tcx>
27+
) -> PlacedRootMonoItems<'tcx>
3028
where
3129
I: Iterator<Item = MonoItem<'tcx>>,
3230
{
@@ -91,38 +89,120 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
9189
codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
9290
}
9391

94-
PreInliningPartitioning {
95-
codegen_units: codegen_units.into_values().collect(),
96-
roots,
97-
internalization_candidates,
98-
}
92+
let codegen_units = codegen_units.into_values().collect();
93+
PlacedRootMonoItems { codegen_units, roots, internalization_candidates }
9994
}
10095

10196
fn merge_codegen_units(
10297
&mut self,
10398
cx: &PartitioningCx<'_, 'tcx>,
104-
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
99+
codegen_units: &mut Vec<CodegenUnit<'tcx>>,
105100
) {
106-
merging::merge_codegen_units(cx, initial_partitioning);
101+
assert!(cx.target_cgu_count >= 1);
102+
103+
// Note that at this point in time the `codegen_units` here may not be
104+
// in a deterministic order (but we know they're deterministically the
105+
// same set). We want this merging to produce a deterministic ordering
106+
// of codegen units from the input.
107+
//
108+
// Due to basically how we've implemented the merging below (merge the
109+
// two smallest into each other) we're sure to start off with a
110+
// deterministic order (sorted by name). This'll mean that if two cgus
111+
// have the same size the stable sort below will keep everything nice
112+
// and deterministic.
113+
codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
114+
115+
// This map keeps track of what got merged into what.
116+
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
117+
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
118+
119+
// Merge the two smallest codegen units until the target size is
120+
// reached.
121+
while codegen_units.len() > cx.target_cgu_count {
122+
// Sort small cgus to the back
123+
codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
124+
let mut smallest = codegen_units.pop().unwrap();
125+
let second_smallest = codegen_units.last_mut().unwrap();
126+
127+
// Move the mono-items from `smallest` to `second_smallest`
128+
second_smallest.modify_size_estimate(smallest.size_estimate());
129+
for (k, v) in smallest.items_mut().drain() {
130+
second_smallest.items_mut().insert(k, v);
131+
}
132+
133+
// Record that `second_smallest` now contains all the stuff that was
134+
// in `smallest` before.
135+
let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
136+
cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names);
137+
138+
debug!(
139+
"CodegenUnit {} merged into CodegenUnit {}",
140+
smallest.name(),
141+
second_smallest.name()
142+
);
143+
}
144+
145+
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
146+
147+
if cx.tcx.sess.opts.incremental.is_some() {
148+
// If we are doing incremental compilation, we want CGU names to
149+
// reflect the path of the source level module they correspond to.
150+
// For CGUs that contain the code of multiple modules because of the
151+
// merging done above, we use a concatenation of the names of all
152+
// contained CGUs.
153+
let new_cgu_names: FxHashMap<Symbol, String> = cgu_contents
154+
.into_iter()
155+
// This `filter` makes sure we only update the name of CGUs that
156+
// were actually modified by merging.
157+
.filter(|(_, cgu_contents)| cgu_contents.len() > 1)
158+
.map(|(current_cgu_name, cgu_contents)| {
159+
let mut cgu_contents: Vec<&str> =
160+
cgu_contents.iter().map(|s| s.as_str()).collect();
161+
162+
// Sort the names, so things are deterministic and easy to
163+
// predict. We are sorting primitive `&str`s here so we can
164+
// use unstable sort.
165+
cgu_contents.sort_unstable();
166+
167+
(current_cgu_name, cgu_contents.join("--"))
168+
})
169+
.collect();
170+
171+
for cgu in codegen_units.iter_mut() {
172+
if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
173+
if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
174+
cgu.set_name(Symbol::intern(&new_cgu_name));
175+
} else {
176+
// If we don't require CGU names to be human-readable,
177+
// we use a fixed length hash of the composite CGU name
178+
// instead.
179+
let new_cgu_name = CodegenUnit::mangle_name(&new_cgu_name);
180+
cgu.set_name(Symbol::intern(&new_cgu_name));
181+
}
182+
}
183+
}
184+
} else {
185+
// If we are compiling non-incrementally we just generate simple CGU
186+
// names containing an index.
187+
for (index, cgu) in codegen_units.iter_mut().enumerate() {
188+
let numbered_codegen_unit_name =
189+
cgu_name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index));
190+
cgu.set_name(numbered_codegen_unit_name);
191+
}
192+
}
107193
}
108194

109195
fn place_inlined_mono_items(
110196
&mut self,
111197
cx: &PartitioningCx<'_, 'tcx>,
112-
initial_partitioning: PreInliningPartitioning<'tcx>,
113-
) -> PostInliningPartitioning<'tcx> {
114-
let mut new_partitioning = Vec::new();
198+
codegen_units: &mut [CodegenUnit<'tcx>],
199+
roots: FxHashSet<MonoItem<'tcx>>,
200+
) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
115201
let mut mono_item_placements = FxHashMap::default();
116202

117-
let PreInliningPartitioning {
118-
codegen_units: initial_cgus,
119-
roots,
120-
internalization_candidates,
121-
} = initial_partitioning;
122-
123-
let single_codegen_unit = initial_cgus.len() == 1;
203+
let single_codegen_unit = codegen_units.len() == 1;
124204

125-
for old_codegen_unit in initial_cgus {
205+
for old_codegen_unit in codegen_units.iter_mut() {
126206
// Collect all items that need to be available in this codegen unit.
127207
let mut reachable = FxHashSet::default();
128208
for root in old_codegen_unit.items().keys() {
@@ -174,14 +254,10 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
174254
}
175255
}
176256

177-
new_partitioning.push(new_codegen_unit);
257+
*old_codegen_unit = new_codegen_unit;
178258
}
179259

180-
return PostInliningPartitioning {
181-
codegen_units: new_partitioning,
182-
mono_item_placements,
183-
internalization_candidates,
184-
};
260+
return mono_item_placements;
185261

186262
fn follow_inlining<'tcx>(
187263
mono_item: MonoItem<'tcx>,
@@ -201,14 +277,16 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
201277
fn internalize_symbols(
202278
&mut self,
203279
cx: &PartitioningCx<'_, 'tcx>,
204-
partitioning: &mut PostInliningPartitioning<'tcx>,
280+
codegen_units: &mut [CodegenUnit<'tcx>],
281+
mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
282+
internalization_candidates: FxHashSet<MonoItem<'tcx>>,
205283
) {
206-
if partitioning.codegen_units.len() == 1 {
284+
if codegen_units.len() == 1 {
207285
// Fast path for when there is only one codegen unit. In this case we
208286
// can internalize all candidates, since there is nowhere else they
209287
// could be accessed from.
210-
for cgu in &mut partitioning.codegen_units {
211-
for candidate in &partitioning.internalization_candidates {
288+
for cgu in codegen_units {
289+
for candidate in &internalization_candidates {
212290
cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default));
213291
}
214292
}
@@ -225,15 +303,13 @@ impl<'tcx> Partition<'tcx> for DefaultPartitioning {
225303
}
226304
});
227305

228-
let mono_item_placements = &partitioning.mono_item_placements;
229-
230306
// For each internalization candidates in each codegen unit, check if it is
231307
// accessed from outside its defining codegen unit.
232-
for cgu in &mut partitioning.codegen_units {
308+
for cgu in codegen_units {
233309
let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
234310

235311
for (accessee, linkage_and_visibility) in cgu.items_mut() {
236-
if !partitioning.internalization_candidates.contains(accessee) {
312+
if !internalization_candidates.contains(accessee) {
237313
// This item is no candidate for internalizing, so skip it.
238314
continue;
239315
}

0 commit comments

Comments
 (0)