Add the ability to pass backend specific options through CompilerConfig.

Use this to replace wasmer_llvm_backend::GLOBAL_OPTIONS.
This commit is contained in:
Nick Lewycky
2019-12-04 10:38:28 -08:00
parent af7a368320
commit 8d3cf874cd
5 changed files with 95 additions and 46 deletions

View File

@ -2,6 +2,7 @@ use super::stackmap::StackmapRegistry;
use crate::{
intrinsics::Intrinsics,
structs::{Callbacks, LLVMModule, LLVMResult, MemProtect},
LLVMCallbacks,
};
use inkwell::{
memory_buffer::MemoryBuffer,
@ -13,8 +14,6 @@ use std::{
any::Any,
cell::RefCell,
ffi::{c_void, CString},
fs::File,
io::Write,
mem,
ops::Deref,
ptr::{self, NonNull},
@ -176,23 +175,22 @@ impl LLVMBackend {
_stackmaps: &StackmapRegistry,
_module_info: &ModuleInfo,
target_machine: &TargetMachine,
llvm_callbacks: &Option<Rc<RefCell<dyn LLVMCallbacks>>>,
) -> (Self, LLVMCache) {
let memory_buffer = target_machine
.write_to_memory_buffer(&module.borrow_mut(), FileType::Object)
.unwrap();
let mem_buf_slice = memory_buffer.as_slice();
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.obj_file } {
let mut file = File::create(path).unwrap();
let mut pos = 0;
while pos < mem_buf_slice.len() {
pos += file.write(&mem_buf_slice[pos..]).unwrap();
}
if let Some(callbacks) = llvm_callbacks {
callbacks
.borrow_mut()
.obj_memory_buffer_callback(&memory_buffer);
}
let callbacks = get_callbacks();
let mut module: *mut LLVMModule = ptr::null_mut();
let mem_buf_slice = memory_buffer.as_slice();
let res = unsafe {
module_load(
mem_buf_slice.as_ptr(),

View File

@ -5,6 +5,7 @@ use crate::{
stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic},
state::{ControlFrame, ExtraInfo, IfElseState, State},
trampolines::generate_trampolines,
LLVMBackendConfig, LLVMCallbacks,
};
use inkwell::{
builder::Builder,
@ -877,6 +878,7 @@ pub struct LLVMModuleCodeGenerator<'ctx> {
stackmaps: Rc<RefCell<StackmapRegistry>>,
track_state: bool,
target_machine: TargetMachine,
llvm_callbacks: Option<Rc<RefCell<dyn LLVMCallbacks>>>,
}
pub struct LLVMFunctionCodeGenerator<'ctx> {
@ -8513,6 +8515,7 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
stackmaps: Rc::new(RefCell::new(StackmapRegistry::default())),
track_state: false,
target_machine,
llvm_callbacks: None,
}
}
@ -8654,8 +8657,10 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
message: format!("trampolines generation error: {:?}", e),
})?;
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } {
self.module.borrow_mut().print_to_file(path).unwrap();
if let Some(ref mut callbacks) = self.llvm_callbacks {
callbacks
.borrow_mut()
.preopt_ir_callback(&*self.module.borrow_mut());
}
let pass_manager = PassManager::create(());
@ -8695,8 +8700,10 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
pass_manager.add_early_cse_pass();
pass_manager.run_on(&*self.module.borrow_mut());
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.post_opt_ir } {
self.module.borrow_mut().print_to_file(path).unwrap();
if let Some(ref mut callbacks) = self.llvm_callbacks {
callbacks
.borrow_mut()
.postopt_ir_callback(&*self.module.borrow_mut());
}
let stackmaps = self.stackmaps.borrow();
@ -8707,12 +8714,18 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
&*stackmaps,
module_info,
&self.target_machine,
&mut self.llvm_callbacks,
);
Ok((backend, Box::new(cache_gen)))
}
fn feed_compiler_config(&mut self, config: &CompilerConfig) -> Result<(), CodegenError> {
self.track_state = config.track_state;
if let Some(backend_compiler_config) = &config.backend_specific_config {
if let Some(llvm_config) = backend_compiler_config.get_specific::<LLVMBackendConfig>() {
self.llvm_callbacks = llvm_config.callbacks.clone();
}
}
Ok(())
}

View File

@ -21,8 +21,6 @@ mod state;
mod structs;
mod trampolines;
use std::path::PathBuf;
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
pub use code::LLVMModuleCodeGenerator as ModuleCodeGenerator;
@ -35,21 +33,15 @@ pub type LLVMCompiler = SimpleStreamingCompilerGen<
code::CodegenError,
>;
#[derive(Debug, Clone)]
/// LLVM backend flags.
pub struct LLVMOptions {
/// Emit LLVM IR before optimization pipeline.
pub pre_opt_ir: Option<PathBuf>,
pub type InkwellModule<'ctx> = inkwell::module::Module<'ctx>;
pub type InkwellMemoryBuffer = inkwell::memory_buffer::MemoryBuffer;
/// Emit LLVM IR after optimization pipeline.
pub post_opt_ir: Option<PathBuf>,
/// Emit LLVM generated native code object file.
pub obj_file: Option<PathBuf>,
pub trait LLVMCallbacks: std::any::Any + 'static {
fn preopt_ir_callback(&mut self, module: &InkwellModule);
fn postopt_ir_callback(&mut self, module: &InkwellModule);
fn obj_memory_buffer_callback(&mut self, memory_buffer: &InkwellMemoryBuffer);
}
pub static mut GLOBAL_OPTIONS: LLVMOptions = LLVMOptions {
pre_opt_ir: None,
post_opt_ir: None,
obj_file: None,
};
pub struct LLVMBackendConfig {
pub callbacks: Option<std::rc::Rc<std::cell::RefCell<dyn LLVMCallbacks>>>,
}