diff --git a/example/mini_core.rs b/example/mini_core.rs index 5afedf9d401..64a5b431bd0 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -603,7 +603,7 @@ impl, U: ?Sized, A: Allocator> CoerceUnsized> fo impl Box { pub fn new(val: T) -> Box { unsafe { - let size = intrinsics::size_of::(); + let size = size_of::(); let ptr = libc::malloc(size); intrinsics::copy(&val as *const T as *const u8, ptr, size); Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global) @@ -657,11 +657,11 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn abort() -> !; #[rustc_intrinsic] - pub fn size_of() -> usize; + pub const fn size_of() -> usize; #[rustc_intrinsic] pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub fn align_of() -> usize; + pub const fn align_of() -> usize; #[rustc_intrinsic] pub unsafe fn align_of_val(val: *const T) -> usize; #[rustc_intrinsic] @@ -699,6 +699,24 @@ pub mod libc { } } +pub const fn size_of() -> usize { + ::SIZE +} + +pub const fn align_of() -> usize { + ::ALIGN +} + +trait SizedTypeProperties: Sized { + #[lang = "mem_size_const"] + const SIZE: usize = intrinsics::size_of::(); + + #[lang = "mem_align_const"] + const ALIGN: usize = intrinsics::align_of::(); +} + +impl SizedTypeProperties for T {} + #[lang = "index"] pub trait Index { type Output: ?Sized; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 1e601d42413..45154ff072f 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -90,8 +90,8 @@ fn start( ) -> isize { if argc == 3 { unsafe { puts(*argv); } - unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const u8)); } - unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const u8)); } + unsafe { puts(*((argv as usize + size_of::<*const u8>()) as *const *const u8)); } + unsafe { puts(*((argv as usize + 2 * size_of::<*const u8>()) as *const *const u8)); } } main().report(); @@ -154,7 +154,7 @@ fn main() { let slice = &[0, 1] as &[i32]; let slice_ptr = slice as *const [i32] as *const i32; - let align = intrinsics::align_of::<*const i32>(); + let align = align_of::<*const i32>(); assert_eq!(slice_ptr as usize % align, 0); //return; @@ -195,8 +195,8 @@ fn main() { assert_eq!(intrinsics::size_of_val(a) as u8, 8); assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); - assert_eq!(intrinsics::align_of::() as u8, 2); - assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8); + assert_eq!(align_of::() as u8, 2); + assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8); let u8_needs_drop = const { intrinsics::needs_drop::() }; assert!(!u8_needs_drop); diff --git a/rust-toolchain b/rust-toolchain index ec625481add..9813bbea00c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-09-30" +channel = "nightly-2025-11-04" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/allocator.rs b/src/allocator.rs index 2a95a7368aa..647569694b0 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -2,8 +2,7 @@ use gccjit::FnAttribute; use gccjit::{Context, FunctionType, RValue, ToRValue, Type}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; @@ -18,8 +17,7 @@ pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) { let context = &mods.context; let usize = match tcx.sess.target.pointer_width { @@ -31,45 +29,35 @@ pub(crate) unsafe fn codegen( let i8 = context.new_type::(); let i8p = i8.make_pointer(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut types = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - types.push(usize); - types.push(usize); - } - AllocatorTy::Ptr => types.push(i8p), - AllocatorTy::Usize => types.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), + for method in methods { + let mut types = Vec::with_capacity(method.inputs.len()); + for input in method.inputs.iter() { + match input.ty { + AllocatorTy::Layout => { + types.push(usize); + types.push(usize); } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, + AllocatorTy::Ptr => types.push(i8p), + AllocatorTy::Usize => types.push(usize), - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") + AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { + panic!("invalid allocator arg") } - }; - let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); - let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - - create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); + } } - } + let output = match method.output { + AllocatorTy::ResultPtr => Some(i8p), + AllocatorTy::Never | AllocatorTy::Unit => None, - // FIXME(bjorn3): Add noreturn attribute - create_wrapper_function( - tcx, - context, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), - &[usize, usize], - None, - ); + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } + }; + let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); + let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); + + create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); + } create_const_value_function( tcx, diff --git a/src/asm.rs b/src/asm.rs index a14881c502c..f237861b159 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -546,9 +546,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) { - // TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient - // on all architectures. For instance, what about FP stack? - extended_asm.add_clobber("cc"); + match asm_arch { + InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => { + // "cc" is cr0 on powerpc. + } + // TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient + // on all architectures. For instance, what about FP stack? + _ => { + extended_asm.add_clobber("cc"); + } + } } if !options.contains(InlineAsmOptions::NOMEM) { extended_asm.add_clobber("memory"); @@ -698,6 +705,7 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => "wa", InlineAsmRegClass::PowerPC( PowerPCInlineAsmRegClass::cr | PowerPCInlineAsmRegClass::ctr @@ -778,9 +786,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(), InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(), - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => { - cx.type_vector(cx.type_i32(), 4) - } + InlineAsmRegClass::PowerPC( + PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg, + ) => cx.type_vector(cx.type_i32(), 4), InlineAsmRegClass::PowerPC( PowerPCInlineAsmRegClass::cr | PowerPCInlineAsmRegClass::ctr @@ -957,6 +965,13 @@ fn modifier_to_gcc( InlineAsmRegClass::LoongArch(_) => None, InlineAsmRegClass::Mips(_) => None, InlineAsmRegClass::Nvptx(_) => None, + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => { + if modifier.is_none() { + Some('x') + } else { + modifier + } + } InlineAsmRegClass::PowerPC(_) => None, InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) | InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None, diff --git a/src/back/lto.rs b/src/back/lto.rs index 9071c490013..404064fb7a0 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -31,6 +31,7 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::memmap::Mmap; use rustc_errors::DiagCtxtHandle; +use rustc_log::tracing::info; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; use rustc_session::config::Lto; diff --git a/src/back/write.rs b/src/back/write.rs index b654b34992c..eae0f2aa00f 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -5,6 +5,7 @@ use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; use rustc_fs_util::link_or_copy; +use rustc_log::tracing::debug; use rustc_session::config::OutputType; use rustc_target::spec::SplitDebuginfo; diff --git a/src/common.rs b/src/common.rs index 28848ca6184..7c2969e5871 100644 --- a/src/common.rs +++ b/src/common.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods, }; use rustc_middle::mir::Mutability; -use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; +use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar}; use rustc_middle::ty::layout::LayoutOf; use crate::context::CodegenCx; @@ -247,8 +247,8 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { // This avoids generating a zero-sized constant value and actually needing a // real address at runtime. if alloc.inner().len() == 0 { - assert_eq!(offset.bytes(), 0); - let val = self.const_usize(alloc.inner().align.bytes()); + let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); + let val = self.const_usize(self.tcx.truncate_to_target_usize(val)); return if matches!(layout.primitive(), Pointer(_)) { self.context.new_cast(None, val, ty) } else { diff --git a/src/consts.rs b/src/consts.rs index 7fe8fc122b3..ec7d4b285a3 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -8,6 +8,7 @@ use rustc_codegen_ssa::traits::{ use rustc_hir::attrs::Linkage; use rustc_hir::def::DefKind; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_log::tracing::trace; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint, diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 4c8585192a1..0f015cc23f5 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -29,13 +29,24 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { _variable_alloca: Self::Value, _direct_offset: Size, _indirect_offsets: &[Size], - _fragment: Option>, + _fragment: &Option>, ) { // FIXME(tempdragon): Not sure if this is correct, probably wrong but still keep it here. #[cfg(feature = "master")] _variable_alloca.set_location(_dbg_loc); } + fn dbg_var_value( + &mut self, + _dbg_var: Self::DIVariable, + _dbg_loc: Self::DILocation, + _value: Self::Value, + _direct_offset: Size, + _indirect_offsets: &[Size], + _fragment: &Option>, + ) { + } + fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { // TODO(antoyo): insert reference to gdb debug scripts section global. } diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 42ba40692b7..702704ddf13 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -1,8 +1,8 @@ #[cfg(feature = "master")] use gccjit::Context; use rustc_codegen_ssa::target_features; +use rustc_data_structures::smallvec::{SmallVec, smallvec}; use rustc_session::Session; -use smallvec::{SmallVec, smallvec}; fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { target_features::retpoline_features_by_flags(sess, features); diff --git a/src/lib.rs b/src/lib.rs index 9854f3843c4..5d84ba854bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,5 @@ /* * TODO(antoyo): implement equality in libgccjit based on https://zpz.github.io/blog/overloading-equality-operator-in-cpp-class-hierarchy/ (for type equality?) - * TODO(antoyo): support #[inline] attributes. - * TODO(antoyo): support LTO (gcc's equivalent to Full LTO is -flto -flto-partition=one — https://documentation.suse.com/sbp/all/html/SBP-GCC-10/index.html). * For Thin LTO, this might be helpful: // cspell:disable-next-line * In gcc 4.6 -fwhopr was removed and became default with -flto. The non-whopr path can still be executed via -flto-partition=none. @@ -25,12 +23,6 @@ #![deny(clippy::pattern_type_mismatch)] #![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)] -// These crates are pulled from the sysroot because they are part of -// rustc's public API, so we need to ensure version compatibility. -extern crate smallvec; -#[macro_use] -extern crate tracing; - // The rustc crates we need extern crate rustc_abi; extern crate rustc_apfloat; @@ -44,6 +36,7 @@ extern crate rustc_hir; extern crate rustc_index; #[cfg(feature = "master")] extern crate rustc_interface; +extern crate rustc_log; extern crate rustc_macros; extern crate rustc_middle; extern crate rustc_session; @@ -89,7 +82,7 @@ use back::lto::{ThinBuffer, ThinData}; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; -use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, @@ -290,8 +283,7 @@ impl ExtraBackendMethods for GccCodegenBackend { &self, tcx: TyCtxt<'_>, module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) -> Self::Module { let lto_supported = self.lto_supported.load(Ordering::SeqCst); let mut mods = GccContext { @@ -303,7 +295,7 @@ impl ExtraBackendMethods for GccCodegenBackend { }; unsafe { - allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut mods, module_name, methods); } mods }