Make translator::intrinsics accessible to trampoline.

Start filling in the code to generate trampolines. Move func_type_to_llvm and type_to_llvm from code.rs to intrinsics.rs so that trampoline code can reuse them.
This commit is contained in:
Nick Lewycky
2020-04-24 16:42:14 -07:00
parent a6bde15ce5
commit 1de21f0c33
5 changed files with 85 additions and 49 deletions

View File

@@ -91,7 +91,7 @@ impl Compiler for LLVMCompiler {
signatures
.par_iter()
.map_init(FuncTrampoline::new, |func_trampoline, sig| {
func_trampoline.trampoline(sig)
func_trampoline.trampoline(sig, self.config())
})
.collect::<Result<Vec<_>, CompileError>>()
}

View File

@@ -1,3 +1,5 @@
use crate::config::LLVMConfig;
use crate::translator::intrinsics::{func_type_to_llvm, type_to_llvm, Intrinsics};
use inkwell::{
context::Context,
module::{Linkage, Module},
@@ -19,7 +21,34 @@ impl FuncTrampoline {
}
}
pub fn trampoline(&mut self, ty: &FuncType) -> Result<CompiledFunction, CompileError> {
pub fn trampoline(
&mut self,
ty: &FuncType,
config: &LLVMConfig,
) -> Result<CompiledFunction, CompileError> {
let mut module = self.ctx.create_module("");
let target_triple = config.target_triple();
let target_machine = config.target_machine();
module.set_triple(&target_triple);
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
let intrinsics = Intrinsics::declare(&module, &self.ctx);
let callee_ty = func_type_to_llvm(&self.ctx, &intrinsics, ty);
let trampoline_ty = intrinsics.void_ty.fn_type(
&[
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
callee_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(), // func ptr
intrinsics.i64_ptr_ty.as_basic_type_enum(), // args ptr
intrinsics.i64_ptr_ty.as_basic_type_enum(), // returns ptr
],
false,
);
let trampoline_func = module.add_function("", trampoline_ty, Some(Linkage::External));
//generate_trampoline(trampoline_func, ty, self.ctx, intrinsics)?;
// TODO: implement this
Err(CompileError::Codegen(
"Trampoline compilation not yet implemented.".to_string(),
@@ -60,7 +89,8 @@ pub fn generate_trampolines<'ctx>(
}
Ok(())
}
*/
/*
fn generate_trampoline<'ctx>(
trampoline_func: FunctionValue,
func_sig: &FuncSig,
@@ -133,4 +163,4 @@ fn generate_trampoline<'ctx>(
builder.build_return(None);
Ok(())
}
*/
*/

View File

@@ -1,5 +1,7 @@
use super::{
intrinsics::{tbaa_label, CtxType, GlobalCache, Intrinsics, MemoryCache},
intrinsics::{
func_type_to_llvm, tbaa_label, type_to_llvm, CtxType, GlobalCache, Intrinsics, MemoryCache,
},
read_info::blocktype_to_type,
// stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic},
state::{ControlFrame, ExtraInfo, IfElseState, State},
@@ -313,47 +315,6 @@ impl FuncTranslator {
}
}
fn func_type_to_llvm<'ctx>(
context: &'ctx Context,
intrinsics: &Intrinsics<'ctx>,
fntype: &FuncType,
) -> FunctionType<'ctx> {
let user_param_types = fntype
.params()
.iter()
.map(|&ty| type_to_llvm(intrinsics, ty));
let param_types: Vec<_> = std::iter::once(intrinsics.ctx_ptr_ty.as_basic_type_enum())
.chain(user_param_types)
.collect();
match fntype.results() {
&[] => intrinsics.void_ty.fn_type(&param_types, false),
&[single_value] => type_to_llvm(intrinsics, single_value).fn_type(&param_types, false),
returns @ _ => {
let basic_types: Vec<_> = returns
.iter()
.map(|&ty| type_to_llvm(intrinsics, ty))
.collect();
context
.struct_type(&basic_types, false)
.fn_type(&param_types, false)
}
}
}
fn type_to_llvm<'ctx>(intrinsics: &Intrinsics<'ctx>, ty: Type) -> BasicTypeEnum<'ctx> {
match ty {
Type::I32 => intrinsics.i32_ty.as_basic_type_enum(),
Type::I64 => intrinsics.i64_ty.as_basic_type_enum(),
Type::F32 => intrinsics.f32_ty.as_basic_type_enum(),
Type::F64 => intrinsics.f64_ty.as_basic_type_enum(),
Type::V128 => intrinsics.i128_ty.as_basic_type_enum(),
Type::AnyRef => unimplemented!("anyref in the llvm backend"),
Type::FuncRef => unimplemented!("funcref in the llvm backend"),
}
}
// Create a vector where each lane contains the same value.
fn splat_vector<'ctx>(
builder: &Builder<'ctx>,

View File

@@ -9,7 +9,10 @@ use inkwell::{
builder::Builder,
context::Context,
module::{Linkage, Module},
types::{BasicType, FloatType, IntType, PointerType, StructType, VectorType, VoidType},
types::{
BasicType, BasicTypeEnum, FloatType, FunctionType, IntType, PointerType, StructType,
VectorType, VoidType,
},
values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue,
PointerValue, VectorValue,
@@ -31,7 +34,8 @@ use wasmer_runtime_core::{
*/
use wasm_common::entity::{EntityRef, PrimaryMap};
use wasm_common::{
FuncIndex, GlobalIndex, MemoryIndex, Mutability, Pages, SignatureIndex, TableIndex, Type,
FuncIndex, FuncType, GlobalIndex, MemoryIndex, Mutability, Pages, SignatureIndex, TableIndex,
Type,
};
use wasmer_runtime::Module as WasmerCompilerModule;
use wasmer_runtime::{MemoryPlan, MemoryStyle, VMOffsets};
@@ -1250,3 +1254,44 @@ pub fn tbaa_label<'ctx>(
let tbaa_kind = context.get_kind_id("tbaa");
instruction.set_metadata(type_tbaa, tbaa_kind);
}
pub fn func_type_to_llvm<'ctx>(
context: &'ctx Context,
intrinsics: &Intrinsics<'ctx>,
fntype: &FuncType,
) -> FunctionType<'ctx> {
let user_param_types = fntype
.params()
.iter()
.map(|&ty| type_to_llvm(intrinsics, ty));
let param_types: Vec<_> = std::iter::once(intrinsics.ctx_ptr_ty.as_basic_type_enum())
.chain(user_param_types)
.collect();
match fntype.results() {
&[] => intrinsics.void_ty.fn_type(&param_types, false),
&[single_value] => type_to_llvm(intrinsics, single_value).fn_type(&param_types, false),
returns @ _ => {
let basic_types: Vec<_> = returns
.iter()
.map(|&ty| type_to_llvm(intrinsics, ty))
.collect();
context
.struct_type(&basic_types, false)
.fn_type(&param_types, false)
}
}
}
pub fn type_to_llvm<'ctx>(intrinsics: &Intrinsics<'ctx>, ty: Type) -> BasicTypeEnum<'ctx> {
match ty {
Type::I32 => intrinsics.i32_ty.as_basic_type_enum(),
Type::I64 => intrinsics.i64_ty.as_basic_type_enum(),
Type::F32 => intrinsics.f32_ty.as_basic_type_enum(),
Type::F64 => intrinsics.f64_ty.as_basic_type_enum(),
Type::V128 => intrinsics.i128_ty.as_basic_type_enum(),
Type::AnyRef => unimplemented!("anyref in the llvm backend"),
Type::FuncRef => unimplemented!("funcref in the llvm backend"),
}
}

View File

@@ -1,5 +1,5 @@
mod code;
mod intrinsics;
pub mod intrinsics;
mod read_info;
//mod stackmap;
mod state;