mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-25 10:22:19 +00:00
Label the loads in intrinsics.rs, most of which are the initial accesses off the context.
Move tbaa_label to intrinsics.rs. Move TBAA pass to first in the list, it doesn't get invalidated. Add TBAA labels for internal fields.
This commit is contained in:
parent
74eaec968e
commit
15ce8bfda7
@ -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, InstructionValue, IntValue,
|
BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PhiValue, PointerValue,
|
||||||
MetadataValue, PhiValue, PointerValue, VectorValue,
|
VectorValue,
|
||||||
},
|
},
|
||||||
AddressSpace, AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate, OptimizationLevel,
|
AddressSpace, AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate, OptimizationLevel,
|
||||||
};
|
};
|
||||||
@ -29,7 +29,7 @@ use wasmer_runtime_core::{
|
|||||||
use wasmparser::{BinaryReaderError, MemoryImmediate, Operator, Type as WpType};
|
use wasmparser::{BinaryReaderError, MemoryImmediate, Operator, Type as WpType};
|
||||||
|
|
||||||
use crate::backend::LLVMBackend;
|
use crate::backend::LLVMBackend;
|
||||||
use crate::intrinsics::{CtxType, GlobalCache, Intrinsics, MemoryCache};
|
use crate::intrinsics::{tbaa_label, CtxType, GlobalCache, Intrinsics, MemoryCache};
|
||||||
use crate::read_info::{blocktype_to_type, type_to_type};
|
use crate::read_info::{blocktype_to_type, type_to_type};
|
||||||
use crate::stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic};
|
use crate::stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic};
|
||||||
use crate::state::{ControlFrame, ExtraInfo, IfElseState, State};
|
use crate::state::{ControlFrame, ExtraInfo, IfElseState, State};
|
||||||
@ -561,7 +561,7 @@ fn resolve_memory_ptr(
|
|||||||
value_size: usize,
|
value_size: usize,
|
||||||
) -> Result<PointerValue, BinaryReaderError> {
|
) -> Result<PointerValue, BinaryReaderError> {
|
||||||
// Look up the memory base (as pointer) and bounds (as unsigned integer).
|
// Look up the memory base (as pointer) and bounds (as unsigned integer).
|
||||||
let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics);
|
let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics, module.clone());
|
||||||
let (mem_base, mem_bound) = match memory_cache {
|
let (mem_base, mem_bound) = match memory_cache {
|
||||||
MemoryCache::Dynamic {
|
MemoryCache::Dynamic {
|
||||||
ptr_to_base_ptr,
|
ptr_to_base_ptr,
|
||||||
@ -652,46 +652,6 @@ fn resolve_memory_ptr(
|
|||||||
.into_pointer_value())
|
.into_pointer_value())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tbaa_label(
|
|
||||||
module: Rc<RefCell<Module>>,
|
|
||||||
intrinsics: &Intrinsics,
|
|
||||||
label: &str,
|
|
||||||
instruction: InstructionValue,
|
|
||||||
index: Option<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 label = if let Some(idx) = index {
|
|
||||||
format!("{}{}", label, idx)
|
|
||||||
} else {
|
|
||||||
label.to_string()
|
|
||||||
};
|
|
||||||
let type_label = context.metadata_string(label.as_str());
|
|
||||||
module.add_global_metadata(
|
|
||||||
label.as_str(),
|
|
||||||
&MetadataValue::create_node(&[type_label.into(), tbaa_root.into()]),
|
|
||||||
);
|
|
||||||
let type_tbaa = module.get_global_metadata(label.as_str())[0];
|
|
||||||
|
|
||||||
let label = label + "_memop";
|
|
||||||
module.add_global_metadata(
|
|
||||||
label.as_str(),
|
|
||||||
&MetadataValue::create_node(&[
|
|
||||||
type_tbaa.into(),
|
|
||||||
type_tbaa.into(),
|
|
||||||
intrinsics.i64_zero.into(),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
let type_tbaa = module.get_global_metadata(label.as_str())[0];
|
|
||||||
|
|
||||||
let tbaa_kind = context.get_kind_id("tbaa");
|
|
||||||
instruction.set_metadata(type_tbaa, tbaa_kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_stack_map(
|
fn emit_stack_map(
|
||||||
_module_info: &ModuleInfo,
|
_module_info: &ModuleInfo,
|
||||||
intrinsics: &Intrinsics,
|
intrinsics: &Intrinsics,
|
||||||
@ -1027,17 +987,33 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
InternalEvent::GetInternal(idx) => {
|
InternalEvent::GetInternal(idx) => {
|
||||||
if state.reachable {
|
if state.reachable {
|
||||||
let idx = idx as usize;
|
let idx = idx as usize;
|
||||||
let field_ptr = ctx.internal_field(idx, intrinsics, builder);
|
let field_ptr =
|
||||||
|
ctx.internal_field(idx, intrinsics, self.module.clone(), builder);
|
||||||
let result = builder.build_load(field_ptr, "get_internal");
|
let result = builder.build_load(field_ptr, "get_internal");
|
||||||
|
tbaa_label(
|
||||||
|
self.module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"internal",
|
||||||
|
result.as_instruction_value().unwrap(),
|
||||||
|
Some(idx as u32),
|
||||||
|
);
|
||||||
state.push1(result);
|
state.push1(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InternalEvent::SetInternal(idx) => {
|
InternalEvent::SetInternal(idx) => {
|
||||||
if state.reachable {
|
if state.reachable {
|
||||||
let idx = idx as usize;
|
let idx = idx as usize;
|
||||||
let field_ptr = ctx.internal_field(idx, intrinsics, builder);
|
let field_ptr =
|
||||||
|
ctx.internal_field(idx, intrinsics, self.module.clone(), builder);
|
||||||
let v = state.pop1()?;
|
let v = state.pop1()?;
|
||||||
builder.build_store(field_ptr, v);
|
let store = builder.build_store(field_ptr, v);
|
||||||
|
tbaa_label(
|
||||||
|
self.module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"internal",
|
||||||
|
store,
|
||||||
|
Some(idx as u32),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1622,7 +1598,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
|
|
||||||
Operator::GetGlobal { global_index } => {
|
Operator::GetGlobal { global_index } => {
|
||||||
let index = GlobalIndex::new(global_index as usize);
|
let index = GlobalIndex::new(global_index as usize);
|
||||||
let global_cache = ctx.global_cache(index, intrinsics);
|
let global_cache = ctx.global_cache(index, intrinsics, self.module.clone());
|
||||||
match global_cache {
|
match global_cache {
|
||||||
GlobalCache::Const { value } => {
|
GlobalCache::Const { value } => {
|
||||||
state.push1(value);
|
state.push1(value);
|
||||||
@ -1644,7 +1620,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
let (value, info) = state.pop1_extra()?;
|
let (value, info) = state.pop1_extra()?;
|
||||||
let value = apply_pending_canonicalization(builder, intrinsics, value, info);
|
let value = apply_pending_canonicalization(builder, intrinsics, value, info);
|
||||||
let index = GlobalIndex::new(global_index as usize);
|
let index = GlobalIndex::new(global_index as usize);
|
||||||
let global_cache = ctx.global_cache(index, intrinsics);
|
let global_cache = ctx.global_cache(index, intrinsics, self.module.clone());
|
||||||
match global_cache {
|
match global_cache {
|
||||||
GlobalCache::Mut { ptr_to_value } => {
|
GlobalCache::Mut { ptr_to_value } => {
|
||||||
let store = builder.build_store(ptr_to_value, value);
|
let store = builder.build_store(ptr_to_value, value);
|
||||||
@ -1712,14 +1688,19 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let func_ptr =
|
let func_ptr = ctx.local_func(
|
||||||
ctx.local_func(local_func_index, llvm_sig, intrinsics, builder);
|
local_func_index,
|
||||||
|
llvm_sig,
|
||||||
|
intrinsics,
|
||||||
|
self.module.clone(),
|
||||||
|
builder,
|
||||||
|
);
|
||||||
|
|
||||||
(params, func_ptr)
|
(params, func_ptr)
|
||||||
}
|
}
|
||||||
LocalOrImport::Import(import_func_index) => {
|
LocalOrImport::Import(import_func_index) => {
|
||||||
let (func_ptr_untyped, ctx_ptr) =
|
let (func_ptr_untyped, ctx_ptr) =
|
||||||
ctx.imported_func(import_func_index, intrinsics);
|
ctx.imported_func(import_func_index, intrinsics, self.module.clone());
|
||||||
|
|
||||||
let params: Vec<_> = std::iter::once(ctx_ptr.as_basic_value_enum())
|
let params: Vec<_> = std::iter::once(ctx_ptr.as_basic_value_enum())
|
||||||
.chain(
|
.chain(
|
||||||
@ -1822,8 +1803,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
Operator::CallIndirect { index, table_index } => {
|
Operator::CallIndirect { index, table_index } => {
|
||||||
let sig_index = SigIndex::new(index as usize);
|
let sig_index = SigIndex::new(index as usize);
|
||||||
let expected_dynamic_sigindex = ctx.dynamic_sigindex(sig_index, intrinsics);
|
let expected_dynamic_sigindex = ctx.dynamic_sigindex(sig_index, intrinsics);
|
||||||
let (table_base, table_bound) =
|
let (table_base, table_bound) = ctx.table(
|
||||||
ctx.table(TableIndex::new(table_index as usize), intrinsics, builder);
|
TableIndex::new(table_index as usize),
|
||||||
|
intrinsics,
|
||||||
|
self.module.clone(),
|
||||||
|
builder,
|
||||||
|
);
|
||||||
let func_index = state.pop1()?.into_int_value();
|
let func_index = state.pop1()?.into_int_value();
|
||||||
|
|
||||||
// We assume the table has the `anyfunc` element type.
|
// We assume the table has the `anyfunc` element type.
|
||||||
@ -7814,11 +7799,11 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
|
|||||||
if cfg!(test) {
|
if cfg!(test) {
|
||||||
pass_manager.add_verifier_pass();
|
pass_manager.add_verifier_pass();
|
||||||
}
|
}
|
||||||
|
pass_manager.add_type_based_alias_analysis_pass();
|
||||||
pass_manager.add_lower_expect_intrinsic_pass();
|
pass_manager.add_lower_expect_intrinsic_pass();
|
||||||
pass_manager.add_scalar_repl_aggregates_pass();
|
pass_manager.add_scalar_repl_aggregates_pass();
|
||||||
pass_manager.add_instruction_combining_pass();
|
pass_manager.add_instruction_combining_pass();
|
||||||
pass_manager.add_cfg_simplification_pass();
|
pass_manager.add_cfg_simplification_pass();
|
||||||
pass_manager.add_type_based_alias_analysis_pass();
|
|
||||||
pass_manager.add_gvn_pass();
|
pass_manager.add_gvn_pass();
|
||||||
pass_manager.add_jump_threading_pass();
|
pass_manager.add_jump_threading_pass();
|
||||||
pass_manager.add_correlated_value_propagation_pass();
|
pass_manager.add_correlated_value_propagation_pass();
|
||||||
|
@ -7,12 +7,15 @@ use inkwell::{
|
|||||||
BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType,
|
BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType,
|
||||||
},
|
},
|
||||||
values::{
|
values::{
|
||||||
BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue, VectorValue,
|
BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue,
|
||||||
|
MetadataValue, PointerValue, VectorValue,
|
||||||
},
|
},
|
||||||
AddressSpace,
|
AddressSpace,
|
||||||
};
|
};
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::rc::Rc;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
memory::MemoryType,
|
memory::MemoryType,
|
||||||
module::ModuleInfo,
|
module::ModuleInfo,
|
||||||
@ -653,7 +656,12 @@ impl<'a> CtxType<'a> {
|
|||||||
ptr
|
ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memory(&mut self, index: MemoryIndex, intrinsics: &Intrinsics) -> MemoryCache {
|
pub fn memory(
|
||||||
|
&mut self,
|
||||||
|
index: MemoryIndex,
|
||||||
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
|
) -> MemoryCache {
|
||||||
let (cached_memories, info, ctx_ptr_value, cache_builder) = (
|
let (cached_memories, info, ctx_ptr_value, cache_builder) = (
|
||||||
&mut self.cached_memories,
|
&mut self.cached_memories,
|
||||||
self.info,
|
self.info,
|
||||||
@ -690,6 +698,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let memory_array_ptr = cache_builder
|
let memory_array_ptr = cache_builder
|
||||||
.build_load(memory_array_ptr_ptr, "memory_array_ptr")
|
.build_load(memory_array_ptr_ptr, "memory_array_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"memory_array",
|
||||||
|
memory_array_ptr.as_instruction_value().unwrap(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let const_index = intrinsics.i32_ty.const_int(index, false);
|
let const_index = intrinsics.i32_ty.const_int(index, false);
|
||||||
let memory_ptr_ptr = unsafe {
|
let memory_ptr_ptr = unsafe {
|
||||||
cache_builder.build_in_bounds_gep(
|
cache_builder.build_in_bounds_gep(
|
||||||
@ -701,6 +716,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let memory_ptr = cache_builder
|
let memory_ptr = cache_builder
|
||||||
.build_load(memory_ptr_ptr, "memory_ptr")
|
.build_load(memory_ptr_ptr, "memory_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"memory_ptr",
|
||||||
|
memory_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index as u32),
|
||||||
|
);
|
||||||
|
|
||||||
let (ptr_to_base_ptr, ptr_to_bounds) = unsafe {
|
let (ptr_to_base_ptr, ptr_to_bounds) = unsafe {
|
||||||
(
|
(
|
||||||
@ -714,14 +736,29 @@ impl<'a> CtxType<'a> {
|
|||||||
ptr_to_base_ptr,
|
ptr_to_base_ptr,
|
||||||
ptr_to_bounds,
|
ptr_to_bounds,
|
||||||
},
|
},
|
||||||
MemoryType::Static | MemoryType::SharedStatic => MemoryCache::Static {
|
MemoryType::Static | MemoryType::SharedStatic => {
|
||||||
base_ptr: cache_builder
|
let base_ptr = cache_builder
|
||||||
.build_load(ptr_to_base_ptr, "base")
|
.build_load(ptr_to_base_ptr, "base")
|
||||||
.into_pointer_value(),
|
.into_pointer_value();
|
||||||
bounds: cache_builder
|
let bounds = cache_builder
|
||||||
.build_load(ptr_to_bounds, "bounds")
|
.build_load(ptr_to_bounds, "bounds")
|
||||||
.into_int_value(),
|
.into_int_value();
|
||||||
},
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"memory_base",
|
||||||
|
base_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index as u32),
|
||||||
|
);
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"memory_bounds",
|
||||||
|
bounds.as_instruction_value().unwrap(),
|
||||||
|
Some(index as u32),
|
||||||
|
);
|
||||||
|
MemoryCache::Static { base_ptr, bounds }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -730,6 +767,7 @@ impl<'a> CtxType<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
index: TableIndex,
|
index: TableIndex,
|
||||||
intrinsics: &Intrinsics,
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
) -> (PointerValue, PointerValue) {
|
) -> (PointerValue, PointerValue) {
|
||||||
let (cached_tables, info, ctx_ptr_value, cache_builder) = (
|
let (cached_tables, info, ctx_ptr_value, cache_builder) = (
|
||||||
&mut self.cached_tables,
|
&mut self.cached_tables,
|
||||||
@ -768,6 +806,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let table_array_ptr = cache_builder
|
let table_array_ptr = cache_builder
|
||||||
.build_load(table_array_ptr_ptr, "table_array_ptr")
|
.build_load(table_array_ptr_ptr, "table_array_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"context_field_ptr_to_tables",
|
||||||
|
table_array_ptr.as_instruction_value().unwrap(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let const_index = intrinsics.i32_ty.const_int(index, false);
|
let const_index = intrinsics.i32_ty.const_int(index, false);
|
||||||
let table_ptr_ptr = unsafe {
|
let table_ptr_ptr = unsafe {
|
||||||
cache_builder.build_in_bounds_gep(table_array_ptr, &[const_index], "table_ptr_ptr")
|
cache_builder.build_in_bounds_gep(table_array_ptr, &[const_index], "table_ptr_ptr")
|
||||||
@ -775,6 +820,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let table_ptr = cache_builder
|
let table_ptr = cache_builder
|
||||||
.build_load(table_ptr_ptr, "table_ptr")
|
.build_load(table_ptr_ptr, "table_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"table_ptr",
|
||||||
|
table_array_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index as u32),
|
||||||
|
);
|
||||||
|
|
||||||
let (ptr_to_base_ptr, ptr_to_bounds) = unsafe {
|
let (ptr_to_base_ptr, ptr_to_bounds) = unsafe {
|
||||||
(
|
(
|
||||||
@ -796,15 +848,30 @@ impl<'a> CtxType<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
index: TableIndex,
|
index: TableIndex,
|
||||||
intrinsics: &Intrinsics,
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
builder: &Builder,
|
builder: &Builder,
|
||||||
) -> (PointerValue, IntValue) {
|
) -> (PointerValue, IntValue) {
|
||||||
let (ptr_to_base_ptr, ptr_to_bounds) = self.table_prepare(index, intrinsics);
|
let (ptr_to_base_ptr, ptr_to_bounds) =
|
||||||
(
|
self.table_prepare(index, intrinsics, module.clone());
|
||||||
builder
|
let base_ptr = builder
|
||||||
.build_load(ptr_to_base_ptr, "base_ptr")
|
.build_load(ptr_to_base_ptr, "base_ptr")
|
||||||
.into_pointer_value(),
|
.into_pointer_value();
|
||||||
builder.build_load(ptr_to_bounds, "bounds").into_int_value(),
|
let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value();
|
||||||
)
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"table_base_ptr",
|
||||||
|
base_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index.index() as u32),
|
||||||
|
);
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"table_bounds",
|
||||||
|
bounds.as_instruction_value().unwrap(),
|
||||||
|
Some(index.index() as u32),
|
||||||
|
);
|
||||||
|
(base_ptr, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_func(
|
pub fn local_func(
|
||||||
@ -812,6 +879,7 @@ impl<'a> CtxType<'a> {
|
|||||||
index: LocalFuncIndex,
|
index: LocalFuncIndex,
|
||||||
fn_ty: FunctionType,
|
fn_ty: FunctionType,
|
||||||
intrinsics: &Intrinsics,
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
builder: &Builder,
|
builder: &Builder,
|
||||||
) -> PointerValue {
|
) -> PointerValue {
|
||||||
let local_func_array_ptr_ptr = unsafe {
|
let local_func_array_ptr_ptr = unsafe {
|
||||||
@ -824,6 +892,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let local_func_array_ptr = builder
|
let local_func_array_ptr = builder
|
||||||
.build_load(local_func_array_ptr_ptr, "local_func_array_ptr")
|
.build_load(local_func_array_ptr_ptr, "local_func_array_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"context_field_ptr_to_local_funcs",
|
||||||
|
local_func_array_ptr.as_instruction_value().unwrap(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let local_func_ptr_ptr = unsafe {
|
let local_func_ptr_ptr = unsafe {
|
||||||
builder.build_in_bounds_gep(
|
builder.build_in_bounds_gep(
|
||||||
local_func_array_ptr,
|
local_func_array_ptr,
|
||||||
@ -834,6 +909,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let local_func_ptr = builder
|
let local_func_ptr = builder
|
||||||
.build_load(local_func_ptr_ptr, "local_func_ptr")
|
.build_load(local_func_ptr_ptr, "local_func_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"local_func_ptr",
|
||||||
|
local_func_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index.index() as u32),
|
||||||
|
);
|
||||||
builder.build_pointer_cast(
|
builder.build_pointer_cast(
|
||||||
local_func_ptr,
|
local_func_ptr,
|
||||||
fn_ty.ptr_type(AddressSpace::Generic),
|
fn_ty.ptr_type(AddressSpace::Generic),
|
||||||
@ -875,7 +957,12 @@ impl<'a> CtxType<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn global_cache(&mut self, index: GlobalIndex, intrinsics: &Intrinsics) -> GlobalCache {
|
pub fn global_cache(
|
||||||
|
&mut self,
|
||||||
|
index: GlobalIndex,
|
||||||
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
|
) -> GlobalCache {
|
||||||
let (cached_globals, ctx_ptr_value, info, cache_builder) = (
|
let (cached_globals, ctx_ptr_value, info, cache_builder) = (
|
||||||
&mut self.cached_globals,
|
&mut self.cached_globals,
|
||||||
self.ctx_ptr_value,
|
self.ctx_ptr_value,
|
||||||
@ -923,6 +1010,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let global_array_ptr = cache_builder
|
let global_array_ptr = cache_builder
|
||||||
.build_load(globals_array_ptr_ptr, "global_array_ptr")
|
.build_load(globals_array_ptr_ptr, "global_array_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"context_field_ptr_to_globals",
|
||||||
|
globals_array_ptr_ptr.as_instruction_value().unwrap(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let const_index = intrinsics.i32_ty.const_int(index, false);
|
let const_index = intrinsics.i32_ty.const_int(index, false);
|
||||||
let global_ptr_ptr = unsafe {
|
let global_ptr_ptr = unsafe {
|
||||||
cache_builder.build_in_bounds_gep(
|
cache_builder.build_in_bounds_gep(
|
||||||
@ -934,6 +1028,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let global_ptr = cache_builder
|
let global_ptr = cache_builder
|
||||||
.build_load(global_ptr_ptr, "global_ptr")
|
.build_load(global_ptr_ptr, "global_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"global_ptr",
|
||||||
|
globals_array_ptr_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index as u32),
|
||||||
|
);
|
||||||
|
|
||||||
let global_ptr_typed =
|
let global_ptr_typed =
|
||||||
cache_builder.build_pointer_cast(global_ptr, llvm_ptr_ty, "global_ptr_typed");
|
cache_builder.build_pointer_cast(global_ptr, llvm_ptr_ty, "global_ptr_typed");
|
||||||
@ -943,9 +1044,15 @@ impl<'a> CtxType<'a> {
|
|||||||
ptr_to_value: global_ptr_typed,
|
ptr_to_value: global_ptr_typed,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GlobalCache::Const {
|
let value = cache_builder.build_load(global_ptr_typed, "global_value");
|
||||||
value: cache_builder.build_load(global_ptr_typed, "global_value"),
|
tbaa_label(
|
||||||
}
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"global",
|
||||||
|
value.as_instruction_value().unwrap(),
|
||||||
|
Some(index as u32),
|
||||||
|
);
|
||||||
|
GlobalCache::Const { value }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -954,6 +1061,7 @@ impl<'a> CtxType<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
index: ImportedFuncIndex,
|
index: ImportedFuncIndex,
|
||||||
intrinsics: &Intrinsics,
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
) -> (PointerValue, PointerValue) {
|
) -> (PointerValue, PointerValue) {
|
||||||
let (cached_imported_functions, ctx_ptr_value, cache_builder) = (
|
let (cached_imported_functions, ctx_ptr_value, cache_builder) = (
|
||||||
&mut self.cached_imported_functions,
|
&mut self.cached_imported_functions,
|
||||||
@ -972,6 +1080,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let func_array_ptr = cache_builder
|
let func_array_ptr = cache_builder
|
||||||
.build_load(func_array_ptr_ptr, "func_array_ptr")
|
.build_load(func_array_ptr_ptr, "func_array_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"context_field_ptr_to_imported_funcs",
|
||||||
|
func_array_ptr.as_instruction_value().unwrap(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
let const_index = intrinsics.i32_ty.const_int(index.index() as u64, false);
|
let const_index = intrinsics.i32_ty.const_int(index.index() as u64, false);
|
||||||
let imported_func_ptr = unsafe {
|
let imported_func_ptr = unsafe {
|
||||||
cache_builder.build_in_bounds_gep(
|
cache_builder.build_in_bounds_gep(
|
||||||
@ -993,6 +1108,20 @@ impl<'a> CtxType<'a> {
|
|||||||
let ctx_ptr = cache_builder
|
let ctx_ptr = cache_builder
|
||||||
.build_load(ctx_ptr_ptr, "ctx_ptr")
|
.build_load(ctx_ptr_ptr, "ctx_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"imported_func_ptr",
|
||||||
|
func_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index.index() as u32),
|
||||||
|
);
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"imported_func_ctx_ptr",
|
||||||
|
ctx_ptr.as_instruction_value().unwrap(),
|
||||||
|
Some(index.index() as u32),
|
||||||
|
);
|
||||||
|
|
||||||
ImportedFuncCache { func_ptr, ctx_ptr }
|
ImportedFuncCache { func_ptr, ctx_ptr }
|
||||||
});
|
});
|
||||||
@ -1004,6 +1133,7 @@ impl<'a> CtxType<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
intrinsics: &Intrinsics,
|
intrinsics: &Intrinsics,
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
builder: &Builder,
|
builder: &Builder,
|
||||||
) -> PointerValue {
|
) -> PointerValue {
|
||||||
assert!(index < INTERNALS_SIZE);
|
assert!(index < INTERNALS_SIZE);
|
||||||
@ -1018,6 +1148,13 @@ impl<'a> CtxType<'a> {
|
|||||||
let local_internals_ptr = builder
|
let local_internals_ptr = builder
|
||||||
.build_load(local_internals_ptr_ptr, "local_internals_ptr")
|
.build_load(local_internals_ptr_ptr, "local_internals_ptr")
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
|
tbaa_label(
|
||||||
|
module.clone(),
|
||||||
|
intrinsics,
|
||||||
|
"context_field_ptr_to_internals",
|
||||||
|
local_internals_ptr_ptr.as_instruction_value().unwrap(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
builder.build_in_bounds_gep(
|
builder.build_in_bounds_gep(
|
||||||
local_internals_ptr,
|
local_internals_ptr,
|
||||||
@ -1027,3 +1164,43 @@ impl<'a> CtxType<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tbaa_label(
|
||||||
|
module: Rc<RefCell<Module>>,
|
||||||
|
intrinsics: &Intrinsics,
|
||||||
|
label: &str,
|
||||||
|
instruction: InstructionValue,
|
||||||
|
index: Option<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 label = if let Some(idx) = index {
|
||||||
|
format!("{}{}", label, idx)
|
||||||
|
} else {
|
||||||
|
label.to_string()
|
||||||
|
};
|
||||||
|
let type_label = context.metadata_string(label.as_str());
|
||||||
|
module.add_global_metadata(
|
||||||
|
label.as_str(),
|
||||||
|
&MetadataValue::create_node(&[type_label.into(), tbaa_root.into()]),
|
||||||
|
);
|
||||||
|
let type_tbaa = module.get_global_metadata(label.as_str())[0];
|
||||||
|
|
||||||
|
let label = label + "_memop";
|
||||||
|
module.add_global_metadata(
|
||||||
|
label.as_str(),
|
||||||
|
&MetadataValue::create_node(&[
|
||||||
|
type_tbaa.into(),
|
||||||
|
type_tbaa.into(),
|
||||||
|
intrinsics.i64_zero.into(),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
let type_tbaa = module.get_global_metadata(label.as_str())[0];
|
||||||
|
|
||||||
|
let tbaa_kind = context.get_kind_id("tbaa");
|
||||||
|
instruction.set_metadata(type_tbaa, tbaa_kind);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user