Andreas Klebinger pushed to branch wip/andreask/spec_no_float at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -64,7 +64,7 @@ import GHC.Unit.Module.ModGuts
    64 64
     import GHC.Core.Unfold
    
    65 65
     
    
    66 66
     import Data.List( partition )
    
    67
    -import Data.List.NonEmpty ( NonEmpty (..) )
    
    67
    +-- import Data.List.NonEmpty ( NonEmpty (..) )
    
    68 68
     import GHC.Core.Subst (substTickish)
    
    69 69
     
    
    70 70
     {-
    
    ... ... @@ -1277,67 +1277,8 @@ specCase :: SpecEnv
    1277 1277
                       , OutId
    
    1278 1278
                       , [OutAlt]
    
    1279 1279
                       , UsageDetails)
    
    1280
    -specCase env scrut' case_bndr [Alt con args rhs]
    
    1281
    -  | -- See Note [Floating dictionaries out of cases]
    
    1282
    -    interestingDict scrut' (idType case_bndr)
    
    1283
    -  , not (isDeadBinder case_bndr && null sc_args')
    
    1284
    -  = do { case_bndr_flt :| sc_args_flt <- mapM clone_me (case_bndr' :| sc_args')
    
    1285
    -
    
    1286
    -       ; let case_bndr_flt' = case_bndr_flt `addDictUnfolding` scrut'
    
    1287
    -             scrut_bind     = mkDB (NonRec case_bndr_flt scrut')
    
    1288
    -
    
    1289
    -             sc_args_flt' = zipWith addDictUnfolding sc_args_flt sc_rhss
    
    1290
    -             sc_rhss      = [ Case (Var case_bndr_flt') case_bndr' (idType sc_arg')
    
    1291
    -                                   [Alt con args' (Var sc_arg')]
    
    1292
    -                            | sc_arg' <- sc_args' ]
    
    1293
    -             cb_set       = unitVarSet case_bndr_flt'
    
    1294
    -             sc_binds     = [ DB { db_bind = NonRec sc_arg_flt sc_rhs, db_fvs  = cb_set }
    
    1295
    -                            | (sc_arg_flt, sc_rhs) <- sc_args_flt' `zip` sc_rhss ]
    
    1296
    -
    
    1297
    -             flt_binds    = scrut_bind : sc_binds
    
    1298
    -
    
    1299
    -             -- Extend the substitution for RHS to map the *original* binders
    
    1300
    -             -- to their floated versions.
    
    1301
    -             mb_sc_flts :: [Maybe DictId]
    
    1302
    -             mb_sc_flts = map (lookupVarEnv clone_env) args'
    
    1303
    -             clone_env  = zipVarEnv sc_args' sc_args_flt'
    
    1304
    -
    
    1305
    -             subst_prs  = (case_bndr, Var case_bndr_flt)
    
    1306
    -                        : [ (arg, Var sc_flt)
    
    1307
    -                          | (arg, Just sc_flt) <- args `zip` mb_sc_flts ]
    
    1308
    -             subst'   = se_subst env_rhs
    
    1309
    -                        `Core.extendSubstInScopeList` (case_bndr_flt' : sc_args_flt')
    
    1310
    -                        `Core.extendIdSubstList`      subst_prs
    
    1311
    -             env_rhs' = env_rhs { se_subst = subst' }
    
    1312
    -
    
    1313
    -       ; (rhs', rhs_uds)   <- specExpr env_rhs' rhs
    
    1314
    -       ; let (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds
    
    1315
    -             all_uds = flt_binds `consDictBinds` free_uds
    
    1316
    -             alt'    = Alt con args' (wrapDictBindsE dumped_dbs rhs')
    
    1317
    ---       ; pprTrace "specCase" (ppr case_bndr $$ ppr scrut_bind) $
    
    1318
    -       ; return (Var case_bndr_flt, case_bndr', [alt'], all_uds) }
    
    1319
    -  where
    
    1320
    -    (env_rhs, (case_bndr':|args')) = substBndrs env (case_bndr:|args)
    
    1321
    -    sc_args' = filter is_flt_sc_arg args'
    
    1322
    -
    
    1323
    -    clone_me bndr = do { uniq <- getUniqueM
    
    1324
    -                       ; return (mkUserLocalOrCoVar occ uniq wght ty loc) }
    
    1325
    -       where
    
    1326
    -         name = idName bndr
    
    1327
    -         wght = idMult bndr
    
    1328
    -         ty   = idType bndr
    
    1329
    -         occ  = nameOccName name
    
    1330
    -         loc  = getSrcSpan name
    
    1331
    -
    
    1332
    -    arg_set = mkVarSet args'
    
    1333
    -    is_flt_sc_arg var =  isId var
    
    1334
    -                      && not (isDeadBinder var)
    
    1335
    -                      && isDictTy var_ty
    
    1336
    -                      && tyCoVarsOfType var_ty `disjointVarSet` arg_set
    
    1337
    -       where
    
    1338
    -         var_ty = idType var
    
    1339
    -
    
    1340
    -
    
    1280
    +-- We used to float out super class selections here,
    
    1281
    +-- but no longer do so. See Historical Note [Floating dictionaries out of cases]
    
    1341 1282
     specCase env scrut case_bndr alts
    
    1342 1283
       = do { (alts', uds_alts) <- mapAndCombineSM spec_alt alts
    
    1343 1284
            ; return (scrut, case_bndr', alts', uds_alts) }
    
    ... ... @@ -1414,36 +1355,36 @@ Note [tryRules: plan (BEFORE)] in the Simplifier (partly) redundant. That is,
    1414 1355
     if we run rules in the specialiser, does it matter if we make rules "win" over
    
    1415 1356
     inlining in the Simplifier?  Yes, it does!  See the discussion in #21851.
    
    1416 1357
     
    
    1417
    -Note [Floating dictionaries out of cases]
    
    1418
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1419
    -Consider
    
    1358
    +Historical Note [Floating dictionaries out of cases]
    
    1359
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1360
    +Function `specCase` used to give special treatment to a case-expression
    
    1361
    +that scrutinised a dictionary, like this:
    
    1420 1362
        g = \d. case d of { MkD sc ... -> ...(f sc)... }
    
    1421
    -Naively we can't float d2's binding out of the case expression,
    
    1422
    -because 'sc' is bound by the case, and that in turn means we can't
    
    1423
    -specialise f, which seems a pity.
    
    1424
    -
    
    1425
    -So we invert the case, by floating out a binding
    
    1426
    -for 'sc_flt' thus:
    
    1427
    -    sc_flt = case d of { MkD sc ... -> sc }
    
    1428
    -Now we can float the call instance for 'f'.  Indeed this is just
    
    1429
    -what'll happen if 'sc' was originally bound with a let binding,
    
    1430
    -but case is more efficient, and necessary with equalities. So it's
    
    1431
    -good to work with both.
    
    1432
    -
    
    1433
    -You might think that this won't make any difference, because the
    
    1434
    -call instance will only get nuked by the \d.  BUT if 'g' itself is
    
    1435
    -specialised, then transitively we should be able to specialise f.
    
    1436
    -
    
    1437
    -In general, given
    
    1438
    -   case e of cb { MkD sc ... -> ...(f sc)... }
    
    1439
    -we transform to
    
    1440
    -   let cb_flt = e
    
    1441
    -       sc_flt = case cb_flt of { MkD sc ... -> sc }
    
    1442
    -   in
    
    1443
    -   case cb_flt of bg { MkD sc ... -> ....(f sc_flt)... }
    
    1444
    -
    
    1445
    -The "_flt" things are the floated binds; we use the current substitution
    
    1446
    -to substitute sc -> sc_flt in the RHS
    
    1363
    +But actually
    
    1364
    +
    
    1365
    +* We never explicitly case-analyse a dictionary; rather the class-op
    
    1366
    +  rules select superclasses from it.  (NB: worker/wrapper can unbox
    
    1367
    +  tuple dictionaries -- see (DNB1) in Note [Do not unbox class dictionaries];
    
    1368
    +  but that's only after worker/wrapper, and specialisation happens before
    
    1369
    +  that.)
    
    1370
    +
    
    1371
    +* Calling `interestingDict` on every scrutinee is hardly sensible;
    
    1372
    +  generally `interestingDict` is called only on Constraint-kinded things.
    
    1373
    +
    
    1374
    +* It was giving a Lint scope error in !14272
    
    1375
    +
    
    1376
    +So now there is no special case. This Note just records the change
    
    1377
    +in case we ever want to reinstate it.   The original note was
    
    1378
    +added in
    
    1379
    +
    
    1380
    +   commit c107a00ccf1e641a2d008939cf477c71caa028d5
    
    1381
    +   Author: Simon Peyton Jones <simonpj@microsoft.com>
    
    1382
    +   Date:   Thu Aug 12 13:11:33 2010 +0000
    
    1383
    +
    
    1384
    +       Improve the Specialiser, fixing Trac #4203
    
    1385
    +
    
    1386
    +End of Historical Note
    
    1387
    +
    
    1447 1388
     
    
    1448 1389
     ************************************************************************
    
    1449 1390
     *                                                                      *