Author: | Sergio0694 |
---|---|
Assignees: | - |
Labels: | `area-CodeGen-coreclr`, `area-Tools-ILLink` |
Milestone: | - |
Closed Sergio0694 closed 10 months ago
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.
Author: | Sergio0694 |
---|---|
Assignees: | - |
Labels: | `area-CodeGen-coreclr`, `area-Tools-ILLink` |
Milestone: | - |
Where is the IsPrimitive check in CsWinRT that you expect this optimization to help with?
We're not using it yet, but @jkoritzinsky suggested we could add a branch checking that here so that all primitive value types would be covered, and wouldn't cause the linker to preserve and generate code for everything because it can't statically resolve what the result of that helper type logic is doing. We're basically looking for a way of statically being able to tell if an unconstrained T
type argument is blittable or not.
linker
Do you mean IL linker? IL linker does not analyze instantiated generics.
If you mean AOT compiler, you can replace the IsPrimitive check with inlined check for all primitive types typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte) || ...
(types checks like this are treated as intrinsics) and see whether it is going to produce the expected results.
We're basically looking for a way of statically being able to tell if an unconstrained
T
type argument is blittable or not.
Wouldn't an intrinsic like this:
public class Assembly
{
public bool IsBlittable(Type type);
}
make more sense for this? It being on Assembly would let it respect DisableRuntimeMarshalling
and such.
Overview
We're currently working on AOT support for CsWinRT, and as part of that we're also looking into ways to reduce the binary size footprint, which is currently very large even for very simple applications. One issue we've noticed in particular is the static constructor in the
Marshaler<T>
type which is quite large for value types (we've started doing some work in that area here, but there's plenty more to do). This is because the linker is not able to properly handle all branches, so it just preserves everything, which then ends up compiling a whole bunch of useless code, as can be seen when opening the MSTAT files with sizoscope.It would be beneficial to use
Type.IsPrimitive
as a JIT constant, as we could use that to at least skip the (currently reflection based) path checking for ABI types, which is just completely breaking the flow analysis of the linker. We could then at least avoid that generic size explosion for all primitive types. In general, the more properties onType
were JIT time constants, the we could inform the linker in these cases, but IIsPrimitive
seems like a good place to start, since there's plenty of (commonly used) value types there, and we already know none of them will ever have an ABI type anyway.Codegen
Current codegen on .NET 8 x64 (sharplab):
Expected codegen on .NET 8 x64:
cc. @jkoritzinsky @MichalStrehovsky @EgorBo