Emit direct calls for local functions, but not for imports.

This commit is contained in:
Nick Lewycky
2019-11-08 13:38:23 -08:00
parent 674a70fa05
commit 2957b6abd8
2 changed files with 11 additions and 68 deletions

View File

@ -852,7 +852,7 @@ pub struct LLVMModuleCodeGenerator {
signatures: Map<SigIndex, FunctionType>, signatures: Map<SigIndex, FunctionType>,
signatures_raw: Map<SigIndex, FuncSig>, signatures_raw: Map<SigIndex, FuncSig>,
function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>, function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>,
llvm_functions: HashMap<FuncIndex, FunctionValue>, llvm_functions: Rc<RefCell<HashMap<FuncIndex, FunctionValue>>>,
func_import_count: usize, func_import_count: usize,
personality_func: FunctionValue, personality_func: FunctionValue,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module>>,
@ -867,6 +867,7 @@ pub struct LLVMFunctionCodeGenerator {
alloca_builder: Option<Builder>, alloca_builder: Option<Builder>,
intrinsics: Option<Intrinsics>, intrinsics: Option<Intrinsics>,
state: State, state: State,
llvm_functions: Rc<RefCell<HashMap<FuncIndex, FunctionValue>>>,
function: FunctionValue, function: FunctionValue,
func_sig: FuncSig, func_sig: FuncSig,
signatures: Map<SigIndex, FunctionType>, signatures: Map<SigIndex, FunctionType>,
@ -1694,7 +1695,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let func_sig = &info.signatures[sigindex]; let func_sig = &info.signatures[sigindex];
let (params, func_ptr) = match func_index.local_or_import(info) { let (params, func_ptr) = match func_index.local_or_import(info) {
LocalOrImport::Local(local_func_index) => { LocalOrImport::Local(_) => {
let params: Vec<_> = std::iter::once(ctx.basic()) let params: Vec<_> = std::iter::once(ctx.basic())
.chain( .chain(
state state
@ -1724,15 +1725,9 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
) )
.collect(); .collect();
let func_ptr = ctx.local_func( let func_ptr = self.llvm_functions.borrow_mut()[&func_index];
local_func_index,
llvm_sig,
intrinsics,
self.module.clone(),
builder,
);
(params, func_ptr) (params, func_ptr.as_global_value().as_pointer_value())
} }
LocalOrImport::Import(import_func_index) => { LocalOrImport::Import(import_func_index) => {
let (func_ptr_untyped, ctx_ptr) = let (func_ptr_untyped, ctx_ptr) =
@ -1768,7 +1763,6 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
.collect(); .collect();
let func_ptr_ty = llvm_sig.ptr_type(AddressSpace::Generic); let func_ptr_ty = llvm_sig.ptr_type(AddressSpace::Generic);
let func_ptr = builder.build_pointer_cast( let func_ptr = builder.build_pointer_cast(
func_ptr_untyped, func_ptr_untyped,
func_ptr_ty, func_ptr_ty,
@ -8021,7 +8015,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
signatures: Map::new(), signatures: Map::new(),
signatures_raw: Map::new(), signatures_raw: Map::new(),
function_signatures: None, function_signatures: None,
llvm_functions: HashMap::new(), llvm_functions: Rc::new(RefCell::new(HashMap::new())),
func_import_count: 0, func_import_count: 0,
personality_func, personality_func,
stackmaps: Rc::new(RefCell::new(StackmapRegistry::default())), stackmaps: Rc::new(RefCell::new(StackmapRegistry::default())),
@ -8060,7 +8054,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
let sig_id = self.function_signatures.as_ref().unwrap()[func_index]; let sig_id = self.function_signatures.as_ref().unwrap()[func_index];
let func_sig = self.signatures_raw[sig_id].clone(); let func_sig = self.signatures_raw[sig_id].clone();
let function = &self.llvm_functions[&func_index]; let function = &self.llvm_functions.borrow_mut()[&func_index];
function.set_personality_function(self.personality_func); function.set_personality_function(self.personality_func);
let mut state = State::new(); let mut state = State::new();
@ -8118,6 +8112,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
builder: Some(builder), builder: Some(builder),
alloca_builder: Some(alloca_builder), alloca_builder: Some(alloca_builder),
intrinsics: Some(intrinsics), intrinsics: Some(intrinsics),
llvm_functions: self.llvm_functions.clone(),
function: *function, function: *function,
func_sig: func_sig, func_sig: func_sig,
locals, locals,
@ -8238,7 +8233,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
self.signatures[*sig_id], self.signatures[*sig_id],
Some(Linkage::External), Some(Linkage::External),
); );
self.llvm_functions.insert(index, function); self.llvm_functions.borrow_mut().insert(index, function);
} }
self.function_signatures = Some(Arc::new(assoc)); self.function_signatures = Some(Arc::new(assoc));
Ok(()) Ok(())

View File

@ -3,9 +3,7 @@ use inkwell::{
builder::Builder, builder::Builder,
context::Context, context::Context,
module::Module, module::Module,
types::{ types::{BasicType, FloatType, IntType, PointerType, StructType, VectorType, VoidType},
BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType,
},
values::{ values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue, BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue,
PointerValue, VectorValue, PointerValue, VectorValue,
@ -21,8 +19,7 @@ use wasmer_runtime_core::{
module::ModuleInfo, module::ModuleInfo,
structures::TypedIndex, structures::TypedIndex,
types::{ types::{
GlobalIndex, ImportedFuncIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex, GlobalIndex, ImportedFuncIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type,
TableIndex, Type,
}, },
units::Pages, units::Pages,
vm::{Ctx, INTERNALS_SIZE}, vm::{Ctx, INTERNALS_SIZE},
@ -895,55 +892,6 @@ impl<'a> CtxType<'a> {
(base_ptr, bounds) (base_ptr, bounds)
} }
pub fn local_func(
&mut self,
index: LocalFuncIndex,
fn_ty: FunctionType,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
builder: &Builder,
) -> PointerValue {
let local_func_array_ptr_ptr = unsafe {
builder.build_struct_gep(
self.ctx_ptr_value,
offset_to_index(Ctx::offset_local_functions()),
"local_func_array_ptr_ptr",
)
};
let local_func_array_ptr = builder
.build_load(local_func_array_ptr_ptr, "local_func_array_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
intrinsics,
"context_field_ptr_to_local_funcs",
local_func_array_ptr.as_instruction_value().unwrap(),
None,
);
let local_func_ptr_ptr = unsafe {
builder.build_in_bounds_gep(
local_func_array_ptr,
&[intrinsics.i32_ty.const_int(index.index() as u64, false)],
"local_func_ptr_ptr",
)
};
let local_func_ptr = builder
.build_load(local_func_ptr_ptr, "local_func_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
intrinsics,
"local_func_ptr",
local_func_ptr.as_instruction_value().unwrap(),
Some(index.index() as u32),
);
builder.build_pointer_cast(
local_func_ptr,
fn_ty.ptr_type(AddressSpace::Generic),
"local_func_ptr",
)
}
pub fn dynamic_sigindex(&mut self, index: SigIndex, intrinsics: &Intrinsics) -> IntValue { pub fn dynamic_sigindex(&mut self, index: SigIndex, intrinsics: &Intrinsics) -> IntValue {
let (cached_sigindices, ctx_ptr_value, cache_builder) = ( let (cached_sigindices, ctx_ptr_value, cache_builder) = (
&mut self.cached_sigindices, &mut self.cached_sigindices,