Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #70438

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/etc/gdb_rust_pretty_printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ def children(self):
innermap = GdbValue(self.__val.get_wrapped_value()['map'])
if innermap.get_wrapped_value()['length'] > 0:
root = GdbValue(innermap.get_wrapped_value()['root'])
type_name = str(root.type.ty.name).replace('core::option::Option<', '')[:-1]
type_name = str(root.type.ty.name).replace('core::option::Option<', '', 1)[:-1]
root = root.get_wrapped_value().cast(gdb.lookup_type(type_name))
node_ptr = root['node']
i = 0
Expand All @@ -398,7 +398,7 @@ def to_string(self):
def children(self):
if self.__val.get_wrapped_value()['length'] > 0:
root = GdbValue(self.__val.get_wrapped_value()['root'])
type_name = str(root.type.ty.name).replace('core::option::Option<', '')[:-1]
type_name = str(root.type.ty.name).replace('core::option::Option<', '', 1)[:-1]
root = root.get_wrapped_value().cast(gdb.lookup_type(type_name))
node_ptr = root['node']
i = 0
Expand Down
87 changes: 47 additions & 40 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use crate::ModuleLlvm;
use log::debug;
use rustc::bug;
use rustc::ty::TyCtxt;
use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig};
use rustc_codegen_ssa::back::write::{
run_assembler, BitcodeSection, CodegenContext, EmitObj, ModuleConfig,
};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
use rustc_data_structures::small_c_str::SmallCStr;
Expand Down Expand Up @@ -651,7 +653,7 @@ pub(crate) unsafe fn codegen(
let thin = ThinBuffer::new(llmod);
let data = thin.data();

if config.emit_bc || config.obj_is_bitcode {
if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_emit_bitcode",
&module.name[..],
Expand All @@ -662,7 +664,7 @@ pub(crate) unsafe fn codegen(
}
}

if config.embed_bitcode == EmbedBitcode::Full {
if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_embed_bitcode",
&module.name[..],
Expand All @@ -682,7 +684,7 @@ pub(crate) unsafe fn codegen(
diag_handler.err(&msg);
}
}
} else if config.embed_bitcode == EmbedBitcode::Marker {
} else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) {
embed_bitcode(cgcx, llcx, llmod, None);
}

Expand Down Expand Up @@ -732,9 +734,9 @@ pub(crate) unsafe fn codegen(
})?;
}

let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode;
let config_emit_object_code = matches!(config.emit_obj, EmitObj::ObjectCode(_));

if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) {
if config.emit_asm || (config_emit_object_code && config.no_integrated_as) {
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
Expand All @@ -743,60 +745,65 @@ pub(crate) unsafe fn codegen(
// We can't use the same module for asm and binary output, because that triggers
// various errors like invalid IR or broken binaries, so we might have to clone the
// module to produce the asm output
let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod };
let llmod = if config_emit_object_code { llvm::LLVMCloneModule(llmod) } else { llmod };
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile)
})?;
}

if config_emit_normal_obj {
if !config.no_integrated_as {
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(
diag_handler,
tm,
cpm,
llmod,
&obj_out,
llvm::FileType::ObjectFile,
)
})?;
} else {
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
run_assembler(cgcx, diag_handler, &assembly, &obj_out);

if !config.emit_asm && !cgcx.save_temps {
drop(fs::remove_file(&assembly));
match config.emit_obj {
EmitObj::ObjectCode(_) => {
if !config.no_integrated_as {
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_emit_obj",
&module.name[..],
);
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(
diag_handler,
tm,
cpm,
llmod,
&obj_out,
llvm::FileType::ObjectFile,
)
})?;
} else {
let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_asm_to_obj",
&module.name[..],
);
let assembly =
cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
run_assembler(cgcx, diag_handler, &assembly, &obj_out);

if !config.emit_asm && !cgcx.save_temps {
drop(fs::remove_file(&assembly));
}
}
}
}

if config.obj_is_bitcode {
if config.emit_obj {
EmitObj::Bitcode => {
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
if let Err(e) = link_or_copy(&bc_out, &obj_out) {
diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
}
}

if !config.emit_bc {
debug!("removing_bitcode {:?}", bc_out);
if let Err(e) = fs::remove_file(&bc_out) {
diag_handler.err(&format!("failed to remove bitcode: {}", e));
if !config.emit_bc {
debug!("removing_bitcode {:?}", bc_out);
if let Err(e) = fs::remove_file(&bc_out) {
diag_handler.err(&format!("failed to remove bitcode: {}", e));
}
}
}

EmitObj::None => {}
}

drop(handlers);
}
Ok(module.into_compiled_module(
config.emit_obj,
config.emit_obj != EmitObj::None,
config.emit_bc,
config.emit_bc_compressed,
&cgcx.output_filenames,
Expand Down
82 changes: 49 additions & 33 deletions src/librustc_codegen_ssa/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,31 @@ use std::thread;

const PRE_LTO_BC_EXT: &str = "pre-lto.bc";

/// The kind of bitcode to embed in object files.
#[derive(PartialEq)]
pub enum EmbedBitcode {
/// What kind of object file to emit.
#[derive(Clone, Copy, PartialEq)]
pub enum EmitObj {
// No object file.
None,

// Just uncompressed llvm bitcode. Provides easy compatibility with
// emscripten's ecc compiler, when used as the linker.
Bitcode,

// Object code, possibly augmented with a bitcode section.
ObjectCode(BitcodeSection),
}

/// What kind of llvm bitcode section to embed in an object file.
#[derive(Clone, Copy, PartialEq)]
pub enum BitcodeSection {
// No bitcode section.
None,

// An empty bitcode section (to placate tools such as the iOS linker that
// require this section even if they don't use it).
Marker,

// A full, uncompressed bitcode section.
Full,
}

Expand Down Expand Up @@ -84,7 +104,7 @@ pub struct ModuleConfig {
pub emit_bc_compressed: bool,
pub emit_ir: bool,
pub emit_asm: bool,
pub emit_obj: bool,
pub emit_obj: EmitObj,
// Miscellaneous flags. These are mostly copied from command-line
// options.
pub verify_llvm_ir: bool,
Expand All @@ -96,12 +116,7 @@ pub struct ModuleConfig {
pub merge_functions: bool,
pub inline_threshold: Option<usize>,
pub new_llvm_pass_manager: Option<bool>,
// Instead of creating an object file by doing LLVM codegen, just
// make the object file bitcode. Provides easy compatibility with
// emscripten's ecc compiler, when used as the linker.
pub obj_is_bitcode: bool,
pub no_integrated_as: bool,
pub embed_bitcode: EmbedBitcode,
}

impl ModuleConfig {
Expand All @@ -124,9 +139,7 @@ impl ModuleConfig {
emit_bc_compressed: false,
emit_ir: false,
emit_asm: false,
emit_obj: false,
obj_is_bitcode: false,
embed_bitcode: EmbedBitcode::None,
emit_obj: EmitObj::None,
no_integrated_as: false,

verify_llvm_ir: false,
Expand All @@ -147,17 +160,6 @@ impl ModuleConfig {
self.no_builtins = no_builtins || sess.target.target.options.no_builtins;
self.inline_threshold = sess.opts.cg.inline_threshold;
self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
self.obj_is_bitcode =
sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
self.embed_bitcode =
if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode {
match sess.opts.optimize {
config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker,
_ => EmbedBitcode::Full,
}
} else {
EmbedBitcode::None
};

// Copy what clang does by turning on loop vectorization at O2 and
// slp vectorization at O3. Otherwise configure other optimization aspects
Expand Down Expand Up @@ -194,9 +196,9 @@ impl ModuleConfig {

pub fn bitcode_needed(&self) -> bool {
self.emit_bc
|| self.obj_is_bitcode
|| self.emit_bc_compressed
|| self.embed_bitcode == EmbedBitcode::Full
|| self.emit_obj == EmitObj::Bitcode
|| self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)
}
}

Expand Down Expand Up @@ -397,6 +399,20 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
allocator_config.emit_bc_compressed = true;
}

let emit_obj =
if sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
EmitObj::Bitcode
} else if sess.opts.debugging_opts.embed_bitcode {
match sess.opts.optimize {
config::OptLevel::No | config::OptLevel::Less => {
EmitObj::ObjectCode(BitcodeSection::Marker)
}
_ => EmitObj::ObjectCode(BitcodeSection::Full),
}
} else {
EmitObj::ObjectCode(BitcodeSection::None)
};

modules_config.emit_pre_lto_bc = need_pre_lto_bitcode_for_incr_comp(sess);

modules_config.no_integrated_as =
Expand All @@ -416,20 +432,20 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
// could be invoked specially with output_type_assembly, so
// in this case we still want the metadata object file.
if !sess.opts.output_types.contains_key(&OutputType::Assembly) {
metadata_config.emit_obj = true;
allocator_config.emit_obj = true;
metadata_config.emit_obj = emit_obj;
allocator_config.emit_obj = emit_obj;
}
}
OutputType::Object => {
modules_config.emit_obj = true;
modules_config.emit_obj = emit_obj;
}
OutputType::Metadata => {
metadata_config.emit_obj = true;
metadata_config.emit_obj = emit_obj;
}
OutputType::Exe => {
modules_config.emit_obj = true;
metadata_config.emit_obj = true;
allocator_config.emit_obj = true;
modules_config.emit_obj = emit_obj;
metadata_config.emit_obj = emit_obj;
allocator_config.emit_obj = emit_obj;
}
OutputType::Mir => {}
OutputType::DepInfo => {}
Expand Down Expand Up @@ -880,7 +896,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
}
}

assert_eq!(object.is_some(), module_config.emit_obj);
assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None);
assert_eq!(bytecode.is_some(), module_config.emit_bc);
assert_eq!(bytecode_compressed.is_some(), module_config.emit_bc_compressed);

Expand Down
4 changes: 3 additions & 1 deletion src/librustc_error_codes/error_codes/E0459.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
A link was used without a name parameter. Erroneous code example:
A link was used without a name parameter.

Erroneous code example:

```compile_fail,E0459
#[link(kind = "dylib")] extern {}
Expand Down
44 changes: 42 additions & 2 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,17 +833,57 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
ptr: Scalar<M::PointerTag>,
src: impl IntoIterator<Item = u8>,
) -> InterpResult<'tcx> {
let src = src.into_iter();
let mut src = src.into_iter();
let size = Size::from_bytes(src.size_hint().0);
// `write_bytes` checks that this lower bound `size` matches the upper bound and reality.
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? {
Some(ptr) => ptr,
None => return Ok(()), // zero-sized access
None => {
// zero-sized access
src.next().expect_none("iterator said it was empty but returned an element");
return Ok(());
}
};
let tcx = self.tcx.tcx;
self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
}

/// Writes the given stream of u16s into memory.
///
/// Performs appropriate bounds checks.
pub fn write_u16s(
&mut self,
ptr: Scalar<M::PointerTag>,
src: impl IntoIterator<Item = u16>,
) -> InterpResult<'tcx> {
let mut src = src.into_iter();
let (lower, upper) = src.size_hint();
let len = upper.expect("can only write bounded iterators");
assert_eq!(lower, len, "can only write iterators with a precise length");

let size = Size::from_bytes(lower);
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(2).unwrap())? {
Some(ptr) => ptr,
None => {
// zero-sized access
src.next().expect_none("iterator said it was empty but returned an element");
return Ok(());
}
};
let tcx = self.tcx.tcx;
let allocation = self.get_raw_mut(ptr.alloc_id)?;

for idx in 0..len {
let val = Scalar::from_u16(
src.next().expect("iterator was shorter than it said it would be"),
);
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
}
src.next().expect_none("iterator was longer than it said it would be");
Ok(())
}

/// Expects the caller to have checked bounds and alignment.
pub fn copy(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust.
#![feature(range_is_empty)]
#![feature(stmt_expr_attributes)]
#![feature(trait_alias)]
#![feature(option_expect_none)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down
Loading