Skip to content

Commit

Permalink
Rollup merge of #119885 - DianQK:revert-pr-113923, r=petrochenkov
Browse files Browse the repository at this point in the history
Revert #113923

Per [#t-compiler/meetings > [weekly] 2024-01-11](https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202024-01-11) discussion, revert #113923. Also revert associated #118568.

The PR #113923 causes the regression issue #118609. We need more time to find a proper solution.

Discussions start at [412365838](https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202024-01-11/near/412365838) and continue to [412369643](https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202024-01-11/near/412369643).

Fixes #118609.

r? compiler
  • Loading branch information
GuillaumeGomez authored Jan 12, 2024
2 parents c997b29 + aa874c5 commit dafbe17
Show file tree
Hide file tree
Showing 21 changed files with 90 additions and 160 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn prepare_lto(
};

let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
if info.level.is_below_threshold(export_threshold) || info.used || info.used_compiler {
if info.level.is_below_threshold(export_threshold) || info.used {
Some(CString::new(name.as_str()).unwrap())
} else {
None
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ pub(crate) unsafe fn llvm_optimize(
unroll_loops,
config.vectorize_slp,
config.vectorize_loop,
config.no_builtins,
config.emit_lifetime_markers,
sanitizer_options.as_ref(),
pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
Expand Down Expand Up @@ -677,14 +678,15 @@ pub(crate) unsafe fn codegen(
unsafe fn with_codegen<'ll, F, R>(
tm: &'ll llvm::TargetMachine,
llmod: &'ll llvm::Module,
no_builtins: bool,
f: F,
) -> R
where
F: FnOnce(&'ll mut PassManager<'ll>) -> R,
{
let cpm = llvm::LLVMCreatePassManager();
llvm::LLVMAddAnalysisPasses(tm, cpm);
llvm::LLVMRustAddLibraryInfo(cpm, llmod);
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
f(cpm)
}

Expand Down Expand Up @@ -785,7 +787,7 @@ pub(crate) unsafe fn codegen(
} else {
llmod
};
with_codegen(tm, llmod, |cpm| {
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(
dcx,
tm,
Expand Down Expand Up @@ -820,7 +822,7 @@ pub(crate) unsafe fn codegen(
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
};

with_codegen(tm, llmod, |cpm| {
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(
dcx,
tm,
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2173,8 +2173,13 @@ extern "C" {
ArgsCstrBuff: *const c_char,
ArgsCstrBuffLen: usize,
) -> *mut TargetMachine;

pub fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine);
pub fn LLVMRustAddLibraryInfo<'a>(PM: &PassManager<'a>, M: &'a Module);
pub fn LLVMRustAddLibraryInfo<'a>(
PM: &PassManager<'a>,
M: &'a Module,
DisableSimplifyLibCalls: bool,
);
pub fn LLVMRustWriteOutputFile<'a>(
T: &'a TargetMachine,
PM: &PassManager<'a>,
Expand All @@ -2196,6 +2201,7 @@ extern "C" {
UnrollLoops: bool,
SLPVectorize: bool,
LoopVectorize: bool,
DisableSimplifyLibCalls: bool,
EmitLifetimeMarkers: bool,
SanitizerOptions: Option<&SanitizerOptions>,
PGOGenPath: *const c_char,
Expand Down
46 changes: 34 additions & 12 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,8 @@ pub fn each_linked_rlib(

for &cnum in crates {
match fmts.get(cnum.as_usize() - 1) {
Some(&Linkage::NotLinked | &Linkage::Dynamic) => continue,
Some(&Linkage::IncludedFromDylib) => {
// We always link crate `compiler_builtins` statically. When enabling LTO, we include it as well.
if info.compiler_builtins != Some(cnum) {
continue;
}
}
Some(&Linkage::Static) => {}
Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
Some(_) => {}
None => return Err(errors::LinkRlibError::MissingFormat),
}
let crate_name = info.crate_name[&cnum];
Expand Down Expand Up @@ -526,7 +520,8 @@ fn link_staticlib<'a>(
&codegen_results.crate_info,
Some(CrateType::Staticlib),
&mut |cnum, path| {
let lto = are_upstream_rust_objects_already_included(sess);
let lto = are_upstream_rust_objects_already_included(sess)
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum);

let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
Expand Down Expand Up @@ -1277,6 +1272,24 @@ fn link_sanitizer_runtime(
}
}

/// Returns a boolean indicating whether the specified crate should be ignored
/// during LTO.
///
/// Crates ignored during LTO are not lumped together in the "massive object
/// file" that we create and are linked in their normal rlib states. See
/// comments below for what crates do not participate in LTO.
///
/// It's unusual for a crate to not participate in LTO. Typically only
/// compiler-specific and unstable crates have a reason to not participate in
/// LTO.
pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool {
// If our target enables builtin function lowering in LLVM then the
// crates providing these functions don't participate in LTO (e.g.
// no_builtins or compiler builtins crates).
!sess.target.no_builtins
&& (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
}

/// This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use
pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
fn infer_from(
Expand Down Expand Up @@ -2742,6 +2755,10 @@ fn rehome_sysroot_lib_dir<'a>(sess: &'a Session, lib_dir: &Path) -> PathBuf {
// symbols). We must continue to include the rest of the rlib, however, as
// it may contain static native libraries which must be linked in.
//
// (*) Crates marked with `#![no_builtins]` don't participate in LTO and
// their bytecode wasn't included. The object files in those libraries must
// still be passed to the linker.
//
// Note, however, that if we're not doing LTO we can just pass the rlib
// blindly to the linker (fast) because it's fine if it's not actually
// included as we're at the end of the dependency chain.
Expand All @@ -2767,7 +2784,9 @@ fn add_static_crate<'a>(
cmd.link_rlib(&rlib_path);
};

if !are_upstream_rust_objects_already_included(sess) {
if !are_upstream_rust_objects_already_included(sess)
|| ignored_for_lto(sess, &codegen_results.crate_info, cnum)
{
link_upstream(cratepath);
return;
}
Expand All @@ -2781,6 +2800,8 @@ fn add_static_crate<'a>(
let canonical_name = name.replace('-', "_");
let upstream_rust_objects_already_included =
are_upstream_rust_objects_already_included(sess);
let is_builtins =
sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum);

let mut archive = archive_builder_builder.new_archive_builder(sess);
if let Err(error) = archive.add_archive(
Expand All @@ -2797,8 +2818,9 @@ fn add_static_crate<'a>(

// If we're performing LTO and this is a rust-generated object
// file, then we don't need the object file as it's part of the
// LTO module.
if upstream_rust_objects_already_included && is_rust_object {
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
// though, so we let that object file slide.
if upstream_rust_objects_already_included && is_rust_object && is_builtins {
return true;
}

Expand Down
22 changes: 3 additions & 19 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
// export level, however, as they're just implementation details.
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE);
let special_runtime_crate = tcx.is_panic_runtime(LOCAL_CRATE) || is_compiler_builtins;
let special_runtime_crate =
tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE);

let mut reachable_non_generics: DefIdMap<_> = tcx
.reachable_set(())
Expand Down Expand Up @@ -105,21 +105,16 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
}
})
.map(|def_id| {
let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id());
// We won't link right if this symbol is stripped during LTO.
let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
// We have to preserve the symbols of the built-in functions during LTO.
let is_builtin_fn = is_compiler_builtins
&& symbol_export_level(tcx, def_id.to_def_id())
.is_below_threshold(SymbolExportLevel::C)
&& codegen_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
let used = name == "rust_eh_personality";

let export_level = if special_runtime_crate {
SymbolExportLevel::Rust
} else {
symbol_export_level(tcx, def_id.to_def_id())
};
let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id());
debug!(
"EXPORTED SYMBOL (local): {} ({:?})",
tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())),
Expand All @@ -139,7 +134,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|| used,
used_compiler: is_builtin_fn,
};
(def_id.to_def_id(), info)
})
Expand All @@ -152,7 +146,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
used_compiler: false,
},
);
}
Expand Down Expand Up @@ -201,7 +194,6 @@ fn exported_symbols_provider_local(
level: info.level,
kind: SymbolExportKind::Text,
used: info.used,
used_compiler: false,
},
)
})
Expand All @@ -218,7 +210,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::C,
kind: SymbolExportKind::Text,
used: false,
used_compiler: false,
},
));
}
Expand All @@ -238,7 +229,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Text,
used: false,
used_compiler: false,
},
));
}
Expand All @@ -251,7 +241,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Data,
used: false,
used_compiler: false,
},
))
}
Expand All @@ -271,7 +260,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
used_compiler: false,
},
)
}));
Expand All @@ -297,7 +285,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
used_compiler: false,
},
)
}));
Expand All @@ -315,7 +302,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: true,
used_compiler: false,
},
));
}
Expand Down Expand Up @@ -356,7 +342,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Text,
used: false,
used_compiler: false,
},
));
}
Expand All @@ -373,7 +358,6 @@ fn exported_symbols_provider_local(
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Text,
used: false,
used_compiler: false,
},
));
}
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,23 @@ impl ModuleConfig {

let emit_obj = if !should_emit_obj {
EmitObj::None
} else if sess.target.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
} else if sess.target.obj_is_bitcode
|| (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
{
// This case is selected if the target uses objects as bitcode, or
// if linker plugin LTO is enabled. In the linker plugin LTO case
// the assumption is that the final link-step will read the bitcode
// and convert it to object code. This may be done by either the
// native linker or rustc itself.
//
// Note, however, that the linker-plugin-lto requested here is
// explicitly ignored for `#![no_builtins]` crates. These crates are
// specifically ignored by rustc's LTO passes and wouldn't work if
// loaded into the linker. These crates define symbols that LLVM
// lowers intrinsics to, and these symbol dependencies aren't known
// until after codegen. As a result any crate marked
// `#![no_builtins]` is assumed to not participate in LTO and
// instead goes on to generate object code.
EmitObj::Bitcode
} else if need_bitcode_in_object(tcx) {
EmitObj::ObjectCode(BitcodeSection::Full)
Expand Down Expand Up @@ -1023,6 +1034,9 @@ fn start_executing_work<B: ExtraBackendMethods>(

let mut each_linked_rlib_for_lto = Vec::new();
drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
if link::ignored_for_lto(sess, crate_info, cnum) {
return;
}
each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
}));

Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ impl CrateInfo {
local_crate_name,
compiler_builtins,
profiler_runtime: None,
is_no_builtins: Default::default(),
native_libraries: Default::default(),
used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(),
crate_name: Default::default(),
Expand All @@ -885,14 +886,19 @@ impl CrateInfo {
if tcx.is_profiler_runtime(cnum) {
info.profiler_runtime = Some(cnum);
}
if tcx.is_no_builtins(cnum) {
info.is_no_builtins.insert(cnum);
}
}

// Handle circular dependencies in the standard library.
// See comment before `add_linked_symbol_object` function for the details.
// If global LTO is enabled then almost everything (*) is glued into a single object file,
// so this logic is not necessary and can cause issues on some targets (due to weak lang
// item symbols being "privatized" to that object file), so we disable it.
// (*) Native libs are not glued, and we assume that they cannot define weak lang items.
// (*) Native libs, and `#[compiler_builtins]` and `#[no_builtins]` crates are not glued,
// and we assume that they cannot define weak lang items. This is not currently enforced
// by the compiler, but that's ok because all this stuff is unstable anyway.
let target = &tcx.sess.target;
if !are_upstream_rust_objects_already_included(tcx.sess) {
let missing_weak_lang_items: FxHashSet<Symbol> = info
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extern crate tracing;
extern crate rustc_middle;

use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_hir::def_id::CrateNum;
use rustc_middle::dep_graph::WorkProduct;
Expand Down Expand Up @@ -158,6 +158,7 @@ pub struct CrateInfo {
pub local_crate_name: Symbol,
pub compiler_builtins: Option<CrateNum>,
pub profiler_runtime: Option<CrateNum>,
pub is_no_builtins: FxHashSet<CrateNum>,
pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>,
pub crate_name: FxHashMap<CrateNum, Symbol>,
pub used_libraries: Vec<NativeLib>,
Expand Down
Loading

0 comments on commit dafbe17

Please sign in to comment.