mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-13 00:51:20 +00:00
Add the ability to pass backend specific options through CompilerConfig.
Use this to replace wasmer_llvm_backend::GLOBAL_OPTIONS.
This commit is contained in:
@ -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(),
|
||||
|
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -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>>>,
|
||||
}
|
||||
|
Reference in New Issue
Block a user