Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[mono] Use SROA-friendly struct type declarations (#59007)
LLVM's SROA can decompose loads and stores of aggregate type into a sequence of aggregate-element-typed loads and stores. Before this change, Mono translated .NET-level value types into LLVM IR-level structs containing nothing but `i8` elements. When a value type field has reference type, and a value of this value type is copied using a `memcpy` intrinsic or an LLVM IR load followed by a store, LLVM will emit code that loads managed references in multiple byte-sized fragments before reconstructing the original pointer using a sequence of ALU ops. This causes sgen to fail to pin the referent. This change works around this by translating value types to LLVM IR structs with pointer-sized fields. Packed value types with non-standard alignment will be translated into LLVM IR structs containing alignment-sized fields. Note that this does not completely guarantee that the code we generate will respect sgen's requirements. No specific guarantees are provided about the translation of non-atomic LLVM IR loads and stores to machine code. And we'll need some alternative means (perhaps a special `gc_copy_unaligned` runtime call or similar) to copy packed or misaligned value types that contain managed references. For stronger LLVM IR-level guarantees, we'll want to make use of unordered atomic loads and stores and unordered atomic memcpy, but that work is out of scope for this change. Fixes #58062, but see the previous paragraph for caveats. See: - https://github.com/dotnet/llvm-project/blob/release/11.x/llvm/lib/Transforms/Scalar/SROA.cpp#L3371-L3388 - https://github.com/dotnet/llvm-project/blob/release/11.x/llvm/lib/Transforms/Scalar/SROA.cpp#L3327-L3340
- Loading branch information