From 7ba60ecb538249a7ba23d3a4bcc96e468de03a50 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 15 Jul 2023 12:37:47 +0000 Subject: [PATCH] Extract a create_wrapper_function for use in allocator shim writing This deduplicates some logic and makes it easier to follow what wrappers are produced. In the future it may allow moving the code to determine which wrappers to create to cg_ssa. --- src/allocator.rs | 109 ++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 59 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 13f88192bbc..38309fa0153 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,6 +1,6 @@ #[cfg(feature="master")] use gccjit::FnAttribute; -use gccjit::{FunctionType, GlobalKind, ToRValue}; +use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; use rustc_ast::expand::allocator::{ alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, @@ -22,7 +22,6 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam }; let i8 = context.new_type::(); let i8p = i8.make_pointer(); - let void = context.new_type::<()>(); if kind == AllocatorKind::Default { for method in ALLOCATOR_METHODS { @@ -47,67 +46,62 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam panic!("invalid allocator output") } }; - let name = global_fn_name(method.name); + let from_name = global_fn_name(method.name); + let to_name = default_fn_name(method.name); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) - .collect(); - let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, name, false); + create_wrapper_function(tcx, context, &from_name, &to_name, &types, output); + } + } - if tcx.sess.target.options.default_hidden_visibility { - #[cfg(feature="master")] - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - } - if tcx.sess.must_emit_unwind_tables() { - // TODO(antoyo): emit unwind tables. - } + // FIXME(bjorn3): Add noreturn attribute + create_wrapper_function( + tcx, + context, + "__rust_alloc_error_handler", + &alloc_error_handler_name(alloc_error_handler_kind), + &[usize, usize], + None, + ); - let callee = default_fn_name(method.name); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) - .collect(); - let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, callee, false); - #[cfg(feature="master")] - callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - - let block = func.new_block("entry"); - - let args = args - .iter() - .enumerate() - .map(|(i, _)| func.get_param(i as i32).to_rvalue()) - .collect::>(); - let ret = context.new_call(None, callee, &args); - //llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - block.end_with_return(None, ret); - } - else { - block.end_with_void_return(None); - } + let name = OomStrategy::SYMBOL.to_string(); + let global = context.new_global(None, GlobalKind::Exported, i8, name); + let value = tcx.sess.opts.unstable_opts.oom.should_panic(); + let value = context.new_rvalue_from_int(i8, value as i32); + global.global_set_initializer_rvalue(value); - // TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances - // as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643 - } - } + let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string(); + let global = context.new_global(None, GlobalKind::Exported, i8, name); + let value = context.new_rvalue_from_int(i8, 0); + global.global_set_initializer_rvalue(value); +} + +fn create_wrapper_function( + tcx: TyCtxt<'_>, + context: &Context<'_>, + from_name: &str, + to_name: &str, + types: &[Type<'_>], + output: Option>, +) { + let void = context.new_type::<()>(); - let types = [usize, usize]; - let name = "__rust_alloc_error_handler".to_string(); let args: Vec<_> = types.iter().enumerate() .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) .collect(); - let func = context.new_function(None, FunctionType::Exported, void, &args, name, false); + let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, from_name, false); - if tcx.sess.target.default_hidden_visibility { + if tcx.sess.target.options.default_hidden_visibility { #[cfg(feature="master")] func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); } + if tcx.sess.must_emit_unwind_tables() { + // TODO(antoyo): emit unwind tables. + } - let callee = alloc_error_handler_name(alloc_error_handler_kind); let args: Vec<_> = types.iter().enumerate() .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) .collect(); - let callee = context.new_function(None, FunctionType::Extern, void, &args, callee, false); + let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, to_name, false); #[cfg(feature="master")] callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); @@ -118,18 +112,15 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam .enumerate() .map(|(i, _)| func.get_param(i as i32).to_rvalue()) .collect::>(); - let _ret = context.new_call(None, callee, &args); + let ret = context.new_call(None, callee, &args); //llvm::LLVMSetTailCall(ret, True); - block.end_with_void_return(None); - - let name = OomStrategy::SYMBOL.to_string(); - let global = context.new_global(None, GlobalKind::Exported, i8, name); - let value = tcx.sess.opts.unstable_opts.oom.should_panic(); - let value = context.new_rvalue_from_int(i8, value as i32); - global.global_set_initializer_rvalue(value); + if output.is_some() { + block.end_with_return(None, ret); + } + else { + block.end_with_void_return(None); + } - let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string(); - let global = context.new_global(None, GlobalKind::Exported, i8, name); - let value = context.new_rvalue_from_int(i8, 0); - global.global_set_initializer_rvalue(value); + // TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances + // as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643 }