mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-18 11:21:21 +00:00
Add support for backend flags. Backend flags are opaque to src/bin/wasmer.rs.
Use them to implement three features in the LLVM backend, getting a valid ELF object file, the post-optimization LLVM IR and the pre-optimization LLVM IR. Presently they are also global to the backend which is not ideal.
This commit is contained in:
@ -13,6 +13,7 @@ goblin = "0.0.24"
|
|||||||
libc = "0.2.60"
|
libc = "0.2.60"
|
||||||
nix = "0.14.1"
|
nix = "0.14.1"
|
||||||
capstone = { version = "0.6.0", optional = true }
|
capstone = { version = "0.6.0", optional = true }
|
||||||
|
structopt = "0.2.18"
|
||||||
|
|
||||||
[dependencies.inkwell]
|
[dependencies.inkwell]
|
||||||
git = "https://github.com/wasmerio/inkwell"
|
git = "https://github.com/wasmerio/inkwell"
|
||||||
|
@ -10,6 +10,8 @@ use libc::c_char;
|
|||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
ffi::{c_void, CString},
|
ffi::{c_void, CString},
|
||||||
|
fs::File,
|
||||||
|
io::Write,
|
||||||
mem,
|
mem,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
ptr::{self, NonNull},
|
ptr::{self, NonNull},
|
||||||
@ -177,6 +179,14 @@ impl LLVMBackend {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mem_buf_slice = memory_buffer.as_slice();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let callbacks = get_callbacks();
|
let callbacks = get_callbacks();
|
||||||
let mut module: *mut LLVMModule = ptr::null_mut();
|
let mut module: *mut LLVMModule = ptr::null_mut();
|
||||||
|
|
||||||
|
@ -4639,6 +4639,10 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
|
|||||||
self.intrinsics.as_ref().unwrap(),
|
self.intrinsics.as_ref().unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } {
|
||||||
|
self.module.print_to_file(path).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let pass_manager = PassManager::create(());
|
let pass_manager = PassManager::create(());
|
||||||
if cfg!(test) {
|
if cfg!(test) {
|
||||||
pass_manager.add_verifier_pass();
|
pass_manager.add_verifier_pass();
|
||||||
@ -4658,7 +4662,9 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
|
|||||||
pass_manager.add_slp_vectorize_pass();
|
pass_manager.add_slp_vectorize_pass();
|
||||||
pass_manager.run_on(&self.module);
|
pass_manager.run_on(&self.module);
|
||||||
|
|
||||||
// self.module.print_to_stderr();
|
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.post_opt_ir } {
|
||||||
|
self.module.print_to_file(path).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let (backend, cache_gen) = LLVMBackend::new(self.module, self.intrinsics.take().unwrap());
|
let (backend, cache_gen) = LLVMBackend::new(self.module, self.intrinsics.take().unwrap());
|
||||||
Ok((backend, Box::new(cache_gen)))
|
Ok((backend, Box::new(cache_gen)))
|
||||||
|
@ -16,6 +16,9 @@ mod state;
|
|||||||
mod structs;
|
mod structs;
|
||||||
mod trampolines;
|
mod trampolines;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use structopt::StructOpt;
|
||||||
|
|
||||||
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
|
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
|
||||||
pub use code::LLVMModuleCodeGenerator as ModuleCodeGenerator;
|
pub use code::LLVMModuleCodeGenerator as ModuleCodeGenerator;
|
||||||
|
|
||||||
@ -27,3 +30,25 @@ pub type LLVMCompiler = SimpleStreamingCompilerGen<
|
|||||||
backend::LLVMBackend,
|
backend::LLVMBackend,
|
||||||
code::CodegenError,
|
code::CodegenError,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt, Clone)]
|
||||||
|
/// LLVM backend flags.
|
||||||
|
pub struct CLIOptions {
|
||||||
|
/// Emit LLVM IR before optimization pipeline.
|
||||||
|
#[structopt(long = "backend-llvm-pre-opt-ir", parse(from_os_str))]
|
||||||
|
pre_opt_ir: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Emit LLVM IR after optimization pipeline.
|
||||||
|
#[structopt(long = "backend-llvm-post-opt-ir", parse(from_os_str))]
|
||||||
|
post_opt_ir: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Emit LLVM generated native code object file.
|
||||||
|
#[structopt(long = "backend-llvm-object-file", parse(from_os_str))]
|
||||||
|
obj_file: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static mut GLOBAL_OPTIONS: CLIOptions = CLIOptions {
|
||||||
|
pre_opt_ir: None,
|
||||||
|
post_opt_ir: None,
|
||||||
|
obj_file: None,
|
||||||
|
};
|
||||||
|
@ -155,6 +155,10 @@ struct Run {
|
|||||||
#[structopt(long = "cache-key", hidden = true)]
|
#[structopt(long = "cache-key", hidden = true)]
|
||||||
cache_key: Option<String>,
|
cache_key: Option<String>,
|
||||||
|
|
||||||
|
#[cfg(feature = "backend-llvm")]
|
||||||
|
#[structopt(flatten)]
|
||||||
|
backend_llvm_options: wasmer_llvm_backend::CLIOptions,
|
||||||
|
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
features: PrestandardFeatures,
|
features: PrestandardFeatures,
|
||||||
|
|
||||||
@ -356,6 +360,15 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?;
|
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "backend-llvm")]
|
||||||
|
{
|
||||||
|
if options.backend == Backend::LLVM {
|
||||||
|
unsafe {
|
||||||
|
wasmer_llvm_backend::GLOBAL_OPTIONS = options.backend_llvm_options.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let compiler: Box<dyn Compiler> = match options.backend {
|
let compiler: Box<dyn Compiler> = match options.backend {
|
||||||
#[cfg(feature = "backend-singlepass")]
|
#[cfg(feature = "backend-singlepass")]
|
||||||
Backend::Singlepass => Box::new(SinglePassCompiler::new()),
|
Backend::Singlepass => Box::new(SinglePassCompiler::new()),
|
||||||
|
Reference in New Issue
Block a user