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:
Nick Lewycky
2019-08-08 16:05:17 -07:00
parent 77fe15db31
commit b2c4501357
5 changed files with 56 additions and 1 deletions

View File

@ -10,6 +10,8 @@ use libc::c_char;
use std::{
any::Any,
ffi::{c_void, CString},
fs::File,
io::Write,
mem,
ops::Deref,
ptr::{self, NonNull},
@ -177,6 +179,14 @@ impl LLVMBackend {
.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();
}
}
let callbacks = get_callbacks();
let mut module: *mut LLVMModule = ptr::null_mut();

View File

@ -4639,6 +4639,10 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
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(());
if cfg!(test) {
pass_manager.add_verifier_pass();
@ -4658,7 +4662,9 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
pass_manager.add_slp_vectorize_pass();
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());
Ok((backend, Box::new(cache_gen)))

View File

@ -16,6 +16,9 @@ mod state;
mod structs;
mod trampolines;
use std::path::PathBuf;
use structopt::StructOpt;
pub use code::LLVMFunctionCodeGenerator as FunctionCodeGenerator;
pub use code::LLVMModuleCodeGenerator as ModuleCodeGenerator;
@ -27,3 +30,25 @@ pub type LLVMCompiler = SimpleStreamingCompilerGen<
backend::LLVMBackend,
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,
};