[wasm] [JIT]: Enable more GC-ref local candidates by introducing spilling

Aperta
#136,663 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
42/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
csharp, wasm

Direzione di ricerca

Read PR #135543 and trace how Wasm local candidates are selected and how GC safepoints treat references. The issue gives an example in System.SpanHelpers.IndexOfAny, where a GC reference could stay in a local if it is spilled to a pinned safe slot before a call. Done means enabling profitable GC reference locals with spills that preserve GC correctness; the issue names no implementation files or tests.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

arch-wasm area-CodeGen-coreclr tenet-performance

https://github.com/dotnet/runtime/pull/135543 introduced GC refs as Wasm local candidates, but only if they are never live across a GC safepoint. We could consider pushing further and allowing GC refs to be local candidates if it is profitable -- inserting spills as necessary to maintain GC correctness. Take the following instruction sequence from
int System.SpanHelpers.IndexOfAny<__Canon>(ref __Canon, __Canon, __Canon, int) as an example:
This is part of computing

lookUp.Equals(value0)

with T lookup; T value0 where T: IEquatable<T>?


 00BF:                       i32.load align=1
 00C2:                       i32.store align=1 offset=12 ;; spill value0
 00C5:                       local.get 0
 00C7:                       i32.load align=1 offset=12 ;; load value0 for nullcheck
 00CA:                       i32.eqz
 00CB:                       br_if 0
;; call setup for a future call to `Equals`
 00CD:                      local.get 0
 00CF:                       local.get 0
 00D1:                       i32.load align=1 offset=12  ;; load value0
 00D4:                       local.get 0
 00D6:                       i32.load align=1 offset=20 ;; load lookUp
;; setup + call for System.IEquatable lookup
 00D9:                       local.get 0
 00DB:                       local.get 1
 00DD:                       global.get 1 // imageBase
 00DF:                       i32.load align=1 offset=6860860 // METHOD_DICTIONARY_LOOKUP: System.IEquatable`1<mvar #0> (TYPE_HANDLE)
 00E5:                       local.tee 67
 00E7:                       local.get 67
 00E9:                       i32.load align=1
 00EC:                       call_indirect 0 (type 59) 
... 

In this case, the slot SP+12 is a gc ref. Notice that we update its value and store it at 00C2, before loading it multiple times at 00C7 and 00D1, with no GC safepoint in between. If we assigned this ref to a local instead, we could delete the loads but keep the initial spill for GC correctness, and we'd instead have:

i32.load align=1
local.tee <ref> ;; tee ref value0 into a local home
i32.store align=1 offset=12 ;; spill to pinned "safe slot"
local.get <ref> ;; load value0 from local home
i32.eqz
br_if 0
local.get 0
local.get <ref> ;; load value0 from local home
local.get 0
i32.load align=1 offset=20
local.get 0
local.get 1
global.get 1 // imageBase
i32.load align=1 offset=6860860 // METHOD_DICTIONARY_LOOKUP: System.IEquatable`1<mvar #0> (TYPE_HANDLE)
local.tee 67
local.get 67
i32.load align=1
call_indirect 0 (type 59)
;; local <ref> is safe to use since it was spilled to a pinned slot previously before the call

which has 1 net fewer instruction and less stack traffic.

Lingua principale
C#
Stelle
18.4k
Fork
5.8k
Merge medio
2g 12h
PR unite (30g)
600

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di dotnet/runtime

Tutte le issue di dotnet/runtime

Issue simili

Altre issue su C#

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.