Include trampolines in the generated object file.

This commit is contained in:
Nick Lewycky
2020-08-05 14:20:47 -07:00
parent 0b62c775de
commit 9ca46f4f2d
2 changed files with 81 additions and 7 deletions

View File

@@ -163,6 +163,10 @@ impl LLVMCompiler {
let target_machine = self.config().target_machine(target);
let ctx = Context::create();
let merged_module = ctx.create_module("");
// TODO: make these steps run in parallel instead of in three phases
// with a serial step in between them.
function_body_inputs
.into_iter()
.collect::<Vec<_>>()
@@ -198,6 +202,52 @@ impl LLVMCompiler {
merged_module.link_in_module(m).unwrap();
});
compile_info.module
.signatures
.values()
.collect::<Vec<_>>()
.par_iter()
.map_init(
|| {
let target_machine = self.config().target_machine(target);
FuncTrampoline::new(target_machine)
},
|func_trampoline, sig| {
let module = func_trampoline.trampoline_to_module(sig, self.config())?;
Ok(module.write_bitcode_to_memory().as_slice().to_vec())
}
)
.collect::<Result<Vec<_>, CompileError>>()?
.into_iter()
.for_each(|bc| {
let membuf = MemoryBuffer::create_from_memory_range(&bc, "");
let m = Module::parse_bitcode_from_buffer(&membuf, &ctx).unwrap();
merged_module.link_in_module(m).unwrap();
});
compile_info.module
.signatures
.values()
.collect::<Vec<_>>()
.par_iter()
.map_init(
|| {
let target_machine = self.config().target_machine(target);
FuncTrampoline::new(target_machine)
},
|func_trampoline, sig| {
let module = func_trampoline.dynamic_trampoline_to_module(sig, self.config())?;
Ok(module.write_bitcode_to_memory().as_slice().to_vec())
}
)
.collect::<Result<Vec<_>, CompileError>>()?
.into_iter()
.for_each(|bc| {
let membuf = MemoryBuffer::create_from_memory_range(&bc, "");
let m = Module::parse_bitcode_from_buffer(&membuf, &ctx).unwrap();
merged_module.link_in_module(m).unwrap();
});
if self.config().enable_verifier {
merged_module.verify().unwrap();
}

View File

@@ -8,7 +8,7 @@ use crate::translator::intrinsics::{type_to_llvm, type_to_llvm_ptr, Intrinsics};
use inkwell::{
attributes::{Attribute, AttributeLoc},
context::Context,
module::Linkage,
module::{Linkage, Module},
passes::PassManager,
targets::{FileType, TargetMachine},
types::BasicType,
@@ -35,11 +35,11 @@ impl FuncTrampoline {
}
}
pub fn trampoline(
&mut self,
pub fn trampoline_to_module(
&self,
ty: &FunctionType,
config: &LLVM,
) -> Result<FunctionBody, CompileError> {
) -> Result<Module, CompileError> {
// The function type, used for the callbacks.
let function = CompiledFunctionKind::FunctionCallTrampoline(ty.clone());
let module = self.ctx.create_module("");
@@ -85,6 +85,18 @@ impl FuncTrampoline {
callbacks.postopt_ir(&function, &module);
}
Ok(module)
}
pub fn trampoline(
&self,
ty: &FunctionType,
config: &LLVM,
) -> Result<FunctionBody, CompileError> {
let module = self.trampoline_to_module(ty, config)?;
let function = CompiledFunctionKind::FunctionCallTrampoline(ty.clone());
let target_machine = &self.target_machine;
let memory_buffer = target_machine
.write_to_memory_buffer(&module, FileType::Object)
.unwrap();
@@ -145,11 +157,11 @@ impl FuncTrampoline {
})
}
pub fn dynamic_trampoline(
&mut self,
pub fn dynamic_trampoline_to_module(
&self,
ty: &FunctionType,
config: &LLVM,
) -> Result<FunctionBody, CompileError> {
) -> Result<Module, CompileError> {
// The function type, used for the callbacks
let function = CompiledFunctionKind::DynamicFunctionTrampoline(ty.clone());
let module = self.ctx.create_module("");
@@ -187,6 +199,18 @@ impl FuncTrampoline {
callbacks.postopt_ir(&function, &module);
}
Ok(module)
}
pub fn dynamic_trampoline(
&self,
ty: &FunctionType,
config: &LLVM,
) -> Result<FunctionBody, CompileError> {
let function = CompiledFunctionKind::DynamicFunctionTrampoline(ty.clone());
let target_machine = &self.target_machine;
let module = self.dynamic_trampoline_to_module(ty, config)?;
let memory_buffer = target_machine
.write_to_memory_buffer(&module, FileType::Object)
.unwrap();