rewrite post-processing routines not to require a `CrateContext`
These do some low-level munging on the LLVM data structures. Unclear that they need to operate as a "second pass" but leave it for now.
This commit is contained in:
parent
bc79f01a58
commit
863927c712
|
@ -799,7 +799,8 @@ fn write_metadata(cx: &SharedCrateContext,
|
|||
/// Find any symbols that are defined in one compilation unit, but not declared
|
||||
/// in any other compilation unit. Give these symbols internal linkage.
|
||||
fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||
ccxs: &CrateContextList<'a, 'tcx>,
|
||||
scx: &SharedCrateContext<'a, 'tcx>,
|
||||
llvm_modules: &[ModuleLlvm],
|
||||
symbol_map: &SymbolMap<'tcx>,
|
||||
exported_symbols: &ExportedSymbols) {
|
||||
let export_threshold =
|
||||
|
@ -814,7 +815,6 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
|||
.map(|&(ref name, _)| &name[..])
|
||||
.collect::<FxHashSet<&str>>();
|
||||
|
||||
let scx = ccxs.shared();
|
||||
let tcx = scx.tcx();
|
||||
|
||||
let incr_comp = sess.opts.debugging_opts.incremental.is_some();
|
||||
|
@ -829,8 +829,8 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
|||
// incremental compilation, we don't need to collect. See below for more
|
||||
// information.
|
||||
if !incr_comp {
|
||||
for ccx in ccxs.iter_need_trans() {
|
||||
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
|
||||
for ll in llvm_modules {
|
||||
for val in iter_globals(ll.llmod).chain(iter_functions(ll.llmod)) {
|
||||
let linkage = llvm::LLVMRustGetLinkage(val);
|
||||
// We only care about external declarations (not definitions)
|
||||
// and available_externally definitions.
|
||||
|
@ -866,8 +866,8 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
|||
// Examine each external definition. If the definition is not used in
|
||||
// any other compilation unit, and is not reachable from other crates,
|
||||
// then give it internal linkage.
|
||||
for ccx in ccxs.iter_need_trans() {
|
||||
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
|
||||
for ll in llvm_modules {
|
||||
for val in iter_globals(ll.llmod).chain(iter_functions(ll.llmod)) {
|
||||
let linkage = llvm::LLVMRustGetLinkage(val);
|
||||
|
||||
let is_externally_visible = (linkage == llvm::Linkage::ExternalLinkage) ||
|
||||
|
@ -926,19 +926,20 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
|||
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||
// code references on its own.
|
||||
// See #26591, #27438
|
||||
fn create_imps(cx: &CrateContextList) {
|
||||
fn create_imps(sess: &Session,
|
||||
llvm_modules: &[ModuleLlvm]) {
|
||||
// The x86 ABI seems to require that leading underscores are added to symbol
|
||||
// names, so we need an extra underscore on 32-bit. There's also a leading
|
||||
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
|
||||
// underscores added in front).
|
||||
let prefix = if cx.shared().sess().target.target.target_pointer_width == "32" {
|
||||
let prefix = if sess.target.target.target_pointer_width == "32" {
|
||||
"\x01__imp__"
|
||||
} else {
|
||||
"\x01__imp_"
|
||||
};
|
||||
unsafe {
|
||||
for ccx in cx.iter_need_trans() {
|
||||
let exported: Vec<_> = iter_globals(ccx.llmod())
|
||||
for ll in llvm_modules {
|
||||
let exported: Vec<_> = iter_globals(ll.llmod)
|
||||
.filter(|&val| {
|
||||
llvm::LLVMRustGetLinkage(val) ==
|
||||
llvm::Linkage::ExternalLinkage &&
|
||||
|
@ -946,13 +947,13 @@ fn create_imps(cx: &CrateContextList) {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let i8p_ty = Type::i8p(&ccx);
|
||||
let i8p_ty = Type::i8p_llcx(ll.llcx);
|
||||
for val in exported {
|
||||
let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
|
||||
let mut imp_name = prefix.as_bytes().to_vec();
|
||||
imp_name.extend(name.to_bytes());
|
||||
let imp_name = CString::new(imp_name).unwrap();
|
||||
let imp = llvm::LLVMAddGlobal(ccx.llmod(),
|
||||
let imp = llvm::LLVMAddGlobal(ll.llmod,
|
||||
i8p_ty.to_ref(),
|
||||
imp_name.as_ptr() as *const _);
|
||||
let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
|
||||
|
@ -1244,11 +1245,23 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let exported_symbols = ExportedSymbols::compute_from(&shared_ccx,
|
||||
&symbol_map);
|
||||
|
||||
// Get the list of llvm modules we created. We'll do a few wacky
|
||||
// transforms on them now.
|
||||
|
||||
let llvm_modules: Vec<_> =
|
||||
modules.iter()
|
||||
.filter_map(|module| match module.source {
|
||||
ModuleSource::Translated(llvm) => Some(llvm),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Now that we have all symbols that are exported from the CGUs of this
|
||||
// crate, we can run the `internalize_symbols` pass.
|
||||
time(shared_ccx.sess().time_passes(), "internalize symbols", || {
|
||||
internalize_symbols(sess,
|
||||
&crate_context_list,
|
||||
&shared_ccx,
|
||||
&llvm_modules,
|
||||
&symbol_map,
|
||||
&exported_symbols);
|
||||
});
|
||||
|
@ -1259,7 +1272,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
if sess.target.target.options.is_like_msvc &&
|
||||
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
|
||||
create_imps(&crate_context_list);
|
||||
create_imps(sess, &llvm_modules);
|
||||
}
|
||||
|
||||
let linker_info = LinkerInfo::new(&shared_ccx, &exported_symbols);
|
||||
|
|
|
@ -244,21 +244,6 @@ impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
|
|||
filter_to_previous_work_product_unavail: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over all CCX that need translation (cannot reuse results from
|
||||
/// previous incr. comp.).
|
||||
pub fn iter_need_trans<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> {
|
||||
CrateContextIterator {
|
||||
shared: self.shared,
|
||||
index: 0,
|
||||
local_ccxs: &self.local_ccxs[..],
|
||||
filter_to_previous_work_product_unavail: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shared(&self) -> &'a SharedCrateContext<'a, 'tcx> {
|
||||
self.shared
|
||||
}
|
||||
}
|
||||
|
||||
/// A CrateContext value binds together one LocalCrateContext with the
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use llvm;
|
||||
use llvm::{TypeRef, Bool, False, True, TypeKind};
|
||||
use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind};
|
||||
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
||||
|
||||
use context::CrateContext;
|
||||
|
@ -82,6 +82,10 @@ impl Type {
|
|||
ty!(llvm::LLVMInt8TypeInContext(ccx.llcx()))
|
||||
}
|
||||
|
||||
pub fn i8_llcx(llcx: ContextRef) -> Type {
|
||||
ty!(llvm::LLVMInt8TypeInContext(llcx))
|
||||
}
|
||||
|
||||
pub fn i16(ccx: &CrateContext) -> Type {
|
||||
ty!(llvm::LLVMInt16TypeInContext(ccx.llcx()))
|
||||
}
|
||||
|
@ -123,6 +127,10 @@ impl Type {
|
|||
Type::i8(ccx).ptr_to()
|
||||
}
|
||||
|
||||
pub fn i8p_llcx(llcx: ContextRef) -> Type {
|
||||
Type::i8_llcx(llcx).ptr_to()
|
||||
}
|
||||
|
||||
pub fn int(ccx: &CrateContext) -> Type {
|
||||
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
|
||||
"16" => Type::i16(ccx),
|
||||
|
|
Loading…
Reference in New Issue