KEMBAR78
NativeAOT codegen optimization opportunities · Issue #64242 · dotnet/runtime · GitHub
Skip to content

NativeAOT codegen optimization opportunities #64242

@MichalStrehovsky

Description

@MichalStrehovsky

(Note this is milestoned as Future on purpose - none of this is blocking.)

A couple relatively low hanging optimization opportunities in the JIT space.

  • Enable loop alignment
    Loop alignment seems to have some pretty nice benefits. NativeAOT/crossgen2 will already respect requests to align at 32-byte boundaries (Add support in crossgen2 for 32-byte alignment #32602), but RyuJIT never requests that for prejit. RyuJIT seems to also have assumptions that the code buffer to write instructions into is 32-byte aligned. It's a managed byte[] in our AOT compilers and it's hard to align that. RyuJIT should ideally count bytes from the beginning of the buffer.
  • Optimize static field access
    Static fields always go through a helper call. It can be done better. Improve static field access for NativeAOT #63620 is a WIP pull request. I don't know when I'll get back to it.
  • Optimize class constructor checks - NativeAOT: Inline static initialization checks in codegen #80954
    If there's a static constructor, the EE side will ask RyuJIT to run the class constructor check (CORINFO_INITCLASS_USE_HELPER). This is a helper call that checks whether the class constructor already ran and if not, runs it. The helper looks like this:
    // We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
    encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeNonGCStaticsSymbol(target), -NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
    AddrMode initialized = new AddrMode(encoder.TargetRegister.Arg0, null, factory.Target.PointerSize, 0, AddrModeSize.Int32);
    encoder.EmitCMP(ref initialized, 1);
    encoder.EmitRETIfEqual();
    encoder.EmitMOV(encoder.TargetRegister.Arg1, encoder.TargetRegister.Result);
    encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase));
    . We could inline the fast path into RyuJIT codegen (compare a dereferenced IConHandle with 1 and if they're equal, the cctor already executed and we can move on). This would probably require a new JitInteface method that provides info about lookup for the IConHandle and lookup for the helper to call if the IConHandle is not 1. There already is a pull request that does pretty much that: RyuJIT: Inlined "is class statically inited" check #47901. We need to revive it for NativeAOT.
  • Optimize thread static field access [NativeAOT] Inline access to thread statics #79521
    Emit the platform-specific native sequence to access thread statics inline instead of calling a helper.
  • Reading preinitialized data JIT: import static readonly fields holding frozen objects as const handles #76112
    NativeAOT can run static constructors at compile time and provide values of readonly static fields. RyuJIT can already consume that (see code around CORINFO_FLG_FIELD_FINAL), but in doing so it assumes the address returned from getFieldAddress is an actual address that can be dereferenced. It's a handle when precompiling. We would want to introduce a proper JitInterface API for this. The static data preinitializer can return more than just primitive types - we could also make this work for reference types (we can return a handle that points to an object in the frozen data segment). Might be better to look into this after "Optimize static field access" above is done.
  • Devirtualization
    The compiler driver has a pretty good idea of what types will be allocated over the lifetime of the app. It can provide answers to questions such as "what are all the types that could implement this interface". This can be used to drive devirtualization. Some of it doesn't really even have to be guarded (there might only be a single possibility, for example).
  • General optimizations

Cc @EgorBo - might be in your area of interest

category:cq
theme:ready-to-run
skill-level:expert
cost:medium
impact:medium

Metadata

Metadata

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions