
#14880: GHC panic: updateRole -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: goldfire Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (Type | Version: 8.2.2 checker) | Resolution: | Keywords: TypeInType Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #15076 | Differential Rev(s): Phab:D4769 Wiki Page: | -------------------------------------+------------------------------------- Comment (by tdammers): Yes, that's essentially what I have. Specifically: {{{#!haskell tcvs_of_type' :: Type -> TyCoVarSetNotClosed -> TyCoVarSetNotClosed tcvs_of_type' (TyVarTy v) = flip extendVarSet v tcvs_of_type' (TyConApp _ tys) = tcvs_of_types' tys tcvs_of_type' (LitTy {}) = id tcvs_of_type' (AppTy fun arg) = tcvs_of_type' fun . tcvs_of_type' arg tcvs_of_type' (FunTy arg res) = tcvs_of_type' arg . tcvs_of_type' res tcvs_of_type' (ForAllTy (TvBndr tv _) ty) = unionVarSet (delVarSet (tcvs_of_type ty) tv) . tcvs_of_type' (tyVarKind tv) tcvs_of_type' (CastTy ty co) = tcvs_of_type' ty . tcvs_of_co' co tcvs_of_type' (CoercionTy co) = tcvs_of_co' co tcvs_of_types :: [Type] -> TyCoVarSetNotClosed tcvs_of_types ts = tcvs_of_types' ts emptyVarSet tcvs_of_types' :: [Type] -> TyCoVarSetNotClosed -> TyCoVarSetNotClosed tcvs_of_types' [] = id tcvs_of_types' (t:ts) = tcvs_of_type' t . tcvs_of_types' ts tcvs_of_co :: Coercion -> TyCoVarSetNotClosed tcvs_of_co co = tcvs_of_co' co emptyVarSet tcvs_of_co' :: Coercion -> TyCoVarSetNotClosed -> TyCoVarSetNotClosed tcvs_of_co' (Refl _ ty) = tcvs_of_type' ty tcvs_of_co' (TyConAppCo _ _ cos) = tcvs_of_cos' cos tcvs_of_co' (AppCo co arg) = tcvs_of_co' co . tcvs_of_co' arg tcvs_of_co' (ForAllCo tv kind_co co) = unionVarSet (delVarSet (tcvs_of_co co) tv) . tcvs_of_co' kind_co tcvs_of_co' (FunCo _ co1 co2) = tcvs_of_co' co1 . tcvs_of_co' co2 tcvs_of_co' (CoVarCo v) = flip extendVarSet v tcvs_of_co' (HoleCo h) = flip extendVarSet (coHoleCoVar h) -- See Note [CoercionHoles and coercion free variables] tcvs_of_co' (AxiomInstCo _ _ cos) = tcvs_of_cos' cos tcvs_of_co' (UnivCo p _ t1 t2) = tcvs_of_prov' p . tcvs_of_type' t1 . tcvs_of_type' t2 tcvs_of_co' (SymCo co) = tcvs_of_co' co tcvs_of_co' (TransCo co1 co2) = tcvs_of_co' co1 . tcvs_of_co' co2 tcvs_of_co' (NthCo _ _ co) = tcvs_of_co' co tcvs_of_co' (LRCo _ co) = tcvs_of_co' co tcvs_of_co' (InstCo co arg) = tcvs_of_co' co . tcvs_of_co' arg tcvs_of_co' (CoherenceCo c1 c2) = tcvs_of_co' c1 . tcvs_of_co' c2 tcvs_of_co' (KindCo co) = tcvs_of_co' co tcvs_of_co' (SubCo co) = tcvs_of_co' co tcvs_of_co' (AxiomRuleCo _ cos) = tcvs_of_cos' cos tcvs_of_cos :: [Coercion] -> TyCoVarSetNotClosed tcvs_of_cos co = tcvs_of_cos' co emptyVarSet tcvs_of_cos' :: [Coercion] -> TyCoVarSetNotClosed -> TyCoVarSetNotClosed tcvs_of_cos' [] = id tcvs_of_cos' (co:cos) = tcvs_of_co' co . tcvs_of_cos' cos -- tcvs_of_prov :: UnivCoProvenance -> TyCoVarSetNotClosed -- tcvs_of_prov p = tcvs_of_prov' p emptyVarSet tcvs_of_prov' :: UnivCoProvenance -> TyCoVarSetNotClosed -> TyCoVarSetNotClosed tcvs_of_prov' UnsafeCoerceProv = id tcvs_of_prov' (PhantomProv co) = tcvs_of_co' co tcvs_of_prov' (ProofIrrelProv co) = tcvs_of_co' co tcvs_of_prov' (PluginProv _) = id }}} So the `'`-ed versions are the ones with an accumulator; I kept the original ones around but rewrote them in terms of the accumulator version so that other functions that depend on them keep working unchanged. Apart from the forall cases, everything goes through the accumulator version, and uses only single-var insertions and no unions. I also rewrote the plural ones (`tcvs_of_cos` / `tcvs_of_types`) to avoid unions there. The only real difference I can see here is that I used point-free style over parentheses, but that surely ought not to make a difference. There is a slight performance improvement over the union-based version, but not enough to explain the test failures, and it's still nowhere near the original numbers. To wit: Pre-patch: {{{ /home/tobias/well-typed/devel/ghc-phab/inplace/lib/bin/ghc-stage2 -B/home/tobias/well-typed/devel/ghc-phab/inplace/lib -c testsuite/tests/perf/compiler/T5631.hs -fforce-recomp +RTS -rlogs/old.ticky STACK USAGE: ENTERS: 51211603 of which 51211603 (100.0%) direct to the entry code [the rest indirected via Node's info ptr] 6192996 ( 12.1%) thunks 3676345 ( 7.2%) data values 0 ( 0.0%) normal indirections 0 ( 0.0%) permanent indirections FUNCTION ENTRIES: 41342262 TAIL CALLS: 33149658, of which 27886423 (84%) were to known functions SLOW APPLICATIONS: 0 evaluated, 0 unevaluated Too few args Correct args Too many args FUN 0 0 0 PAP 0 0 0 RETURNS: 23002648 11895484 ( 51.7%) from entering a new constructor [the rest from entering an existing constructor] RET_NEW: 11895484: 36.3% 13.5% 24.9% 4.5% 19.1% 0.9% 0.3% 0.2% 0.4% RET_OLD: 3676345: 11.6% 18.6% 18.8% 5.7% 6.3% 20.5% 0.3% 1.1% 17.1% RET_UNBOXED_TUP: 7430819: 0.0% 68.9% 29.7% 1.2% 0.1% 0.0% 0.1% 0.1% 0.0% }}} Post-patch: {{{ /home/tobias/well-typed/devel/ghc-phab/inplace/lib/bin/ghc-stage2 -B/home/tobias/well-typed/devel/ghc-phab/inplace/lib -c testsuite/tests/perf/compiler/T5631.hs -fforce-recomp +RTS -rlogs/new.ticky STACK USAGE: ENTERS: 54717036 of which 54717036 (100.0%) direct to the entry code [the rest indirected via Node's info ptr] 6198335 ( 11.3%) thunks 4824139 ( 8.8%) data values 0 ( 0.0%) normal indirections 0 ( 0.0%) permanent indirections FUNCTION ENTRIES: 43694562 TAIL CALLS: 35496964, of which 29883207 (84%) were to known functions SLOW APPLICATIONS: 0 evaluated, 0 unevaluated Too few args Correct args Too many args FUN 0 0 0 PAP 0 0 0 RETURNS: 24705888 13776908 ( 55.8%) from entering a new constructor [the rest from entering an existing constructor] RET_NEW: 13776908: 36.0% 11.6% 25.9% 3.9% 21.1% 0.8% 0.2% 0.1% 0.3% RET_OLD: 4824139: 23.8% 14.1% 20.4% 4.4% 7.6% 15.6% 0.3% 0.9% 13.0% RET_UNBOXED_TUP: 6104841: 0.0% 83.5% 14.8% 1.4% 0.1% 0.0% 0.1% 0.1% 0.0% }}} Post-patch with rewritten `tcvs...` functions: {{{ /home/tobias/well-typed/devel/ghc-phab/inplace/lib/bin/ghc-stage2 -B/home/tobias/well-typed/devel/ghc-phab/inplace/lib -c testsuite/tests/perf/compiler/T5631.hs -fforce-recomp +RTS -rlogs/new- accum.ticky STACK USAGE: ENTERS: 54394961 of which 54394961 (100.0%) direct to the entry code [the rest indirected via Node's info ptr] 6198336 ( 11.4%) thunks 4906771 ( 9.0%) data values 0 ( 0.0%) normal indirections 0 ( 0.0%) permanent indirections FUNCTION ENTRIES: 43289854 TAIL CALLS: 35075741, of which 29461984 (84%) were to known functions SLOW APPLICATIONS: 0 evaluated, 0 unevaluated Too few args Correct args Too many args FUN 0 0 0 PAP 0 0 0 RETURNS: 24431674 13420062 ( 54.9%) from entering a new constructor [the rest from entering an existing constructor] RET_NEW: 13420062: 32.7% 11.9% 25.9% 4.0% 24.0% 0.8% 0.2% 0.1% 0.4% RET_OLD: 4906771: 26.3% 13.9% 17.1% 4.3% 9.2% 15.3% 0.3% 0.9% 12.8% RET_UNBOXED_TUP: 6104841: 0.0% 83.5% 14.8% 1.4% 0.1% 0.0% 0.1% 0.1% 0.0% }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14880#comment:52 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler