Skip to content

Commit

Permalink
Extract a create_wrapper_function for use in allocator shim writing
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bjorn3 committed Jul 15, 2023
1 parent 3a74f93 commit 7ba60ec
Showing 1 changed file with 50 additions and 59 deletions.
109 changes: 50 additions & 59 deletions src/allocator.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -22,7 +22,6 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
};
let i8 = context.new_type::<i8>();
let i8p = i8.make_pointer();
let void = context.new_type::<()>();

if kind == AllocatorKind::Default {
for method in ALLOCATOR_METHODS {
Expand All @@ -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::<Vec<_>>();
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<Type<'_>>,
) {
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));

Expand All @@ -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::<Vec<_>>();
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
}

0 comments on commit 7ba60ec

Please sign in to comment.