Update module to be held by Rc<RefCell<>> so that we can pass it to LLVMFunctionCodeGenerator.

Use that to generate distinct TBAA labels for distinct local variables.
This commit is contained in:
Nick Lewycky 2019-10-30 13:11:29 -07:00
parent f77d9bfe32
commit e7d1742c63
2 changed files with 59 additions and 20 deletions

View File

@ -9,12 +9,14 @@ use inkwell::{
use libc::c_char; use libc::c_char;
use std::{ use std::{
any::Any, any::Any,
cell::RefCell,
ffi::{c_void, CString}, ffi::{c_void, CString},
fs::File, fs::File,
io::Write, io::Write,
mem, mem,
ops::Deref, ops::Deref,
ptr::{self, NonNull}, ptr::{self, NonNull},
rc::Rc,
slice, str, slice, str,
sync::{Arc, Once}, sync::{Arc, Once},
}; };
@ -167,14 +169,14 @@ pub struct LLVMBackend {
impl LLVMBackend { impl LLVMBackend {
pub fn new( pub fn new(
module: Module, module: Rc<RefCell<Module>>,
_intrinsics: Intrinsics, _intrinsics: Intrinsics,
_stackmaps: &StackmapRegistry, _stackmaps: &StackmapRegistry,
_module_info: &ModuleInfo, _module_info: &ModuleInfo,
target_machine: &TargetMachine, target_machine: &TargetMachine,
) -> (Self, LLVMCache) { ) -> (Self, LLVMCache) {
let memory_buffer = target_machine let memory_buffer = target_machine
.write_to_memory_buffer(&module, FileType::Object) .write_to_memory_buffer(&module.borrow_mut(), FileType::Object)
.unwrap(); .unwrap();
let mem_buf_slice = memory_buffer.as_slice(); let mem_buf_slice = memory_buffer.as_slice();

View File

@ -6,8 +6,8 @@ use inkwell::{
targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine}, targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine},
types::{BasicType, BasicTypeEnum, FunctionType, PointerType, VectorType}, types::{BasicType, BasicTypeEnum, FunctionType, PointerType, VectorType},
values::{ values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, MetadataValue, PhiValue, BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue,
PointerValue, VectorValue, MetadataValue, PhiValue, PointerValue, VectorValue,
}, },
AddressSpace, AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate, OptimizationLevel, AddressSpace, AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate, OptimizationLevel,
}; };
@ -647,6 +647,41 @@ fn resolve_memory_ptr(
.into_pointer_value()) .into_pointer_value())
} }
fn local_tbaa(
module: Rc<RefCell<Module>>,
intrinsics: &Intrinsics,
instruction: InstructionValue,
index: u32,
) {
let module = module.borrow_mut();
let context = module.get_context();
module.add_global_metadata("wasmer_tbaa_root", &MetadataValue::create_node(&[]));
let tbaa_root = module.get_global_metadata("wasmer_tbaa_root")[0];
let name = format!("local {}", index);
let local = context.metadata_string(name.as_str());
module.add_global_metadata(
name.as_str(),
&MetadataValue::create_node(&[local.into(), tbaa_root.into()]),
);
let local_tbaa = module.get_global_metadata(name.as_str())[0];
let name = name + "_memop";
module.add_global_metadata(
name.as_str(),
&MetadataValue::create_node(&[
local_tbaa.into(),
local_tbaa.into(),
intrinsics.i64_zero.into(),
]),
);
let local_tbaa = module.get_global_metadata(name.as_str())[0];
let tbaa_kind = context.get_kind_id("tbaa");
instruction.set_metadata(local_tbaa, tbaa_kind);
}
fn emit_stack_map( fn emit_stack_map(
_module_info: &ModuleInfo, _module_info: &ModuleInfo,
intrinsics: &Intrinsics, intrinsics: &Intrinsics,
@ -814,7 +849,7 @@ pub struct LLVMModuleCodeGenerator {
function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>, function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>,
func_import_count: usize, func_import_count: usize,
personality_func: FunctionValue, personality_func: FunctionValue,
module: Module, module: Rc<RefCell<Module>>,
stackmaps: Rc<RefCell<StackmapRegistry>>, stackmaps: Rc<RefCell<StackmapRegistry>>,
track_state: bool, track_state: bool,
target_machine: TargetMachine, target_machine: TargetMachine,
@ -842,6 +877,7 @@ pub struct LLVMFunctionCodeGenerator {
index: usize, index: usize,
opcode_offset: usize, opcode_offset: usize,
track_state: bool, track_state: bool,
module: Rc<RefCell<Module>>,
memory_tbaa: MetadataValue, memory_tbaa: MetadataValue,
locals_tbaa: MetadataValue, locals_tbaa: MetadataValue,
globals_tbaa: MetadataValue, globals_tbaa: MetadataValue,
@ -1548,10 +1584,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
Operator::GetLocal { local_index } => { Operator::GetLocal { local_index } => {
let pointer_value = locals[local_index as usize]; let pointer_value = locals[local_index as usize];
let v = builder.build_load(pointer_value, &state.var_name()); let v = builder.build_load(pointer_value, &state.var_name());
let tbaa_kind = context.get_kind_id("tbaa"); local_tbaa(
v.as_instruction_value() self.module.clone(),
.unwrap() intrinsics,
.set_metadata(self.locals_tbaa, tbaa_kind); v.as_instruction_value().unwrap(),
local_index,
);
state.push1(v); state.push1(v);
} }
Operator::SetLocal { local_index } => { Operator::SetLocal { local_index } => {
@ -1559,16 +1597,14 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let (v, i) = state.pop1_extra()?; let (v, i) = state.pop1_extra()?;
let v = apply_pending_canonicalization(builder, intrinsics, v, i); let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let store = builder.build_store(pointer_value, v); let store = builder.build_store(pointer_value, v);
let tbaa_kind = context.get_kind_id("tbaa"); local_tbaa(self.module.clone(), intrinsics, store, local_index);
store.set_metadata(self.locals_tbaa, tbaa_kind);
} }
Operator::TeeLocal { local_index } => { Operator::TeeLocal { local_index } => {
let pointer_value = locals[local_index as usize]; let pointer_value = locals[local_index as usize];
let (v, i) = state.peek1_extra()?; let (v, i) = state.peek1_extra()?;
let v = apply_pending_canonicalization(builder, intrinsics, v, i); let v = apply_pending_canonicalization(builder, intrinsics, v, i);
let store = builder.build_store(pointer_value, v); let store = builder.build_store(pointer_value, v);
let tbaa_kind = context.get_kind_id("tbaa"); local_tbaa(self.module.clone(), intrinsics, store, local_index);
store.set_metadata(self.locals_tbaa, tbaa_kind);
} }
Operator::GetGlobal { global_index } => { Operator::GetGlobal { global_index } => {
@ -7752,7 +7788,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
context: Some(context), context: Some(context),
builder: Some(builder), builder: Some(builder),
intrinsics: Some(intrinsics), intrinsics: Some(intrinsics),
module, module: Rc::new(RefCell::new(module)),
functions: vec![], functions: vec![],
signatures: Map::new(), signatures: Map::new(),
signatures_raw: Map::new(), signatures_raw: Map::new(),
@ -7800,7 +7836,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
[FuncIndex::new(self.func_import_count + self.functions.len())]; [FuncIndex::new(self.func_import_count + self.functions.len())];
let func_sig = self.signatures_raw[sig_id].clone(); let func_sig = self.signatures_raw[sig_id].clone();
let function = self.module.add_function( let function = self.module.borrow_mut().add_function(
&format!("fn{}", self.func_import_count + self.functions.len()), &format!("fn{}", self.func_import_count + self.functions.len()),
self.signatures[sig_id], self.signatures[sig_id],
Some(Linkage::External), Some(Linkage::External),
@ -7873,6 +7909,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
index: local_func_index, index: local_func_index,
opcode_offset: 0, opcode_offset: 0,
track_state: self.track_state, track_state: self.track_state,
module: self.module.clone(),
memory_tbaa: self.memory_tbaa, memory_tbaa: self.memory_tbaa,
locals_tbaa: self.locals_tbaa, locals_tbaa: self.locals_tbaa,
globals_tbaa: self.globals_tbaa, globals_tbaa: self.globals_tbaa,
@ -7906,7 +7943,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
generate_trampolines( generate_trampolines(
module_info, module_info,
&self.signatures, &self.signatures,
&self.module, &self.module.borrow_mut(),
self.context.as_ref().unwrap(), self.context.as_ref().unwrap(),
self.builder.as_ref().unwrap(), self.builder.as_ref().unwrap(),
self.intrinsics.as_ref().unwrap(), self.intrinsics.as_ref().unwrap(),
@ -7916,7 +7953,7 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
})?; })?;
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } { if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } {
self.module.print_to_file(path).unwrap(); self.module.borrow_mut().print_to_file(path).unwrap();
} }
let pass_manager = PassManager::create(()); let pass_manager = PassManager::create(());
@ -7937,16 +7974,16 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
pass_manager.add_cfg_simplification_pass(); pass_manager.add_cfg_simplification_pass();
pass_manager.add_bit_tracking_dce_pass(); pass_manager.add_bit_tracking_dce_pass();
pass_manager.add_slp_vectorize_pass(); pass_manager.add_slp_vectorize_pass();
pass_manager.run_on(&self.module); pass_manager.run_on(&*self.module.borrow_mut());
if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.post_opt_ir } { if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.post_opt_ir } {
self.module.print_to_file(path).unwrap(); self.module.borrow_mut().print_to_file(path).unwrap();
} }
let stackmaps = self.stackmaps.borrow(); let stackmaps = self.stackmaps.borrow();
let (backend, cache_gen) = LLVMBackend::new( let (backend, cache_gen) = LLVMBackend::new(
self.module, self.module.clone(),
self.intrinsics.take().unwrap(), self.intrinsics.take().unwrap(),
&*stackmaps, &*stackmaps,
module_info, module_info,