| ... |
... |
@@ -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
|
|