diff options
Diffstat (limited to 'compiler/rustc_codegen_gcc')
19 files changed, 451 insertions, 478 deletions
diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index 6df2102470f..1cb219e12e0 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -12,12 +12,6 @@ dependencies = [ ] [[package]] -name = "ar" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "450575f58f7bee32816abbff470cbc47797397c2a81e0eaced4b98436daf52e1" - -[[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -212,10 +206,8 @@ dependencies = [ name = "rustc_codegen_gcc" version = "0.1.0" dependencies = [ - "ar", "gccjit", "lang_tester", - "target-lexicon", "tempfile", ] @@ -229,12 +221,6 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d" - -[[package]] name = "tempfile" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml index 211d19a8dc8..1f3da2f799b 100644 --- a/compiler/rustc_codegen_gcc/Cargo.toml +++ b/compiler/rustc_codegen_gcc/Cargo.toml @@ -27,10 +27,6 @@ gccjit = { git = "https://github.com/antoyo/gccjit.rs" } # Local copy. #gccjit = { path = "../gccjit.rs" } -target-lexicon = "0.10.0" - -ar = "0.8.0" - [dev-dependencies] lang_tester = "0.3.9" tempfile = "3.1.0" diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 89661918d05..fd01fcf1fc8 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -13,17 +13,17 @@ // The minimum alignment guaranteed by the architecture. This value is used to // add fast paths for low alignment values. -#[cfg(all(any(target_arch = "x86", +#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "mips", target_arch = "powerpc", - target_arch = "powerpc64")))] + target_arch = "powerpc64"))] const MIN_ALIGN: usize = 8; -#[cfg(all(any(target_arch = "x86_64", +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")))] + target_arch = "sparc64"))] const MIN_ALIGN: usize = 16; pub struct System; diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 848c34211ff..6fb1cbfad8c 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -11,10 +11,6 @@ use crate::intrinsic::ArgAbiExt; use crate::type_of::LayoutGccExt; impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) { - // TODO(antoyo) - } - fn get_param(&mut self, index: usize) -> Self::Value { let func = self.current_func(); let param = func.get_param(index as i32); diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 58efb81e800..e2c9ffe9c1c 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -7,7 +7,7 @@ use rustc_span::symbol::sym; use crate::GccContext; -pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, has_alloc_error_handler: bool) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) { let context = &mods.context; let usize = match tcx.sess.target.pointer_width { @@ -90,14 +90,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam .collect(); let func = context.new_function(None, FunctionType::Exported, void, &args, name, false); - let kind = - if has_alloc_error_handler { - AllocatorKind::Global - } - else { - AllocatorKind::Default - }; - let callee = kind.fn_name(sym::oom); + let callee = alloc_error_handler_kind.fn_name(sym::oom); let args: Vec<_> = types.iter().enumerate() .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) .collect(); diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs index f863abdcc97..11fa074f5ac 100644 --- a/compiler/rustc_codegen_gcc/src/archive.rs +++ b/compiler/rustc_codegen_gcc/src/archive.rs @@ -1,42 +1,17 @@ -use std::fs::File; use std::path::{Path, PathBuf}; -use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; +use rustc_codegen_ssa::back::archive::{ + get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, +}; use rustc_session::Session; use rustc_session::cstore::DllImport; -struct ArchiveConfig<'a> { - sess: &'a Session, - use_native_ar: bool, - use_gnu_style_archive: bool, -} - -#[derive(Debug)] -enum ArchiveEntry { - FromArchive { - archive_index: usize, - entry_index: usize, - }, - File(PathBuf), -} - -pub struct ArArchiveBuilderBuilder; +pub(crate) struct ArArchiveBuilderBuilder; impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> { - let config = ArchiveConfig { - sess, - use_native_ar: false, - // FIXME test for linux and System V derivatives instead - use_gnu_style_archive: sess.target.options.archive_format == "gnu", - }; - - Box::new(ArArchiveBuilder { - config, - src_archives: vec![], - entries: vec![], - }) + Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols)) } fn create_dll_import_lib( @@ -45,145 +20,8 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder { _lib_name: &str, _dll_imports: &[DllImport], _tmpdir: &Path, + _is_direct_dependency: bool, ) -> PathBuf { - unimplemented!(); - } -} - -pub struct ArArchiveBuilder<'a> { - config: ArchiveConfig<'a>, - src_archives: Vec<(PathBuf, ar::Archive<File>)>, - // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at - // the end of an archive for linkers to not get confused. - entries: Vec<(String, ArchiveEntry)>, -} - -impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { - fn add_file(&mut self, file: &Path) { - self.entries.push(( - file.file_name().unwrap().to_str().unwrap().to_string(), - ArchiveEntry::File(file.to_owned()), - )); - } - - fn add_archive( - &mut self, - archive_path: &Path, - mut skip: Box<dyn FnMut(&str) -> bool + 'static>, - ) -> std::io::Result<()> { - let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?); - let archive_index = self.src_archives.len(); - - let mut i = 0; - while let Some(entry) = archive.next_entry() { - let entry = entry?; - let file_name = String::from_utf8(entry.header().identifier().to_vec()) - .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; - if !skip(&file_name) { - self.entries - .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i })); - } - i += 1; - } - - self.src_archives.push((archive_path.to_owned(), archive)); - Ok(()) - } - - fn build(mut self: Box<Self>, output: &Path) -> bool { - use std::process::Command; - - fn add_file_using_ar(archive: &Path, file: &Path) { - Command::new("ar") - .arg("r") // add or replace file - .arg("-c") // silence created file message - .arg(archive) - .arg(&file) - .status() - .unwrap(); - } - - enum BuilderKind<'a> { - Bsd(ar::Builder<File>), - Gnu(ar::GnuBuilder<File>), - NativeAr(&'a Path), - } - - let mut builder = if self.config.use_native_ar { - BuilderKind::NativeAr(output) - } else if self.config.use_gnu_style_archive { - BuilderKind::Gnu(ar::GnuBuilder::new( - File::create(output).unwrap(), - self.entries - .iter() - .map(|(name, _)| name.as_bytes().to_vec()) - .collect(), - )) - } else { - BuilderKind::Bsd(ar::Builder::new(File::create(output).unwrap())) - }; - - let any_members = !self.entries.is_empty(); - - // Add all files - for (entry_name, entry) in self.entries.into_iter() { - match entry { - ArchiveEntry::FromArchive { - archive_index, - entry_index, - } => { - let (ref src_archive_path, ref mut src_archive) = - self.src_archives[archive_index]; - let entry = src_archive.jump_to_entry(entry_index).unwrap(); - let header = entry.header().clone(); - - match builder { - BuilderKind::Bsd(ref mut builder) => { - builder.append(&header, entry).unwrap() - } - BuilderKind::Gnu(ref mut builder) => { - builder.append(&header, entry).unwrap() - } - BuilderKind::NativeAr(archive_file) => { - Command::new("ar") - .arg("x") - .arg(src_archive_path) - .arg(&entry_name) - .status() - .unwrap(); - add_file_using_ar(archive_file, Path::new(&entry_name)); - std::fs::remove_file(entry_name).unwrap(); - } - } - } - ArchiveEntry::File(file) => - match builder { - BuilderKind::Bsd(ref mut builder) => { - builder - .append_file(entry_name.as_bytes(), &mut File::open(file).expect("file for bsd builder")) - .unwrap() - }, - BuilderKind::Gnu(ref mut builder) => { - builder - .append_file(entry_name.as_bytes(), &mut File::open(&file).expect(&format!("file {:?} for gnu builder", file))) - .unwrap() - }, - BuilderKind::NativeAr(archive_file) => add_file_using_ar(archive_file, &file), - }, - } - } - - // Finalize archive - std::mem::drop(builder); - - // Run ranlib to be able to link the archive - let status = - std::process::Command::new("ranlib").arg(output).status().expect("Couldn't run ranlib"); - - if !status.success() { - self.config.sess.fatal(&format!("Ranlib exited with code {:?}", status.code())); - } - - any_members + unimplemented!("creating dll imports is not yet supported"); } } diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 52fd66af065..c346dbd63cc 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -12,6 +12,7 @@ use std::borrow::Cow; use crate::builder::Builder; use crate::context::CodegenCx; +use crate::errors::UnwindingInlineAsm; use crate::type_of::LayoutGccExt; use crate::callee::get_fn; @@ -109,7 +110,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) { if options.contains(InlineAsmOptions::MAY_UNWIND) { self.sess() - .struct_span_err(span[0], "GCC backend does not support unwinding from inline asm") + .create_err(UnwindingInlineAsm { span: span[0] }) .emit(); return; } @@ -497,7 +498,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) }; - self.call(self.type_void(), builtin_unreachable, &[], None); + self.call(self.type_void(), None, builtin_unreachable, &[], None); } // Write results to outputs. diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 6994eeb00c3..782f6856654 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -444,11 +444,23 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block.end_with_switch(None, value, default_block, &gcc_cases); } - fn invoke(&mut self, typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { + fn invoke( + &mut self, + typ: Type<'gcc>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + then: Block<'gcc>, + catch: Block<'gcc>, + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { // TODO(bjorn3): Properly implement unwinding. - let call_site = self.call(typ, func, args, None); + let call_site = self.call(typ, None, func, args, None); let condition = self.context.new_rvalue_from_int(self.bool_type, 1); self.llbb().end_with_conditional(None, condition, then, catch); + if let Some(_fn_abi) = fn_abi { + // TODO(bjorn3): Apply function attributes + } call_site } @@ -643,11 +655,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.current_func().new_local(None, aligned_type, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None) } - fn dynamic_alloca(&mut self, _ty: Type<'gcc>, _align: Align) -> RValue<'gcc> { - unimplemented!(); - } - - fn array_alloca(&mut self, _ty: Type<'gcc>, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { + fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { unimplemented!(); } @@ -747,11 +755,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandRef { val, layout: place.layout } } - fn write_operand_repeatedly(mut self, cg_elem: OperandRef<'tcx, RValue<'gcc>>, count: u64, dest: PlaceRef<'tcx, RValue<'gcc>>) -> Self { + fn write_operand_repeatedly(&mut self, cg_elem: OperandRef<'tcx, RValue<'gcc>>, count: u64, dest: PlaceRef<'tcx, RValue<'gcc>>) { let zero = self.const_usize(0); let count = self.const_usize(count); - let start = dest.project_index(&mut self, zero).llval; - let end = dest.project_index(&mut self, count).llval; + let start = dest.project_index(self, zero).llval; + let end = dest.project_index(self, count).llval; let header_bb = self.append_sibling_block("repeat_loop_header"); let body_bb = self.append_sibling_block("repeat_loop_body"); @@ -770,14 +778,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.switch_to_block(body_bb); let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); - cg_elem.val.store(&mut self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align)); + cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align)); let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[self.const_usize(1)]); self.llbb().add_assignment(None, current, next); self.br(header_bb); self.switch_to_block(next_bb); - self } fn range_metadata(&mut self, _load: RValue<'gcc>, _range: WrappingRange) { @@ -1227,16 +1234,27 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // TODO(antoyo) } - fn call(&mut self, _typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>) -> RValue<'gcc> { + fn call( + &mut self, + _typ: Type<'gcc>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + funclet: Option<&Funclet>, + ) -> RValue<'gcc> { // FIXME(antoyo): remove when having a proper API. let gcc_func = unsafe { std::mem::transmute(func) }; - if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() { + let call = if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() { self.function_call(func, args, funclet) } else { // If it's a not function that was defined, it's a function pointer. self.function_ptr_call(func, args, funclet) + }; + if let Some(_fn_abi) = fn_abi { + // TODO(bjorn3): Apply function attributes } + call } fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 356c03ee3c1..ea8ab761146 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -8,7 +8,6 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint}; -use rustc_span::Span; use rustc_span::def_id::DefId; use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange}; @@ -238,12 +237,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } Node::ForeignItem(&hir::ForeignItem { - span, + span: _, kind: hir::ForeignItemKind::Static(..), .. }) => { let fn_attrs = self.tcx.codegen_fn_attrs(def_id); - check_and_apply_linkage(&self, &fn_attrs, ty, sym, span) + check_and_apply_linkage(&self, &fn_attrs, ty, sym) } item => bug!("get_static: expected static, found {:?}", item), @@ -256,8 +255,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { //debug!("get_static: sym={} item_attr={:?}", sym, self.tcx.item_attrs(def_id)); let attrs = self.tcx.codegen_fn_attrs(def_id); - let span = self.tcx.def_span(def_id); - let global = check_and_apply_linkage(&self, &attrs, ty, sym, span); + let global = check_and_apply_linkage(&self, &attrs, ty, sym); let needs_dll_storage_attr = false; // TODO(antoyo) @@ -296,12 +294,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAllocation<'tcx>) -> RValue<'gcc> { let alloc = alloc.inner(); - let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1); + let mut llvals = Vec::with_capacity(alloc.provenance().ptrs().len() + 1); let dl = cx.data_layout(); let pointer_size = dl.pointer_size.bytes() as usize; let mut next_offset = 0; - for &(offset, alloc_id) in alloc.provenance().iter() { + for &(offset, alloc_id) in alloc.provenance().ptrs().iter() { let offset = offset.bytes(); assert_eq!(offset as usize as u64, offset); let offset = offset as usize; @@ -354,27 +352,12 @@ pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id Ok((const_alloc_to_gcc(cx, alloc), alloc)) } -fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str, span: Span) -> LValue<'gcc> { +fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str) -> LValue<'gcc> { let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); let llty = cx.layout_of(ty).gcc_type(cx, true); - if let Some(linkage) = attrs.linkage { - // If this is a static with a linkage specified, then we need to handle - // it a little specially. The typesystem prevents things like &T and - // extern "C" fn() from being non-null, so we can't just declare a - // static and call it a day. Some linkages (like weak) will make it such - // that the static actually has a null value. - let llty2 = - if let ty::RawPtr(ref mt) = ty.kind() { - cx.layout_of(mt.ty).gcc_type(cx, true) - } - else { - cx.sess().span_fatal( - span, - "must have type `*const T` or `*mut T` due to `#[linkage]` attribute", - ) - }; + if let Some(linkage) = attrs.import_linkage { // Declare a symbol `foo` with the desired linkage. - let global1 = cx.declare_global_with_linkage(&sym, llty2, base::global_linkage_to_gcc(linkage)); + let global1 = cx.declare_global_with_linkage(&sym, cx.type_i8(), base::global_linkage_to_gcc(linkage)); // Declare an internal global `extern_with_linkage_foo` which // is initialized with the address of `foo`. If `foo` is diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 478f6d893dd..837708aeb0e 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, TyAndLayout, LayoutOfHelpers}; use rustc_session::Session; -use rustc_span::Span; +use rustc_span::{Span, source_map::respan}; use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx}; use rustc_target::spec::{HasTargetSpec, Target, TlsModel}; @@ -88,9 +88,9 @@ pub struct CodegenCx<'gcc, 'tcx> { pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>, // TODO(antoyo): improve the SSA API to not require those. - // Mapping from function pointer type to indexes of on stack parameters. + /// Mapping from function pointer type to indexes of on stack parameters. pub on_stack_params: RefCell<FxHashMap<FunctionPtrType<'gcc>, FxHashSet<usize>>>, - // Mapping from function to indexes of on stack parameters. + /// Mapping from function to indexes of on stack parameters. pub on_stack_function_params: RefCell<FxHashMap<Function<'gcc>, FxHashSet<usize>>>, /// Cache of emitted const globals (value -> global) @@ -293,7 +293,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ.is_compatible_with(self.bool_type) } - pub fn sess(&self) -> &Session { + pub fn sess(&self) -> &'tcx Session { &self.tcx.sess } @@ -416,10 +416,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.codegen_unit } - fn used_statics(&self) -> &RefCell<Vec<RValue<'gcc>>> { - unimplemented!(); - } - fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) { // TODO(antoyo) } @@ -428,13 +424,10 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // TODO(antoyo) } - fn create_used_variable(&self) { - unimplemented!(); - } - fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { - if self.get_declared_value("main").is_none() { - Some(self.declare_cfn("main", fn_type)) + let entry_name = self.sess().target.entry_name.as_ref(); + if self.get_declared_value(entry_name).is_none() { + Some(self.declare_entry_fn(entry_name, fn_type, ())) } else { // If the symbol already exists, it is an error: for example, the user wrote @@ -443,14 +436,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { None } } - - fn compiler_used_statics(&self) -> &RefCell<Vec<RValue<'gcc>>> { - unimplemented!() - } - - fn create_compiler_used_variable(&self) { - unimplemented!() - } } impl<'gcc, 'tcx> HasTyCtxt<'tcx> for CodegenCx<'gcc, 'tcx> { @@ -477,7 +462,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { if let LayoutError::SizeOverflow(_) = err { - self.sess().span_fatal(span, &err.to_string()) + self.sess().emit_fatal(respan(span, err)) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) } @@ -495,7 +480,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { - self.sess().span_fatal(span, &err.to_string()) + self.sess().emit_fatal(respan(span, err)) } else { match fn_abi_request { FnAbiRequest::OfFnPtr { sig, extra_args } => { diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 266759ed6cf..a81585d4128 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -4,8 +4,9 @@ use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods}; use rustc_middle::mir; use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; use rustc_span::{SourceFile, Span, Symbol}; -use rustc_target::abi::Size; use rustc_target::abi::call::FnAbi; +use rustc_target::abi::Size; +use std::ops::Range; use crate::builder::Builder; use crate::context::CodegenCx; @@ -13,7 +14,15 @@ use crate::context::CodegenCx; impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). - fn dbg_var_addr(&mut self, _dbg_var: Self::DIVariable, _scope_metadata: Self::DIScope, _variable_alloca: Self::Value, _direct_offset: Size, _indirect_offsets: &[Size]) { + fn dbg_var_addr( + &mut self, + _dbg_var: Self::DIVariable, + _scope_metadata: Self::DIScope, + _variable_alloca: Self::Value, + _direct_offset: Size, + _indirect_offsets: &[Size], + _fragment: Option<Range<Size>>, + ) { unimplemented!(); } @@ -31,16 +40,31 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { } impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn create_vtable_debuginfo(&self, _ty: Ty<'tcx>, _trait_ref: Option<PolyExistentialTraitRef<'tcx>>, _vtable: Self::Value) { + fn create_vtable_debuginfo( + &self, + _ty: Ty<'tcx>, + _trait_ref: Option<PolyExistentialTraitRef<'tcx>>, + _vtable: Self::Value, + ) { // TODO(antoyo) } - fn create_function_debug_context(&self, _instance: Instance<'tcx>, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _llfn: RValue<'gcc>, _mir: &mir::Body<'tcx>) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>> { + fn create_function_debug_context( + &self, + _instance: Instance<'tcx>, + _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + _llfn: RValue<'gcc>, + _mir: &mir::Body<'tcx>, + ) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>> { // TODO(antoyo) None } - fn extend_scope_to_file(&self, _scope_metadata: Self::DIScope, _file: &SourceFile) -> Self::DIScope { + fn extend_scope_to_file( + &self, + _scope_metadata: Self::DIScope, + _file: &SourceFile, + ) -> Self::DIScope { unimplemented!(); } @@ -48,15 +72,32 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // TODO(antoyo) } - fn create_dbg_var(&self, _variable_name: Symbol, _variable_type: Ty<'tcx>, _scope_metadata: Self::DIScope, _variable_kind: VariableKind, _span: Span) -> Self::DIVariable { + fn create_dbg_var( + &self, + _variable_name: Symbol, + _variable_type: Ty<'tcx>, + _scope_metadata: Self::DIScope, + _variable_kind: VariableKind, + _span: Span, + ) -> Self::DIVariable { unimplemented!(); } - fn dbg_scope_fn(&self, _instance: Instance<'tcx>, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _maybe_definition_llfn: Option<RValue<'gcc>>) -> Self::DIScope { + fn dbg_scope_fn( + &self, + _instance: Instance<'tcx>, + _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + _maybe_definition_llfn: Option<RValue<'gcc>>, + ) -> Self::DIScope { unimplemented!(); } - fn dbg_loc(&self, _scope: Self::DIScope, _inlined_at: Option<Self::DILocation>, _span: Span) -> Self::DILocation { + fn dbg_loc( + &self, + _scope: Self::DIScope, + _inlined_at: Option<Self::DILocation>, + _span: Span, + ) -> Self::DILocation { unimplemented!(); } } diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs index a619e2f7712..eae77508c97 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/src/declare.rs @@ -65,13 +65,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global } - pub fn declare_cfn(&self, name: &str, _fn_type: Type<'gcc>) -> RValue<'gcc> { + pub fn declare_entry_fn(&self, name: &str, _fn_type: Type<'gcc>, callconv: () /*llvm::CCallConv*/) -> RValue<'gcc> { // TODO(antoyo): use the fn_type parameter. let const_string = self.context.new_type::<u8>().make_pointer().make_pointer(); let return_type = self.type_i32(); let variadic = false; self.linkage.set(FunctionType::Exported); - let func = declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, &[self.type_i32(), const_string], variadic); + let func = declare_raw_fn(self, name, callconv, return_type, &[self.type_i32(), const_string], variadic); // NOTE: it is needed to set the current_func here as well, because get_fn() is not called // for the main function. *self.current_func.borrow_mut() = Some(func); diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs new file mode 100644 index 00000000000..d0ba7e24791 --- /dev/null +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -0,0 +1,223 @@ +use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; +use rustc_macros::Diagnostic; +use rustc_middle::ty::Ty; +use rustc_span::{Span, Symbol}; +use std::borrow::Cow; + +struct ExitCode(Option<i32>); + +impl IntoDiagnosticArg for ExitCode { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + let ExitCode(exit_code) = self; + match exit_code { + Some(t) => t.into_diagnostic_arg(), + None => DiagnosticArgValue::Str(Cow::Borrowed("<signal>")), + } + } +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_basic_integer, code = "E0511")] +pub(crate) struct InvalidMonomorphizationBasicInteger<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_invalid_float_vector, code = "E0511")] +pub(crate) struct InvalidMonomorphizationInvalidFloatVector<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub elem_ty: &'a str, + pub vec_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_not_float, code = "E0511")] +pub(crate) struct InvalidMonomorphizationNotFloat<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_unrecognized, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnrecognized { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_expected_signed_unsigned, code = "E0511")] +pub(crate) struct InvalidMonomorphizationExpectedSignedUnsigned<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub elem_ty: Ty<'a>, + pub vec_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_unsupported_element, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnsupportedElement<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_ty: Ty<'a>, + pub elem_ty: Ty<'a>, + pub ret_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_invalid_bitmask, code = "E0511")] +pub(crate) struct InvalidMonomorphizationInvalidBitmask<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, + pub expected_int_bits: u64, + pub expected_bytes: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_simd_shuffle, code = "E0511")] +pub(crate) struct InvalidMonomorphizationSimdShuffle<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_expected_simd, code = "E0511")] +pub(crate) struct InvalidMonomorphizationExpectedSimd<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub position: &'a str, + pub found_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_mask_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationMaskType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_return_length, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnLength<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_len: u64, + pub ret_ty: Ty<'a>, + pub out_len: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_return_length_input_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnLengthInputType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_len: u64, + pub in_ty: Ty<'a>, + pub ret_ty: Ty<'a>, + pub out_len: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_return_element, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnElement<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_elem: Ty<'a>, + pub in_ty: Ty<'a>, + pub ret_ty: Ty<'a>, + pub out_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_return_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_elem: Ty<'a>, + pub in_ty: Ty<'a>, + pub ret_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_inserted_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationInsertedType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_elem: Ty<'a>, + pub in_ty: Ty<'a>, + pub out_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_return_integer_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnIntegerType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ret_ty: Ty<'a>, + pub out_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_mismatched_lengths, code = "E0511")] +pub(crate) struct InvalidMonomorphizationMismatchedLengths { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub m_len: u64, + pub v_len: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_unsupported_cast, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnsupportedCast<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_ty: Ty<'a>, + pub in_elem: Ty<'a>, + pub ret_ty: Ty<'a>, + pub out_elem: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_invalid_monomorphization_unsupported_operation, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_ty: Ty<'a>, + pub in_elem: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc_lto_not_supported)] +pub(crate) struct LTONotSupported; + +#[derive(Diagnostic)] +#[diag(codegen_gcc_unwinding_inline_asm)] +pub(crate) struct UnwindingInlineAsm { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 02cedd4646b..49be6c649e6 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -4,7 +4,7 @@ mod simd; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp, FunctionType}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; -use rustc_codegen_ssa::common::{IntPredicate, span_invalid_monomorphization_error}; +use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{ArgAbiMethods, BaseTypeMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods}; @@ -20,6 +20,7 @@ use crate::abi::GccType; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; +use crate::errors::InvalidMonomorphizationBasicInteger; use crate::type_of::LayoutGccExt; use crate::intrinsic::simd::generic_simd_intrinsic; @@ -99,7 +100,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { _ if simple.is_some() => { // FIXME(antoyo): remove this cast when the API supports function. let func = unsafe { std::mem::transmute(simple.expect("simple")) }; - self.call(self.type_void(), func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) + self.call(self.type_void(), None, func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) }, sym::likely => { self.expect(args[0].immediate(), true) @@ -242,15 +243,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { _ => bug!(), }, None => { - span_invalid_monomorphization_error( - tcx.sess, - span, - &format!( - "invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", - name, ty - ), - ); + tcx.sess.emit_err(InvalidMonomorphizationBasicInteger { span, name, ty }); return; } } @@ -348,7 +341,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn abort(&mut self) { let func = self.context.get_builtin_function("abort"); let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; - self.call(self.type_void(), func, &[], None); + self.call(self.type_void(), None, func, &[], None); } fn assume(&mut self, value: Self::Value) { @@ -1131,7 +1124,7 @@ fn try_intrinsic<'gcc, 'tcx>(bx: &mut Builder<'_, 'gcc, 'tcx>, try_func: RValue< // NOTE: the `|| true` here is to use the panic=abort strategy with panic=unwind too if bx.sess().panic_strategy() == PanicStrategy::Abort || true { // TODO(bjorn3): Properly implement unwinding and remove the `|| true` once this is done. - bx.call(bx.type_void(), try_func, &[data], None); + bx.call(bx.type_void(), None, try_func, &[data], None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx.data_layout.i32_align.abi; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 2401f335018..12e416f62a4 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use gccjit::{BinaryOp, RValue, Type, ToRValue}; use rustc_codegen_ssa::base::compare_simd_types; -use rustc_codegen_ssa::common::{TypeKind, span_invalid_monomorphization_error}; +use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods}; @@ -14,43 +14,48 @@ use rustc_span::{Span, Symbol, sym}; use rustc_target::abi::Align; use crate::builder::Builder; +use crate::errors::{ + InvalidMonomorphizationInvalidFloatVector, + InvalidMonomorphizationNotFloat, + InvalidMonomorphizationUnrecognized, + InvalidMonomorphizationExpectedSignedUnsigned, + InvalidMonomorphizationUnsupportedElement, + InvalidMonomorphizationInvalidBitmask, + InvalidMonomorphizationSimdShuffle, + InvalidMonomorphizationExpectedSimd, + InvalidMonomorphizationMaskType, + InvalidMonomorphizationReturnLength, + InvalidMonomorphizationReturnLengthInputType, + InvalidMonomorphizationReturnElement, + InvalidMonomorphizationReturnType, + InvalidMonomorphizationInsertedType, + InvalidMonomorphizationReturnIntegerType, + InvalidMonomorphizationMismatchedLengths, + InvalidMonomorphizationUnsupportedCast, + InvalidMonomorphizationUnsupportedOperation +}; use crate::intrinsic; pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result<RValue<'gcc>, ()> { // macros for error handling: - #[allow(unused_macro_rules)] - macro_rules! emit_error { - ($msg: tt) => { - emit_error!($msg, ) - }; - ($msg: tt, $($fmt: tt)*) => { - span_invalid_monomorphization_error( - bx.sess(), span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), - name, $($fmt)*)); - } - } - macro_rules! return_error { - ($($fmt: tt)*) => { + ($err:expr) => { { - emit_error!($($fmt)*); + bx.sess().emit_err($err); return Err(()); } } } - macro_rules! require { - ($cond: expr, $($fmt: tt)*) => { + ($cond:expr, $err:expr) => { if !$cond { - return_error!($($fmt)*); + return_error!($err); } - }; + } } - macro_rules! require_simd { ($ty: expr, $position: expr) => { - require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) + require!($ty.is_simd(), InvalidMonomorphizationExpectedSimd { span, name, position: $position, found_ty: $ty }) }; } @@ -82,10 +87,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, bx.load(int_ty, ptr, Align::ONE) } _ => return_error!( - "invalid bitmask `{}`, expected `u{}` or `[u8; {}]`", - mask_ty, - expected_int_bits, - expected_bytes + InvalidMonomorphizationInvalidBitmask { span, name, ty: mask_ty, expected_int_bits, expected_bytes } ), }; @@ -127,18 +129,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len } ); require!( bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, - "expected return type with integer elements, found `{}` with non-integer `{}`", - ret_ty, - out_ty + InvalidMonomorphizationReturnIntegerType {span, name, ret_ty, out_ty} ); return Ok(compare_simd_types( @@ -163,8 +158,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, }) } _ => return_error!( - "simd_shuffle index must be an array of `u32`, got `{}`", - args[2].layout.ty + InvalidMonomorphizationSimdShuffle { span, name, ty: args[2].layout.ty } ), } } @@ -179,19 +173,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( out_len == n, - "expected return type of length {}, found `{}` with length {}", - n, - ret_ty, - out_len + InvalidMonomorphizationReturnLength { span, name, in_len: n, ret_ty, out_len } ); require!( in_elem == out_ty, - "expected return element type `{}` (element of input `{}`), \ - found `{}` with element type `{}`", - in_elem, - in_ty, - ret_ty, - out_ty + InvalidMonomorphizationReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty } ); let vector = args[2].immediate(); @@ -207,10 +193,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::simd_insert { require!( in_elem == arg_tys[2], - "expected inserted type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - arg_tys[2] + InvalidMonomorphizationInsertedType { span, name, in_elem, in_ty, out_ty: arg_tys[2] } ); let vector = args[0].immediate(); let index = args[1].immediate(); @@ -263,10 +246,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::simd_extract { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); let vector = args[0].immediate(); return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue()); @@ -279,13 +259,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); require!( m_len == v_len, - "mismatched lengths: mask length `{}` != other vector length `{}`", - m_len, - v_len + InvalidMonomorphizationMismatchedLengths { span, name, m_len, v_len } ); match m_elem_ty.kind() { ty::Int(_) => {} - _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty), + _ => return_error!(InvalidMonomorphizationMaskType { span, name, ty: m_elem_ty }), } return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate())); } @@ -295,12 +273,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len } ); // casting cares about nominal type, not just structural type if in_elem == out_elem { @@ -412,13 +385,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, } _ => { /* Unsupported. Fallthrough. */ } } - require!( - false, - "unsupported cast from `{}` with element `{}` to `{}` with element `{}`", - in_ty, - in_elem, - ret_ty, - out_elem + return_error!( + InvalidMonomorphizationUnsupportedCast { span, name, in_ty, in_elem, ret_ty, out_elem } ); } @@ -431,10 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, })* _ => {}, } - require!(false, - "unsupported operation on `{}` with element `{}`", - in_ty, - in_elem) + return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem }) })* } } @@ -448,23 +413,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, span: Span, args: &[OperandRef<'tcx, RValue<'gcc>>], ) -> Result<RValue<'gcc>, ()> { - macro_rules! emit_error { - ($msg: tt, $($fmt: tt)*) => { - span_invalid_monomorphization_error( - bx.sess(), span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), - name, $($fmt)*)); - } - } macro_rules! return_error { - ($($fmt: tt)*) => { + ($err:expr) => { { - emit_error!($($fmt)*); + bx.sess().emit_err($err); return Err(()); } } } - let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { let elem_ty = bx.cx.type_float_from_ty(*f); @@ -472,16 +428,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, 32 => ("f32", elem_ty), 64 => ("f64", elem_ty), _ => { - return_error!( - "unsupported element type `{}` of floating-point vector `{}`", - f.name_str(), - in_ty - ); + return_error!(InvalidMonomorphizationInvalidFloatVector { span, name, elem_ty: f.name_str(), vec_ty: in_ty }); } } } else { - return_error!("`{}` is not a floating-point type", in_ty); + return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty }); }; let vec_ty = bx.cx.type_vector(elem_ty, in_len); @@ -504,12 +456,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), - _ => return_error!("unrecognized intrinsic `{}`", name), + _ => return_error!(InvalidMonomorphizationUnrecognized { span, name }) }; let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx); let function: RValue<'gcc> = unsafe { std::mem::transmute(function) }; - let c = bx.call(fn_ty, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None); + let c = bx.call(fn_ty, None, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None); Ok(c) } @@ -557,10 +509,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, })* _ => {}, } - require!(false, - "unsupported operation on `{}` with element `{}`", - in_ty, - in_elem) + return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem }) })* } } @@ -579,12 +528,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)), _ => { - return_error!( - "expected element type `{}` of vector type `{}` \ - to be a signed or unsigned integer type", - arg_tys[0].simd_size_and_type(bx.tcx()).1, - arg_tys[0] - ); + return_error!(InvalidMonomorphizationExpectedSignedUnsigned { + span, + name, + elem_ty: arg_tys[0].simd_size_and_type(bx.tcx()).1, + vec_ty: arg_tys[0], + }); } }; let builtin_name = @@ -617,10 +566,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::$name { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { ty::Int(_) | ty::Uint(_) => { @@ -644,13 +590,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op)) } } - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), }; } }; @@ -676,20 +616,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::$name { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { ty::Int(_) | ty::Uint(_) | ty::Float(_) => Ok(bx.$reduction(args[0].immediate())), - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), }; } }; @@ -704,22 +635,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let input = if !$boolean { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); args[0].immediate() } else { match in_elem.kind() { ty::Int(_) | ty::Uint(_) => {} - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), } // boolean reductions operate on vectors of i1s: @@ -733,11 +655,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) } _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty + InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty } ), }; } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 223466fb9b5..b9600da5c39 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -18,6 +18,8 @@ #![recursion_limit="256"] #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] extern crate rustc_apfloat; extern crate rustc_ast; @@ -25,6 +27,7 @@ extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_hir; +extern crate rustc_macros; extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; @@ -50,6 +53,7 @@ mod context; mod coverageinfo; mod debuginfo; mod declare; +mod errors; mod int; mod intrinsic; mod mono_item; @@ -59,6 +63,7 @@ mod type_of; use std::any::Any; use std::sync::{Arc, Mutex}; +use crate::errors::LTONotSupported; use gccjit::{Context, OptimizationLevel, CType}; use rustc_ast::expand::allocator::AllocatorKind; use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; @@ -97,7 +102,7 @@ pub struct GccCodegenBackend { impl CodegenBackend for GccCodegenBackend { fn init(&self, sess: &Session) { if sess.lto() != Lto::No { - sess.warn("LTO is not supported. You may get a linker error."); + sess.emit_warning(LTONotSupported {}); } let temp_dir = TempDir::new().expect("cannot create temporary directory"); @@ -148,11 +153,11 @@ impl CodegenBackend for GccCodegenBackend { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, has_alloc_error_handler: bool) -> Self::Module { + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module { let mut mods = GccContext { context: Context::default(), }; - unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, has_alloc_error_handler); } + unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); } mods } @@ -166,15 +171,6 @@ impl ExtraBackendMethods for GccCodegenBackend { Ok(()) }) } - - fn target_cpu<'b>(&self, _sess: &'b Session) -> &'b str { - unimplemented!(); - } - - fn tune_cpu<'b>(&self, _sess: &'b Session) -> Option<&'b str> { - None - // TODO(antoyo) - } } pub struct ModuleBuffer; @@ -205,7 +201,6 @@ impl WriteBackendMethods for GccCodegenBackend { type Module = GccContext; type TargetMachine = (); type ModuleBuffer = ModuleBuffer; - type Context = (); type ThinData = (); type ThinBuffer = ThinBuffer; @@ -320,10 +315,10 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> { false } /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512gfni, - avx512ifma, avx512pf, avx512vaes, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpclmulqdq, - avx512vpopcntdq, bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, xsave, xsavec, xsaveopt, xsaves + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves */ //false }) diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index 68bdb8d4e55..89a415cdb36 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -201,6 +201,27 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn val_ty(&self, value: RValue<'gcc>) -> Type<'gcc> { value.get_type() } + + fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { + if let Some(struct_type) = ty.is_struct() { + if struct_type.get_field_count() == 0 { + // NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a + // size of usize::MAX in test_binary_search, we workaround this by setting the size to + // zero for ZSTs. + // FIXME(antoyo): fix gccjit API. + len = 0; + } + } + + // NOTE: see note above. Some other test uses usize::MAX. + if len == u64::MAX { + len = 0; + } + + let len: i32 = len.try_into().expect("array len"); + + self.context.new_array_type(None, ty, len) + } } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { @@ -227,27 +248,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.context.new_opaque_struct_type(None, name) } - pub fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { - if let Some(struct_type) = ty.is_struct() { - if struct_type.get_field_count() == 0 { - // NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a - // size of usize::MAX in test_binary_search, we workaround this by setting the size to - // zero for ZSTs. - // FIXME(antoyo): fix gccjit API. - len = 0; - } - } - - // NOTE: see note above. Some other test uses usize::MAX. - if len == u64::MAX { - len = 0; - } - - let len: i32 = len.try_into().expect("array len"); - - self.context.new_array_type(None, ty, len) - } - pub fn type_bool(&self) -> Type<'gcc> { self.context.new_type::<bool>() } @@ -277,7 +277,7 @@ pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout offset = target_offset + field.size; prev_effective_align = effective_field_align; } - if !layout.is_unsized() && field_count > 0 { + if layout.is_sized() && field_count > 0 { if offset > layout.size { bug!("layout: {:#?} stride: {:?} offset: {:?}", layout, layout.size, offset); } @@ -300,4 +300,8 @@ impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // Unsupported. self.context.new_rvalue_from_int(self.int_type, 0) } + + fn set_kcfi_type_metadata(&self, _function: RValue<'gcc>, _kcfi_typeid: u32) { + // Unsupported. + } } diff --git a/compiler/rustc_codegen_gcc/tests/run/asm.rs b/compiler/rustc_codegen_gcc/tests/run/asm.rs index 46abbb553bf..38c1eac7adf 100644 --- a/compiler/rustc_codegen_gcc/tests/run/asm.rs +++ b/compiler/rustc_codegen_gcc/tests/run/asm.rs @@ -3,11 +3,12 @@ // Run-time: // status: 0 -#![feature(asm_const, asm_sym)] +#![feature(asm_const)] use std::arch::{asm, global_asm}; -global_asm!(" +global_asm!( + " .global add_asm add_asm: mov rax, rdi @@ -132,7 +133,9 @@ fn main() { assert_eq!(x, 43); // check sym fn - extern "C" fn foo() -> u64 { 42 } + extern "C" fn foo() -> u64 { + 42 + } let x: u64; unsafe { asm!("call {}", sym foo, lateout("rax") x); diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs index 2b90e4ae8d8..75779622b54 100644 --- a/compiler/rustc_codegen_gcc/tests/run/int.rs +++ b/compiler/rustc_codegen_gcc/tests/run/int.rs @@ -3,7 +3,7 @@ // Run-time: // status: 0 -#![feature(bench_black_box, const_black_box, core_intrinsics, start)] +#![feature(const_black_box, core_intrinsics, start)] #![no_std] |
