Simon Jakobi pushed to branch wip/sjakobi/cgwork-perf-aggregate at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • FINDINGS.md
    ... ... @@ -116,9 +116,36 @@ deliverable.
    116 116
       from `$weqDeBruijnType` + 20.7 % from `splitAppTyNoView_maybe` → the cost is
    
    117 117
       **de Bruijn type-key equality in the solver's TrieMaps**. `rewriteType2`
    
    118 118
       (16.29 %) entered 10.8 % via `TyCon_con`. Cleanly symbolised.
    
    119
    -- `eq_type_expand_ignore` (suite #2) is *not* top in any of the five tests
    
    120
    -  profiled — driven by other type-comparison-heavy tests (candidates: T9872c,
    
    121
    -  T8095, T13719). One more callgrind run would localise it.
    
    119
    +- **`rewriteType2` = `rewrite_one`** (the central rewriter loop) is itself a
    
    120
    +  T9872b driver: 8 top-level `rewrite` calls (← `can_eq_nc`) explode into 1.98 M
    
    121
    +  node-rewrites via the fam-app FINISH-1 re-walk. Body already optimal (one-shot
    
    122
    +  monad, famapp-cache); levers are a cheap per-tyvar rebuild short-circuit (A) and
    
    123
    +  the hard "don't re-walk already-normal sub-structure" (B). Investigation +
    
    124
    +  levers: [[rewriteType2-rewrite-one-tyvar-rebuild-and-famapp-rewalk]] in
    
    125
    +  `~/ghc/todos`.
    
    126
    +- **`ruleMatchTyKiX3` (0.59 %, `SCALES`) is the shared type matcher**, not RULE
    
    127
    +  matching — it is `unify_ty`/`tc_unify_tys` specialized into `ruleMatchTyKiX`.
    
    128
    +  Driver **T9872b**: 897,764 entries, ~86 MB suite-wide alloc (it is *not* a
    
    129
    +  0-alloc walk — it allocates `UM`-monad plumbing). Caller chain
    
    130
    +  `← tc_unify_tys ← $wtc_match_tys`/`reduceTyFamApp_maybe ← rewriteType2`, i.e.
    
    131
    +  type-family rewriting again. Two (A) levers (the dead `()` in the
    
    132
    +  `(UMState,())` result pair; the `CanEqLHS`/`UMEnv` boxing at `uVarOrFam` call
    
    133
    +  sites — `uVarOrFam` is the #3 suite allocator at 158 MB) plus a (B) re-match
    
    134
    +  hypothesis shared with the rewriter:
    
    135
    +  [[unify-matcher-um-monad-pair-and-uvarorfam-boxing]] in `~/ghc/todos`.
    
    136
    +- **`eq_type_expand_ignore` (suite #2, 6.81 %) is resolved**: driver **T8095**
    
    137
    +  (98.7 % of entries — the deep type-family reduction), a 0-alloc structural walk
    
    138
    +  with the `reallyUnsafePtrEquality#` fast path already present (A done). Late-CCS
    
    139
    +  pins **100 %** of callers on a single source line: the *last-resort* Identity
    
    140
    +  rule of `opt_trans_rule` (`Opt.hs:979`, `RedTypeDirRefl`), which runs a full
    
    141
    +  `eqType (coercionLKind co1) (coercionRKind co2)` at every transitivity
    
    142
    +  composition. 251 k checks → 187 M node compares (745× fanout, deep common
    
    143
    +  prefix), and it returns `False` in ≥96 % of calls (mkReflCo entered only 10 k×),
    
    144
    +  so it's ~O(n·depth) wasted re-walking of near-identical endpoint types. (The
    
    145
    +  `assertPpr` at `Opt.hs:779` is compiled out in perf builds — not the culprit.)
    
    146
    +  Investigation + (B) levers (guard the optional check / share endpoint types /
    
    147
    +  reshape chain optimisation): [[opt-trans-rule-identity-eqtype-deep-walk]] in
    
    148
    +  `~/ghc/todos`.
    
    122 149
     
    
    123 150
     ### Interface load/write  (MultiLayerModules)
    
    124 151