Skip to content

Commit e6327bc

Browse files
committed
Auto merge of rust-lang#97159 - JohnTitor:rollup-ibl51vw, r=JohnTitor
Rollup of 6 pull requests Successful merges: - rust-lang#96866 (Switch CI bucket uploads to intelligent tiering) - rust-lang#97062 (Couple of refactorings to cg_ssa::base::codegen_crate) - rust-lang#97127 (Revert "Auto merge of rust-lang#96441 - ChrisDenton:sync-pipes, r=m-ou-se") - rust-lang#97131 (Improve println! documentation) - rust-lang#97139 (Move some settings DOM generation out of JS) - rust-lang#97152 (Update cargo) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents d8a3fc4 + 9babb1c commit e6327bc

File tree

12 files changed

+75
-188
lines changed

12 files changed

+75
-188
lines changed

compiler/rustc_codegen_ssa/src/base.rs

+24-33
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ use rustc_attr as attr;
1515
use rustc_data_structures::fx::FxHashMap;
1616
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
1717

18+
use rustc_data_structures::sync::par_iter;
1819
#[cfg(parallel_compiler)]
19-
use rustc_data_structures::sync::{par_iter, ParallelIterator};
20+
use rustc_data_structures::sync::ParallelIterator;
2021
use rustc_hir as hir;
2122
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
2223
use rustc_hir::lang_items::LangItem;
@@ -607,6 +608,14 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
607608
second_half.iter().rev().interleave(first_half).copied().collect()
608609
};
609610

611+
// Calculate the CGU reuse
612+
let cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
613+
codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::<Vec<_>>()
614+
});
615+
616+
let mut total_codegen_time = Duration::new(0, 0);
617+
let start_rss = tcx.sess.time_passes().then(|| get_resident_set_size());
618+
610619
// The non-parallel compiler can only translate codegen units to LLVM IR
611620
// on a single thread, leading to a staircase effect where the N LLVM
612621
// threads have to wait on the single codegen threads to generate work
@@ -617,8 +626,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
617626
// This likely is a temporary measure. Once we don't have to support the
618627
// non-parallel compiler anymore, we can compile CGUs end-to-end in
619628
// parallel and get rid of the complicated scheduling logic.
620-
#[cfg(parallel_compiler)]
621-
let pre_compile_cgus = |cgu_reuse: &[CguReuse]| {
629+
let mut pre_compiled_cgus = if cfg!(parallel_compiler) {
622630
tcx.sess.time("compile_first_CGU_batch", || {
623631
// Try to find one CGU to compile per thread.
624632
let cgus: Vec<_> = cgu_reuse
@@ -638,48 +646,31 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
638646
})
639647
.collect();
640648

641-
(pre_compiled_cgus, start_time.elapsed())
649+
total_codegen_time += start_time.elapsed();
650+
651+
pre_compiled_cgus
642652
})
653+
} else {
654+
FxHashMap::default()
643655
};
644656

645-
#[cfg(not(parallel_compiler))]
646-
let pre_compile_cgus = |_: &[CguReuse]| (FxHashMap::default(), Duration::new(0, 0));
647-
648-
let mut cgu_reuse = Vec::new();
649-
let mut pre_compiled_cgus: Option<FxHashMap<usize, _>> = None;
650-
let mut total_codegen_time = Duration::new(0, 0);
651-
let start_rss = tcx.sess.time_passes().then(|| get_resident_set_size());
652-
653657
for (i, cgu) in codegen_units.iter().enumerate() {
654658
ongoing_codegen.wait_for_signal_to_codegen_item();
655659
ongoing_codegen.check_for_errors(tcx.sess);
656660

657-
// Do some setup work in the first iteration
658-
if pre_compiled_cgus.is_none() {
659-
// Calculate the CGU reuse
660-
cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
661-
codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect()
662-
});
663-
// Pre compile some CGUs
664-
let (compiled_cgus, codegen_time) = pre_compile_cgus(&cgu_reuse);
665-
pre_compiled_cgus = Some(compiled_cgus);
666-
total_codegen_time += codegen_time;
667-
}
668-
669661
let cgu_reuse = cgu_reuse[i];
670662
tcx.sess.cgu_reuse_tracker.set_actual_reuse(cgu.name().as_str(), cgu_reuse);
671663

672664
match cgu_reuse {
673665
CguReuse::No => {
674-
let (module, cost) =
675-
if let Some(cgu) = pre_compiled_cgus.as_mut().unwrap().remove(&i) {
676-
cgu
677-
} else {
678-
let start_time = Instant::now();
679-
let module = backend.compile_codegen_unit(tcx, cgu.name());
680-
total_codegen_time += start_time.elapsed();
681-
module
682-
};
666+
let (module, cost) = if let Some(cgu) = pre_compiled_cgus.remove(&i) {
667+
cgu
668+
} else {
669+
let start_time = Instant::now();
670+
let module = backend.compile_codegen_unit(tcx, cgu.name());
671+
total_codegen_time += start_time.elapsed();
672+
module
673+
};
683674
// This will unwind if there are errors, which triggers our `AbortCodegenOnDrop`
684675
// guard. Unfortunately, just skipping the `submit_codegened_module_to_llvm` makes
685676
// compilation hang on post-monomorphization errors.

library/std/src/macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ macro_rules! print {
7272
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
7373
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
7474
///
75-
/// Use the [`format!`] syntax to write data to the standard output.
75+
/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
7676
/// See [`std::fmt`] for more information.
7777
///
7878
/// Use `println!` only for the primary output of your program. Use

library/std/src/os/windows/io/handle.rs

-13
Original file line numberDiff line numberDiff line change
@@ -204,19 +204,6 @@ impl OwnedHandle {
204204
})?;
205205
unsafe { Ok(Self::from_raw_handle(ret)) }
206206
}
207-
208-
/// Allow child processes to inherit the handle.
209-
#[cfg(not(target_vendor = "uwp"))]
210-
pub(crate) fn set_inheritable(&self) -> io::Result<()> {
211-
cvt(unsafe {
212-
c::SetHandleInformation(
213-
self.as_raw_handle(),
214-
c::HANDLE_FLAG_INHERIT,
215-
c::HANDLE_FLAG_INHERIT,
216-
)
217-
})?;
218-
Ok(())
219-
}
220207
}
221208

222209
impl TryFrom<HandleOrInvalid> for OwnedHandle {

library/std/src/sys/windows/c.rs

-6
Original file line numberDiff line numberDiff line change
@@ -1026,12 +1026,6 @@ extern "system" {
10261026
bWaitAll: BOOL,
10271027
dwMilliseconds: DWORD,
10281028
) -> DWORD;
1029-
pub fn CreatePipe(
1030-
hReadPipe: *mut HANDLE,
1031-
hWritePipe: *mut HANDLE,
1032-
lpPipeAttributes: *const SECURITY_ATTRIBUTES,
1033-
nSize: DWORD,
1034-
) -> BOOL;
10351029
pub fn CreateNamedPipeW(
10361030
lpName: LPCWSTR,
10371031
dwOpenMode: DWORD,

library/std/src/sys/windows/handle.rs

-5
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,6 @@ impl Handle {
221221
Ok(Self(self.0.duplicate(access, inherit, options)?))
222222
}
223223

224-
#[cfg(not(target_vendor = "uwp"))]
225-
pub(crate) fn set_inheritable(&self) -> io::Result<()> {
226-
self.0.set_inheritable()
227-
}
228-
229224
/// Performs a synchronous read.
230225
///
231226
/// If the handle is opened for asynchronous I/O then this abort the process.

library/std/src/sys/windows/pipe.rs

+25-76
Original file line numberDiff line numberDiff line change
@@ -18,67 +18,20 @@ use crate::sys_common::IntoInner;
1818
// Anonymous pipes
1919
////////////////////////////////////////////////////////////////////////////////
2020

21-
// A 64kb pipe capacity is the same as a typical Linux default.
22-
const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024;
23-
24-
pub enum AnonPipe {
25-
Sync(Handle),
26-
Async(Handle),
21+
pub struct AnonPipe {
22+
inner: Handle,
2723
}
2824

2925
impl IntoInner<Handle> for AnonPipe {
3026
fn into_inner(self) -> Handle {
31-
match self {
32-
Self::Sync(handle) => handle,
33-
Self::Async(handle) => handle,
34-
}
27+
self.inner
3528
}
3629
}
3730

3831
pub struct Pipes {
3932
pub ours: AnonPipe,
4033
pub theirs: AnonPipe,
4134
}
42-
impl Pipes {
43-
/// Create a new pair of pipes where both pipes are synchronous.
44-
///
45-
/// These must not be used asynchronously.
46-
pub fn new_synchronous(
47-
ours_readable: bool,
48-
their_handle_inheritable: bool,
49-
) -> io::Result<Self> {
50-
unsafe {
51-
// If `CreatePipe` succeeds, these will be our pipes.
52-
let mut read = ptr::null_mut();
53-
let mut write = ptr::null_mut();
54-
55-
if c::CreatePipe(&mut read, &mut write, ptr::null(), PIPE_BUFFER_CAPACITY) == 0 {
56-
Err(io::Error::last_os_error())
57-
} else {
58-
let (ours, theirs) = if ours_readable { (read, write) } else { (write, read) };
59-
let ours = Handle::from_raw_handle(ours);
60-
#[cfg(not(target_vendor = "uwp"))]
61-
let theirs = Handle::from_raw_handle(theirs);
62-
#[cfg(target_vendor = "uwp")]
63-
let mut theirs = Handle::from_raw_handle(theirs);
64-
65-
if their_handle_inheritable {
66-
#[cfg(not(target_vendor = "uwp"))]
67-
{
68-
theirs.set_inheritable()?;
69-
}
70-
71-
#[cfg(target_vendor = "uwp")]
72-
{
73-
theirs = theirs.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?;
74-
}
75-
}
76-
77-
Ok(Pipes { ours: AnonPipe::Sync(ours), theirs: AnonPipe::Sync(theirs) })
78-
}
79-
}
80-
}
81-
}
8235

8336
/// Although this looks similar to `anon_pipe` in the Unix module it's actually
8437
/// subtly different. Here we'll return two pipes in the `Pipes` return value,
@@ -100,6 +53,9 @@ impl Pipes {
10053
/// with `OVERLAPPED` instances, but also works out ok if it's only ever used
10154
/// once at a time (which we do indeed guarantee).
10255
pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result<Pipes> {
56+
// A 64kb pipe capacity is the same as a typical Linux default.
57+
const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024;
58+
10359
// Note that we specifically do *not* use `CreatePipe` here because
10460
// unfortunately the anonymous pipes returned do not support overlapped
10561
// operations. Instead, we create a "hopefully unique" name and create a
@@ -200,9 +156,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
200156
};
201157
opts.security_attributes(&mut sa);
202158
let theirs = File::open(Path::new(&name), &opts)?;
203-
let theirs = AnonPipe::Sync(theirs.into_inner());
159+
let theirs = AnonPipe { inner: theirs.into_inner() };
204160

205-
Ok(Pipes { ours: AnonPipe::Async(ours), theirs })
161+
Ok(Pipes {
162+
ours: AnonPipe { inner: ours },
163+
theirs: AnonPipe { inner: theirs.into_inner() },
164+
})
206165
}
207166
}
208167

@@ -212,12 +171,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
212171
/// This is achieved by creating a new set of pipes and spawning a thread that
213172
/// relays messages between the source and the synchronous pipe.
214173
pub fn spawn_pipe_relay(
215-
source: &Handle,
174+
source: &AnonPipe,
216175
ours_readable: bool,
217176
their_handle_inheritable: bool,
218177
) -> io::Result<AnonPipe> {
219178
// We need this handle to live for the lifetime of the thread spawned below.
220-
let source = AnonPipe::Async(source.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?);
179+
let source = source.duplicate()?;
221180

222181
// create a new pair of anon pipes.
223182
let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?;
@@ -268,24 +227,19 @@ type AlertableIoFn = unsafe extern "system" fn(
268227

269228
impl AnonPipe {
270229
pub fn handle(&self) -> &Handle {
271-
match self {
272-
Self::Async(ref handle) => handle,
273-
Self::Sync(ref handle) => handle,
274-
}
230+
&self.inner
275231
}
276232
pub fn into_handle(self) -> Handle {
277-
self.into_inner()
233+
self.inner
234+
}
235+
fn duplicate(&self) -> io::Result<Self> {
236+
self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| AnonPipe { inner })
278237
}
279238

280239
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
281240
let result = unsafe {
282241
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
283-
match self {
284-
Self::Sync(ref handle) => handle.read(buf),
285-
Self::Async(_) => {
286-
self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
287-
}
288-
}
242+
self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
289243
};
290244

291245
match result {
@@ -299,33 +253,28 @@ impl AnonPipe {
299253
}
300254

301255
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
302-
io::default_read_vectored(|buf| self.read(buf), bufs)
256+
self.inner.read_vectored(bufs)
303257
}
304258

305259
#[inline]
306260
pub fn is_read_vectored(&self) -> bool {
307-
false
261+
self.inner.is_read_vectored()
308262
}
309263

310264
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
311265
unsafe {
312266
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
313-
match self {
314-
Self::Sync(ref handle) => handle.write(buf),
315-
Self::Async(_) => {
316-
self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
317-
}
318-
}
267+
self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
319268
}
320269
}
321270

322271
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
323-
io::default_write_vectored(|buf| self.write(buf), bufs)
272+
self.inner.write_vectored(bufs)
324273
}
325274

326275
#[inline]
327276
pub fn is_write_vectored(&self) -> bool {
328-
false
277+
self.inner.is_write_vectored()
329278
}
330279

331280
/// Synchronizes asynchronous reads or writes using our anonymous pipe.
@@ -397,7 +346,7 @@ impl AnonPipe {
397346

398347
// Asynchronous read of the pipe.
399348
// If successful, `callback` will be called once it completes.
400-
let result = io(self.handle().as_handle(), buf, len, &mut overlapped, callback);
349+
let result = io(self.inner.as_handle(), buf, len, &mut overlapped, callback);
401350
if result == c::FALSE {
402351
// We can return here because the call failed.
403352
// After this we must not return until the I/O completes.

0 commit comments

Comments
 (0)