diff --git a/CHANGELOG.md b/CHANGELOG.md index b4b97be02..afe906514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## **[Unreleased]** +- [#921](https://github.com/wasmerio/wasmer/pull/921) In LLVM backend, annotate all memory accesses with TBAA metadata. - [#883](https://github.com/wasmerio/wasmer/pull/883) Allow floating point operations to have arbitrary inputs, even including SNaNs. - [#856](https://github.com/wasmerio/wasmer/pull/856) Expose methods in the runtime C API to get a WASI import object diff --git a/Cargo.lock b/Cargo.lock index 57eb6a414..835d716a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,7 +120,7 @@ dependencies = [ "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -188,7 +188,7 @@ dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -275,7 +275,7 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -494,7 +494,15 @@ name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hermit-abi" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -514,7 +522,7 @@ dependencies = [ [[package]] name = "inkwell" version = "0.1.0" -source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#5ae21b51d9dd20a63e4431b06e3beb7a42d6ceb8" +source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#10d180807ce6e621ae13d74001bf5677b0e1f179" dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -528,7 +536,7 @@ dependencies = [ [[package]] name = "inkwell_internal_macros" version = "0.1.0" -source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#5ae21b51d9dd20a63e4431b06e3beb7a42d6ceb8" +source = "git+https://github.com/wasmerio/inkwell?branch=llvm8-0#10d180807ce6e621ae13d74001bf5677b0e1f179" dependencies = [ "cargo_toml 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -653,7 +661,7 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -686,9 +694,10 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -748,7 +757,7 @@ dependencies = [ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -914,7 +923,7 @@ dependencies = [ "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1067,7 +1076,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1223,7 +1232,7 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1258,7 +1267,7 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1385,7 +1394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cranelift-codegen 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1458,7 +1467,7 @@ dependencies = [ "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.9.0", "wasmparser 0.39.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1533,7 +1542,7 @@ dependencies = [ "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.39.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1559,7 +1568,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.9.0", ] @@ -1716,6 +1725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e3fa261d919c1ae9d1e4533c4a2f99e10938603c4208d56c05bec7a872b661b0" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" "checksum inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "" @@ -1734,11 +1744,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" +"checksum memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a85c1a8c329f11437034d7313dca647c79096523533a1c79e86f1d0f657c7cc" "checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" -"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" +"checksum num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "155394f924cdddf08149da25bfb932d226b4a593ca7468b08191ff6335941af5" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" @@ -1781,7 +1791,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc" "checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" "checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" -"checksum smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cefaa50e76a6f10b86f36e640eb1739eafbd4084865067778463913e43a77ff3" +"checksum smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "533e29e15d0748f28afbaf4ff7cab44d73e483a8e50b38c40bd13b7f3d48f542" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4f66a4c0ddf7aee4677995697366de0749b0139057342eccbb609b12d0affc" @@ -1799,11 +1809,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -"checksum toml 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c04dffffeac90885436d23c692517bb5b8b3f8863e4afc15023628d067d667b7" +"checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebb2c484029d695fb68a06d80e1536c68d491b3e0cf874c66abed255e831cfe" "checksum typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204" -"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" +"checksum unicode-segmentation 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49f5526225fd8b77342d5986ab5f6055552e9c0776193b5b63fd53b46debfad7" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs index e878c3feb..a5d262035 100644 --- a/lib/llvm-backend/src/backend.rs +++ b/lib/llvm-backend/src/backend.rs @@ -11,12 +11,14 @@ use inkwell::{ use libc::c_char; use std::{ any::Any, + cell::RefCell, ffi::{c_void, CString}, fs::File, io::Write, mem, ops::Deref, ptr::{self, NonNull}, + rc::Rc, slice, str, sync::{Arc, Once}, }; @@ -169,14 +171,14 @@ pub struct LLVMBackend { impl LLVMBackend { pub fn new( - module: Module, + module: Rc>, _intrinsics: Intrinsics, _stackmaps: &StackmapRegistry, _module_info: &ModuleInfo, target_machine: &TargetMachine, ) -> (Self, LLVMCache) { let memory_buffer = target_machine - .write_to_memory_buffer(&module, FileType::Object) + .write_to_memory_buffer(&module.borrow_mut(), FileType::Object) .unwrap(); let mem_buf_slice = memory_buffer.as_slice(); diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index 2377ed6c1..7b5f2d1a2 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -1,6 +1,6 @@ use crate::{ backend::LLVMBackend, - intrinsics::{CtxType, GlobalCache, Intrinsics, MemoryCache}, + intrinsics::{tbaa_label, CtxType, GlobalCache, Intrinsics, MemoryCache}, read_info::{blocktype_to_type, type_to_type}, stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic}, state::{ControlFrame, ExtraInfo, IfElseState, State}, @@ -555,6 +555,7 @@ fn resolve_memory_ptr( builder: &Builder, intrinsics: &Intrinsics, context: &Context, + module: Rc>, function: &FunctionValue, state: &mut State, ctx: &mut CtxType, @@ -563,7 +564,7 @@ fn resolve_memory_ptr( value_size: usize, ) -> Result { // 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, minimum, _maximum) = match memory_cache { MemoryCache::Dynamic { ptr_to_base_ptr, @@ -575,6 +576,20 @@ fn resolve_memory_ptr( .build_load(ptr_to_base_ptr, "base") .into_pointer_value(); let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value(); + tbaa_label( + module.clone(), + intrinsics, + "dynamic_memory_base", + base.as_instruction_value().unwrap(), + Some(0), + ); + tbaa_label( + module.clone(), + intrinsics, + "dynamic_memory_bounds", + bounds.as_instruction_value().unwrap(), + Some(0), + ); (base, bounds, minimum, maximum) } MemoryCache::Static { @@ -838,7 +853,7 @@ pub struct LLVMModuleCodeGenerator { function_signatures: Option>>, func_import_count: usize, personality_func: FunctionValue, - module: Module, + module: Rc>, stackmaps: Rc>, track_state: bool, target_machine: TargetMachine, @@ -861,6 +876,7 @@ pub struct LLVMFunctionCodeGenerator { index: usize, opcode_offset: usize, track_state: bool, + module: Rc>, } impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { @@ -1005,17 +1021,33 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { InternalEvent::GetInternal(idx) => { if state.reachable { 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"); + tbaa_label( + self.module.clone(), + intrinsics, + "internal", + result.as_instruction_value().unwrap(), + Some(idx as u32), + ); state.push1(result); } } InternalEvent::SetInternal(idx) => { if state.reachable { 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()?; - 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), + ); } } } @@ -1562,30 +1594,58 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { Operator::GetLocal { local_index } => { let pointer_value = locals[local_index as usize]; let v = builder.build_load(pointer_value, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "local", + v.as_instruction_value().unwrap(), + Some(local_index), + ); state.push1(v); } Operator::SetLocal { local_index } => { let pointer_value = locals[local_index as usize]; let (v, i) = state.pop1_extra()?; let v = apply_pending_canonicalization(builder, intrinsics, v, i); - builder.build_store(pointer_value, v); + let store = builder.build_store(pointer_value, v); + tbaa_label( + self.module.clone(), + intrinsics, + "local", + store, + Some(local_index), + ); } Operator::TeeLocal { local_index } => { let pointer_value = locals[local_index as usize]; let (v, i) = state.peek1_extra()?; let v = apply_pending_canonicalization(builder, intrinsics, v, i); - builder.build_store(pointer_value, v); + let store = builder.build_store(pointer_value, v); + tbaa_label( + self.module.clone(), + intrinsics, + "local", + store, + Some(local_index), + ); } Operator::GetGlobal { global_index } => { 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 { GlobalCache::Const { value } => { state.push1(value); } GlobalCache::Mut { ptr_to_value } => { let value = builder.build_load(ptr_to_value, "global_value"); + tbaa_label( + self.module.clone(), + intrinsics, + "global", + value.as_instruction_value().unwrap(), + Some(global_index), + ); state.push1(value); } } @@ -1594,10 +1654,17 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let (value, info) = state.pop1_extra()?; let value = apply_pending_canonicalization(builder, intrinsics, value, info); 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 { GlobalCache::Mut { ptr_to_value } => { - builder.build_store(ptr_to_value, value); + let store = builder.build_store(ptr_to_value, value); + tbaa_label( + self.module.clone(), + intrinsics, + "global", + store, + Some(global_index), + ); } GlobalCache::Const { value: _ } => { return Err(CodegenError { @@ -1655,14 +1722,19 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { ) .collect(); - let func_ptr = - ctx.local_func(local_func_index, llvm_sig, intrinsics, builder); + let func_ptr = ctx.local_func( + local_func_index, + llvm_sig, + intrinsics, + self.module.clone(), + builder, + ); (params, func_ptr) } LocalOrImport::Import(import_func_index) => { 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()) .chain( @@ -1765,8 +1837,12 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { Operator::CallIndirect { index, table_index } => { let sig_index = SigIndex::new(index as usize); let expected_dynamic_sigindex = ctx.dynamic_sigindex(sig_index, intrinsics); - let (table_base, table_bound) = - ctx.table(TableIndex::new(table_index as usize), intrinsics, builder); + let (table_base, table_bound) = ctx.table( + TableIndex::new(table_index as usize), + intrinsics, + self.module.clone(), + builder, + ); let func_index = state.pop1()?.into_int_value(); // We assume the table has the `anyfunc` element type. @@ -4388,6 +4464,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4396,6 +4473,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { 4, )?; let result = builder.build_load(effective_address, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + result.as_instruction_value().unwrap(), + Some(0), + ); state.push1(result); } Operator::I64Load { ref memarg } => { @@ -4403,6 +4487,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4411,6 +4496,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { 8, )?; let result = builder.build_load(effective_address, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + result.as_instruction_value().unwrap(), + Some(0), + ); state.push1(result); } Operator::F32Load { ref memarg } => { @@ -4418,6 +4510,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4426,6 +4519,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { 4, )?; let result = builder.build_load(effective_address, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + result.as_instruction_value().unwrap(), + Some(0), + ); state.push1(result); } Operator::F64Load { ref memarg } => { @@ -4433,6 +4533,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4441,6 +4542,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { 8, )?; let result = builder.build_load(effective_address, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + result.as_instruction_value().unwrap(), + Some(0), + ); state.push1(result); } Operator::V128Load { ref memarg } => { @@ -4448,6 +4556,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4456,6 +4565,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { 16, )?; let result = builder.build_load(effective_address, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + result.as_instruction_value().unwrap(), + Some(0), + ); state.push1(result); } @@ -4465,6 +4581,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4472,7 +4589,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i32_ptr_ty, 4, )?; - builder.build_store(effective_address, value); + let store = builder.build_store(effective_address, value); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I64Store { ref memarg } => { let value = state.pop1()?; @@ -4480,6 +4598,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4487,7 +4606,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i64_ptr_ty, 8, )?; - builder.build_store(effective_address, value); + let store = builder.build_store(effective_address, value); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::F32Store { ref memarg } => { let (v, i) = state.pop1_extra()?; @@ -4496,6 +4616,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4503,7 +4624,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.f32_ptr_ty, 4, )?; - builder.build_store(effective_address, v); + let store = builder.build_store(effective_address, v); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::F64Store { ref memarg } => { let (v, i) = state.pop1_extra()?; @@ -4512,6 +4634,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4519,7 +4642,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.f64_ptr_ty, 8, )?; - builder.build_store(effective_address, v); + let store = builder.build_store(effective_address, v); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::V128Store { ref memarg } => { let (v, i) = state.pop1_extra()?; @@ -4528,6 +4652,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4535,14 +4660,15 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i128_ptr_ty, 16, )?; - builder.build_store(effective_address, v); + let store = builder.build_store(effective_address, v); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } - Operator::I32Load8S { ref memarg } => { let effective_address = resolve_memory_ptr( builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4553,6 +4679,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); state.push1(result); @@ -4562,6 +4695,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4569,11 +4703,19 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i16_ptr_ty, 2, )?; - let narrow_result = builder - .build_load(effective_address, &state.var_name()) - .into_int_value(); - let result = - builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); + let narrow_result = builder.build_load(effective_address, &state.var_name()); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); + let result = builder.build_int_s_extend( + narrow_result.into_int_value(), + intrinsics.i32_ty, + &state.var_name(), + ); state.push1(result); } Operator::I64Load8S { ref memarg } => { @@ -4581,6 +4723,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4591,6 +4734,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -4600,6 +4750,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4610,6 +4761,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -4619,6 +4777,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4629,6 +4788,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -4639,6 +4805,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4649,6 +4816,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); state.push1(result); @@ -4658,6 +4832,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4668,6 +4843,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); state.push1(result); @@ -4677,6 +4859,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4687,6 +4870,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -4696,6 +4886,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4706,6 +4897,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -4715,6 +4913,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4725,6 +4924,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { let narrow_result = builder .build_load(effective_address, &state.var_name()) .into_int_value(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + narrow_result.as_instruction_value().unwrap(), + Some(0), + ); let result = builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -4736,6 +4942,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4745,7 +4952,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { )?; let narrow_value = builder.build_int_truncate(value, intrinsics.i8_ty, &state.var_name()); - builder.build_store(effective_address, narrow_value); + let store = builder.build_store(effective_address, narrow_value); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => { let value = state.pop1()?.into_int_value(); @@ -4753,6 +4961,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4762,7 +4971,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { )?; let narrow_value = builder.build_int_truncate(value, intrinsics.i16_ty, &state.var_name()); - builder.build_store(effective_address, narrow_value); + let store = builder.build_store(effective_address, narrow_value); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I64Store32 { ref memarg } => { let value = state.pop1()?.into_int_value(); @@ -4770,6 +4980,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -4779,7 +4990,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { )?; let narrow_value = builder.build_int_truncate(value, intrinsics.i32_ty, &state.var_name()); - builder.build_store(effective_address, narrow_value); + let store = builder.build_store(effective_address, narrow_value); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I8x16Neg => { let (v, i) = state.pop1_extra()?; @@ -5074,6 +5286,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5081,11 +5294,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i8_ptr_ty, 1, )?; - let elem = builder.build_load(effective_address, "").into_int_value(); + let elem = builder.build_load(effective_address, ""); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + elem.as_instruction_value().unwrap(), + Some(0), + ); let res = splat_vector( builder, intrinsics, - elem.as_basic_value_enum(), + elem, intrinsics.i8x16_ty, &state.var_name(), ); @@ -5097,6 +5317,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5104,11 +5325,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i16_ptr_ty, 2, )?; - let elem = builder.build_load(effective_address, "").into_int_value(); + let elem = builder.build_load(effective_address, ""); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + elem.as_instruction_value().unwrap(), + Some(0), + ); let res = splat_vector( builder, intrinsics, - elem.as_basic_value_enum(), + elem, intrinsics.i16x8_ty, &state.var_name(), ); @@ -5120,6 +5348,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5127,11 +5356,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i32_ptr_ty, 4, )?; - let elem = builder.build_load(effective_address, "").into_int_value(); + let elem = builder.build_load(effective_address, ""); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + elem.as_instruction_value().unwrap(), + Some(0), + ); let res = splat_vector( builder, intrinsics, - elem.as_basic_value_enum(), + elem, intrinsics.i32x4_ty, &state.var_name(), ); @@ -5143,6 +5379,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5150,11 +5387,18 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { intrinsics.i64_ptr_ty, 8, )?; - let elem = builder.build_load(effective_address, "").into_int_value(); + let elem = builder.build_load(effective_address, ""); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + elem.as_instruction_value().unwrap(), + Some(0), + ); let res = splat_vector( builder, intrinsics, - elem.as_basic_value_enum(), + elem, intrinsics.i64x2_ty, &state.var_name(), ); @@ -5175,6 +5419,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5195,6 +5440,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(4).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); state.push1(result); } Operator::I64AtomicLoad { ref memarg } => { @@ -5202,6 +5448,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5222,6 +5469,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(8).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); state.push1(result); } Operator::I32AtomicLoad8U { ref memarg } => { @@ -5229,6 +5477,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5251,6 +5500,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(1).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); let result = builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); state.push1(result); @@ -5260,6 +5510,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5282,6 +5533,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(2).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); let result = builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); state.push1(result); @@ -5291,6 +5543,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5313,6 +5566,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(1).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); let result = builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -5322,6 +5576,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5344,6 +5599,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(2).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); let result = builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -5353,6 +5609,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5375,6 +5632,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { load.set_alignment(4).unwrap(); load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", load, Some(0)); let result = builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); state.push1(result); @@ -5385,6 +5643,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5405,6 +5664,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { store .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I64AtomicStore { ref memarg } => { let value = state.pop1()?; @@ -5412,6 +5672,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5432,6 +5693,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { store .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => { let value = state.pop1()?.into_int_value(); @@ -5439,6 +5701,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5461,6 +5724,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { store .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I32AtomicStore16 { ref memarg } | Operator::I64AtomicStore16 { ref memarg } => { @@ -5469,6 +5733,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5491,6 +5756,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { store .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I64AtomicStore32 { ref memarg } => { let value = state.pop1()?.into_int_value(); @@ -5498,6 +5764,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5520,6 +5787,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { store .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) .unwrap(); + tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0)); } Operator::I32AtomicRmw8UAdd { ref memarg } => { let value = state.pop1()?.into_int_value(); @@ -5527,6 +5795,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5552,6 +5821,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -5561,6 +5837,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5586,6 +5863,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -5595,6 +5879,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5618,6 +5903,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I64AtomicRmw8UAdd { ref memarg } => { @@ -5626,6 +5918,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5651,6 +5944,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -5660,6 +5960,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5685,6 +5986,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -5694,6 +6002,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5719,6 +6028,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -5728,6 +6044,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5751,6 +6068,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I32AtomicRmw8USub { ref memarg } => { @@ -5759,6 +6083,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5784,6 +6109,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -5793,6 +6125,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5818,6 +6151,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -5827,6 +6167,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5850,6 +6191,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I64AtomicRmw8USub { ref memarg } => { @@ -5858,6 +6206,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5883,6 +6232,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -5892,6 +6248,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5917,6 +6274,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -5926,6 +6290,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5951,6 +6316,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -5960,6 +6332,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -5983,6 +6356,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I32AtomicRmw8UAnd { ref memarg } => { @@ -5991,6 +6371,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6016,6 +6397,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6025,6 +6413,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6050,6 +6439,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6059,6 +6455,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6082,6 +6479,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I64AtomicRmw8UAnd { ref memarg } => { @@ -6090,6 +6494,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6115,6 +6520,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6124,6 +6536,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6149,6 +6562,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6158,6 +6578,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6183,6 +6604,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6192,6 +6620,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6215,6 +6644,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I32AtomicRmw8UOr { ref memarg } => { @@ -6223,6 +6659,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6248,6 +6685,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6257,6 +6701,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6282,6 +6727,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6291,6 +6743,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6314,6 +6767,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6323,6 +6783,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6348,6 +6809,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6357,6 +6825,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6382,6 +6851,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6391,6 +6867,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6416,6 +6893,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6425,6 +6909,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6448,6 +6933,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I32AtomicRmw8UXor { ref memarg } => { @@ -6456,6 +6948,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6481,6 +6974,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6490,6 +6990,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6515,6 +7016,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6524,6 +7032,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6547,6 +7056,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I64AtomicRmw8UXor { ref memarg } => { @@ -6555,6 +7071,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6580,6 +7097,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6589,6 +7113,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6614,6 +7139,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6623,6 +7155,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6648,6 +7181,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6657,6 +7197,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6680,6 +7221,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I32AtomicRmw8UXchg { ref memarg } => { @@ -6688,6 +7236,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6713,6 +7262,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6722,6 +7278,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6747,6 +7304,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i32_ty, &state.var_name()); state.push1(old); } @@ -6756,6 +7320,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6779,6 +7344,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I64AtomicRmw8UXchg { ref memarg } => { @@ -6787,6 +7359,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6812,6 +7385,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6821,6 +7401,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6846,6 +7427,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6855,6 +7443,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6880,6 +7469,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_int_z_extend(old, intrinsics.i64_ty, &state.var_name()); state.push1(old); } @@ -6889,6 +7485,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6912,6 +7509,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); state.push1(old); } Operator::I32AtomicRmw8UCmpxchg { ref memarg } => { @@ -6921,6 +7525,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6949,6 +7554,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder .build_extract_value(old, 0, "") .unwrap() @@ -6963,6 +7575,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -6991,6 +7604,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder .build_extract_value(old, 0, "") .unwrap() @@ -7005,6 +7625,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -7029,6 +7650,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_extract_value(old, 0, "").unwrap(); state.push1(old); } @@ -7039,6 +7667,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -7067,6 +7696,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder .build_extract_value(old, 0, "") .unwrap() @@ -7081,6 +7717,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -7109,6 +7746,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder .build_extract_value(old, 0, "") .unwrap() @@ -7123,6 +7767,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -7151,6 +7796,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder .build_extract_value(old, 0, "") .unwrap() @@ -7165,6 +7817,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { builder, intrinsics, context, + self.module.clone(), &function, &mut state, &mut ctx, @@ -7189,6 +7842,13 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { AtomicOrdering::SequentiallyConsistent, ) .unwrap(); + tbaa_label( + self.module.clone(), + intrinsics, + "memory", + old.as_instruction_value().unwrap(), + Some(0), + ); let old = builder.build_extract_value(old, 0, "").unwrap(); state.push1(old); } @@ -7350,22 +8010,20 @@ impl ModuleCodeGenerator Some(Linkage::External), ); - let signatures = Map::new(); - LLVMModuleCodeGenerator { context: Some(context), builder: Some(builder), intrinsics: Some(intrinsics), - module, + module: Rc::new(RefCell::new(module)), functions: vec![], - signatures, + signatures: Map::new(), signatures_raw: Map::new(), function_signatures: None, func_import_count: 0, personality_func, stackmaps: Rc::new(RefCell::new(StackmapRegistry::default())), track_state: false, - target_machine: target_machine, + target_machine, } } @@ -7399,7 +8057,7 @@ impl ModuleCodeGenerator [FuncIndex::new(self.func_import_count + self.functions.len())]; 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()), self.signatures[sig_id], Some(Linkage::External), @@ -7472,6 +8130,7 @@ impl ModuleCodeGenerator index: local_func_index, opcode_offset: 0, track_state: self.track_state, + module: self.module.clone(), }; self.functions.push(code); Ok(self.functions.last_mut().unwrap()) @@ -7500,7 +8159,7 @@ impl ModuleCodeGenerator generate_trampolines( module_info, &self.signatures, - &self.module, + &self.module.borrow_mut(), self.context.as_ref().unwrap(), self.builder.as_ref().unwrap(), self.intrinsics.as_ref().unwrap(), @@ -7510,13 +8169,14 @@ impl ModuleCodeGenerator })?; 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(()); if cfg!(test) { pass_manager.add_verifier_pass(); } + pass_manager.add_type_based_alias_analysis_pass(); pass_manager.add_lower_expect_intrinsic_pass(); pass_manager.add_scalar_repl_aggregates_pass(); pass_manager.add_instruction_combining_pass(); @@ -7530,16 +8190,16 @@ impl ModuleCodeGenerator pass_manager.add_cfg_simplification_pass(); pass_manager.add_bit_tracking_dce_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 } { - self.module.print_to_file(path).unwrap(); + self.module.borrow_mut().print_to_file(path).unwrap(); } let stackmaps = self.stackmaps.borrow(); let (backend, cache_gen) = LLVMBackend::new( - self.module, + self.module.clone(), self.intrinsics.take().unwrap(), &*stackmaps, module_info, diff --git a/lib/llvm-backend/src/intrinsics.rs b/lib/llvm-backend/src/intrinsics.rs index 9fb668f1a..1e87a9251 100644 --- a/lib/llvm-backend/src/intrinsics.rs +++ b/lib/llvm-backend/src/intrinsics.rs @@ -7,12 +7,15 @@ use inkwell::{ BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType, }, values::{ - BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue, VectorValue, + BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue, + MetadataValue, PointerValue, VectorValue, }, AddressSpace, }; +use std::cell::RefCell; use std::collections::HashMap; use std::marker::PhantomData; +use std::rc::Rc; use wasmer_runtime_core::{ memory::MemoryType, module::ModuleInfo, @@ -658,7 +661,12 @@ impl<'a> CtxType<'a> { ptr } - pub fn memory(&mut self, index: MemoryIndex, intrinsics: &Intrinsics) -> MemoryCache { + pub fn memory( + &mut self, + index: MemoryIndex, + intrinsics: &Intrinsics, + module: Rc>, + ) -> MemoryCache { let (cached_memories, info, ctx_ptr_value, cache_builder) = ( &mut self.cached_memories, self.info, @@ -667,7 +675,7 @@ impl<'a> CtxType<'a> { ); *cached_memories.entry(index).or_insert_with(|| { - let (memory_array_ptr_ptr, index, memory_type, minimum, maximum) = + let (memory_array_ptr_ptr, index, memory_type, minimum, maximum, field_name) = match index.local_or_import(info) { LocalOrImport::Local(local_mem_index) => ( unsafe { @@ -681,6 +689,7 @@ impl<'a> CtxType<'a> { info.memories[local_mem_index].memory_type(), info.memories[local_mem_index].minimum, info.memories[local_mem_index].maximum, + "context_field_ptr_to_local_memory", ), LocalOrImport::Import(import_mem_index) => ( unsafe { @@ -694,12 +703,20 @@ impl<'a> CtxType<'a> { info.imported_memories[import_mem_index].1.memory_type(), info.imported_memories[import_mem_index].1.minimum, info.imported_memories[import_mem_index].1.maximum, + "context_field_ptr_to_imported_memory", ), }; let memory_array_ptr = cache_builder .build_load(memory_array_ptr_ptr, "memory_array_ptr") .into_pointer_value(); + tbaa_label( + module.clone(), + intrinsics, + field_name, + memory_array_ptr.as_instruction_value().unwrap(), + None, + ); let const_index = intrinsics.i32_ty.const_int(index, false); let memory_ptr_ptr = unsafe { cache_builder.build_in_bounds_gep( @@ -711,6 +728,13 @@ impl<'a> CtxType<'a> { let memory_ptr = cache_builder .build_load(memory_ptr_ptr, "memory_ptr") .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 { ( @@ -726,16 +750,34 @@ impl<'a> CtxType<'a> { minimum, maximum, }, - MemoryType::Static | MemoryType::SharedStatic => MemoryCache::Static { - base_ptr: cache_builder + MemoryType::Static | MemoryType::SharedStatic => { + let base_ptr = cache_builder .build_load(ptr_to_base_ptr, "base") - .into_pointer_value(), - bounds: cache_builder + .into_pointer_value(); + let bounds = cache_builder .build_load(ptr_to_bounds, "bounds") - .into_int_value(), - minimum, - maximum, - }, + .into_int_value(); + tbaa_label( + module.clone(), + intrinsics, + "static_memory_base", + base_ptr.as_instruction_value().unwrap(), + Some(index as u32), + ); + tbaa_label( + module.clone(), + intrinsics, + "static_memory_bounds", + bounds.as_instruction_value().unwrap(), + Some(index as u32), + ); + MemoryCache::Static { + base_ptr, + bounds, + minimum, + maximum, + } + } } }) } @@ -744,6 +786,7 @@ impl<'a> CtxType<'a> { &mut self, index: TableIndex, intrinsics: &Intrinsics, + module: Rc>, ) -> (PointerValue, PointerValue) { let (cached_tables, info, ctx_ptr_value, cache_builder) = ( &mut self.cached_tables, @@ -756,7 +799,7 @@ impl<'a> CtxType<'a> { ptr_to_base_ptr, ptr_to_bounds, } = *cached_tables.entry(index).or_insert_with(|| { - let (table_array_ptr_ptr, index) = match index.local_or_import(info) { + let (table_array_ptr_ptr, index, field_name) = match index.local_or_import(info) { LocalOrImport::Local(local_table_index) => ( unsafe { cache_builder.build_struct_gep( @@ -766,6 +809,7 @@ impl<'a> CtxType<'a> { ) }, local_table_index.index() as u64, + "context_field_ptr_to_local_table", ), LocalOrImport::Import(import_table_index) => ( unsafe { @@ -776,12 +820,20 @@ impl<'a> CtxType<'a> { ) }, import_table_index.index() as u64, + "context_field_ptr_to_import_table", ), }; let table_array_ptr = cache_builder .build_load(table_array_ptr_ptr, "table_array_ptr") .into_pointer_value(); + tbaa_label( + module.clone(), + intrinsics, + field_name, + table_array_ptr.as_instruction_value().unwrap(), + None, + ); let const_index = intrinsics.i32_ty.const_int(index, false); let table_ptr_ptr = unsafe { cache_builder.build_in_bounds_gep(table_array_ptr, &[const_index], "table_ptr_ptr") @@ -789,6 +841,13 @@ impl<'a> CtxType<'a> { let table_ptr = cache_builder .build_load(table_ptr_ptr, "table_ptr") .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 { ( @@ -810,15 +869,30 @@ impl<'a> CtxType<'a> { &mut self, index: TableIndex, intrinsics: &Intrinsics, + module: Rc>, builder: &Builder, ) -> (PointerValue, IntValue) { - let (ptr_to_base_ptr, ptr_to_bounds) = self.table_prepare(index, intrinsics); - ( - builder - .build_load(ptr_to_base_ptr, "base_ptr") - .into_pointer_value(), - builder.build_load(ptr_to_bounds, "bounds").into_int_value(), - ) + let (ptr_to_base_ptr, ptr_to_bounds) = + self.table_prepare(index, intrinsics, module.clone()); + let base_ptr = builder + .build_load(ptr_to_base_ptr, "base_ptr") + .into_pointer_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( @@ -826,6 +900,7 @@ impl<'a> CtxType<'a> { index: LocalFuncIndex, fn_ty: FunctionType, intrinsics: &Intrinsics, + module: Rc>, builder: &Builder, ) -> PointerValue { let local_func_array_ptr_ptr = unsafe { @@ -838,6 +913,13 @@ impl<'a> CtxType<'a> { let local_func_array_ptr = builder .build_load(local_func_array_ptr_ptr, "local_func_array_ptr") .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 { builder.build_in_bounds_gep( local_func_array_ptr, @@ -848,6 +930,13 @@ impl<'a> CtxType<'a> { let local_func_ptr = builder .build_load(local_func_ptr_ptr, "local_func_ptr") .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( local_func_ptr, fn_ty.ptr_type(AddressSpace::Generic), @@ -889,7 +978,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>, + ) -> GlobalCache { let (cached_globals, ctx_ptr_value, info, cache_builder) = ( &mut self.cached_globals, self.ctx_ptr_value, @@ -898,7 +992,7 @@ impl<'a> CtxType<'a> { ); *cached_globals.entry(index).or_insert_with(|| { - let (globals_array_ptr_ptr, index, mutable, wasmer_ty) = + let (globals_array_ptr_ptr, index, mutable, wasmer_ty, field_name) = match index.local_or_import(info) { LocalOrImport::Local(local_global_index) => { let desc = info.globals[local_global_index].desc; @@ -913,6 +1007,7 @@ impl<'a> CtxType<'a> { local_global_index.index() as u64, desc.mutable, desc.ty, + "context_field_ptr_to_local_globals", ) } LocalOrImport::Import(import_global_index) => { @@ -928,6 +1023,7 @@ impl<'a> CtxType<'a> { import_global_index.index() as u64, desc.mutable, desc.ty, + "context_field_ptr_to_imported_globals", ) } }; @@ -937,6 +1033,13 @@ impl<'a> CtxType<'a> { let global_array_ptr = cache_builder .build_load(globals_array_ptr_ptr, "global_array_ptr") .into_pointer_value(); + tbaa_label( + module.clone(), + intrinsics, + field_name, + globals_array_ptr_ptr.as_instruction_value().unwrap(), + None, + ); let const_index = intrinsics.i32_ty.const_int(index, false); let global_ptr_ptr = unsafe { cache_builder.build_in_bounds_gep( @@ -948,6 +1051,13 @@ impl<'a> CtxType<'a> { let global_ptr = cache_builder .build_load(global_ptr_ptr, "global_ptr") .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 = cache_builder.build_pointer_cast(global_ptr, llvm_ptr_ty, "global_ptr_typed"); @@ -957,9 +1067,15 @@ impl<'a> CtxType<'a> { ptr_to_value: global_ptr_typed, } } else { - GlobalCache::Const { - value: cache_builder.build_load(global_ptr_typed, "global_value"), - } + let 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 } } }) } @@ -968,6 +1084,7 @@ impl<'a> CtxType<'a> { &mut self, index: ImportedFuncIndex, intrinsics: &Intrinsics, + module: Rc>, ) -> (PointerValue, PointerValue) { let (cached_imported_functions, ctx_ptr_value, cache_builder) = ( &mut self.cached_imported_functions, @@ -986,6 +1103,13 @@ impl<'a> CtxType<'a> { let func_array_ptr = cache_builder .build_load(func_array_ptr_ptr, "func_array_ptr") .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 imported_func_ptr = unsafe { cache_builder.build_in_bounds_gep( @@ -1007,6 +1131,20 @@ impl<'a> CtxType<'a> { let ctx_ptr = cache_builder .build_load(ctx_ptr_ptr, "ctx_ptr") .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 } }); @@ -1018,6 +1156,7 @@ impl<'a> CtxType<'a> { &mut self, index: usize, intrinsics: &Intrinsics, + module: Rc>, builder: &Builder, ) -> PointerValue { assert!(index < INTERNALS_SIZE); @@ -1032,6 +1171,13 @@ impl<'a> CtxType<'a> { let local_internals_ptr = builder .build_load(local_internals_ptr_ptr, "local_internals_ptr") .into_pointer_value(); + tbaa_label( + module.clone(), + intrinsics, + "context_field_ptr_to_internals", + local_internals_ptr_ptr.as_instruction_value().unwrap(), + None, + ); unsafe { builder.build_in_bounds_gep( local_internals_ptr, @@ -1041,3 +1187,83 @@ impl<'a> CtxType<'a> { } } } + +// Given an instruction that operates on memory, mark the access as not aliasing +// other memory accesses which have a different (label, index) pair. +pub fn tbaa_label( + module: Rc>, + intrinsics: &Intrinsics, + label: &str, + instruction: InstructionValue, + index: Option, +) { + // To convey to LLVM that two pointers must be pointing to distinct memory, + // we use LLVM's Type Based Aliasing Analysis, or TBAA, to mark the memory + // operations as having different types whose pointers may not alias. + // + // See the LLVM documentation at + // https://llvm.org/docs/LangRef.html#tbaa-metadata + // + // LLVM TBAA supports many features, but we use it in a simple way, with + // only scalar types that are children of the root node. Every TBAA type we + // declare is NoAlias with the others. See NoAlias, PartialAlias, + // MayAlias and MustAlias in the LLVM documentation: + // https://llvm.org/docs/AliasAnalysis.html#must-may-and-no-alias-responses + + let module = module.borrow_mut(); + let context = module.get_context(); + + // `!wasmer_tbaa_root = {}`, the TBAA root node for wasmer. + let tbaa_root = module + .get_global_metadata("wasmer_tbaa_root") + .pop() + .unwrap_or_else(|| { + module.add_global_metadata("wasmer_tbaa_root", &MetadataValue::create_node(&[])); + module.get_global_metadata("wasmer_tbaa_root")[0] + }); + + // Construct (or look up) the type descriptor, for example + // `!"local 0" = !{!"local 0", !wasmer_tbaa_root}`. + let label = if let Some(idx) = index { + format!("{}{}", label, idx) + } else { + label.to_string() + }; + let type_label = context.metadata_string(label.as_str()); + let type_tbaa = module + .get_global_metadata(label.as_str()) + .pop() + .unwrap_or_else(|| { + module.add_global_metadata( + label.as_str(), + &MetadataValue::create_node(&[type_label.into(), tbaa_root.into()]), + ); + module.get_global_metadata(label.as_str())[0] + }); + + // Construct (or look up) the access tag, which is a struct of the form + // (base type, access type, offset). + // + // "If BaseTy is a scalar type, Offset must be 0 and BaseTy and AccessTy + // must be the same". + // -- https://llvm.org/docs/LangRef.html#tbaa-metadata + let label = label + "_memop"; + let type_tbaa = module + .get_global_metadata(label.as_str()) + .pop() + .unwrap_or_else(|| { + module.add_global_metadata( + label.as_str(), + &MetadataValue::create_node(&[ + type_tbaa.into(), + type_tbaa.into(), + intrinsics.i64_zero.into(), + ]), + ); + module.get_global_metadata(label.as_str())[0] + }); + + // Attach the access tag to the instruction. + let tbaa_kind = context.get_kind_id("tbaa"); + instruction.set_metadata(type_tbaa, tbaa_kind); +}