Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC

Commits:

10 changed files:

Changes:

  • compiler/GHC/Core/Coercion/Opt.hs
    1 1
     -- (c) The University of Glasgow 2006
    
    2 2
     {-# LANGUAGE CPP #-}
    
    3 3
     
    
    4
    -module GHC.Core.Coercion.Opt( optCoProgram, optCoRefl )
    
    5
    -where
    
    4
    +module GHC.Core.Coercion.Opt( optCoProgram, optCoRefl ) where
    
    6 5
     
    
    7 6
     import GHC.Prelude
    
    8 7
     
    
    ... ... @@ -28,7 +27,6 @@ import GHC.Data.Pair
    28 27
     import GHC.Data.TrieMap
    
    29 28
     
    
    30 29
     import GHC.Utils.Outputable
    
    31
    -import GHC.Utils.Constants (debugIsOn)
    
    32 30
     import GHC.Utils.Misc
    
    33 31
     import GHC.Utils.Panic
    
    34 32
     
    
    ... ... @@ -195,44 +193,50 @@ We use the following invariants:
    195 193
     %*                                                                      *
    
    196 194
     %********************************************************************* -}
    
    197 195
     
    
    198
    -optCoProgram :: CoreProgram -> CoreProgram
    
    196
    +optCoProgram :: Bool   -- True <=> do extra checks/tracking
    
    197
    +             -> CoreProgram -> CoreProgram
    
    199 198
     -- Apply optCoercion to all coercions in /expressions/
    
    200 199
     -- There may also be coercions in /types/ but we `optCoProgram` doesn't
    
    201 200
     -- look at them; they are typically fewer and smaller, and it doesn't seem
    
    202 201
     -- worth the cost of traversing and rebuilding all the types in the program.
    
    203
    -optCoProgram binds
    
    202
    +optCoProgram do_checks binds
    
    204 203
       = map go binds
    
    205 204
       where
    
    206
    -    go (NonRec b r) = NonRec b (optCoExpr in_scope r)
    
    207
    -    go (Rec prs)    = Rec (mapSnd (optCoExpr in_scope) prs)
    
    205
    +    go (NonRec b r) = NonRec b (optCoExpr (do_checks, in_scope) r)
    
    206
    +    go (Rec prs)    = Rec (mapSnd (optCoExpr (do_checks, in_scope)) prs)
    
    207
    +
    
    208 208
         in_scope = mkInScopeSetList (bindersOfBinds binds)
    
    209 209
            -- Put all top-level binders into scope; it is possible to have
    
    210 210
            -- forward references.  See Note [Glomming] in GHC.Core.Opt.OccurAnal
    
    211 211
     
    
    212
    -optCoExpr :: InScopeSet -> CoreExpr -> CoreExpr
    
    213
    -optCoExpr _ e@(Var {})     = e
    
    214
    -optCoExpr _ e@(Lit {})     = e
    
    215
    -optCoExpr _ e@(Type {})    = e
    
    212
    +optCoExpr :: (Bool, InScopeSet) -> CoreExpr -> CoreExpr
    
    213
    +optCoExpr !_ e@(Var {})    = e
    
    214
    +optCoExpr _  e@(Lit {})    = e
    
    215
    +optCoExpr _  e@(Type {})   = e
    
    216 216
     optCoExpr is (App e1 e2)   = App (optCoExpr is e1) (optCoExpr is e2)
    
    217
    -optCoExpr is (Lam b e)     = Lam b (optCoExpr (is `extendInScopeSet` b) e)
    
    217
    +optCoExpr is (Lam b e)     = Lam b (optCoExpr (is `add_bndr` b) e)
    
    218 218
     optCoExpr is (Coercion co) = Coercion (optCo is co)
    
    219 219
     optCoExpr is (Cast e co)   = Cast (optCoExpr is e) (optCo is co)
    
    220 220
     optCoExpr is (Tick t e)    = Tick t (optCoExpr is e)
    
    221
    -optCoExpr is (Let (NonRec b r) e)  = Let (NonRec b (optCoExpr is r))
    
    222
    -                                         (optCoExpr (is `extendInScopeSet` b) e)
    
    223
    -optCoExpr is (Let (Rec prs)    e)  = Let (Rec (mapSnd (optCoExpr is') prs))
    
    224
    -                                         (optCoExpr is' e)
    
    225
    -                                   where
    
    226
    -                                     is' = is `extendInScopeSetList` map fst prs
    
    227
    -optCoExpr is (Case e b ty alts) = Case (optCoExpr is e) b ty
    
    228
    -                                       (map (optCoAlt (is `extendInScopeSet` b)) alts)
    
    221
    +optCoExpr is (Let (NonRec b r) e) = Let (NonRec b (optCoExpr is r))
    
    222
    +                                        (optCoExpr (is `add_bndr` b) e)
    
    223
    +optCoExpr is (Let (Rec prs)    e) = Let (Rec (mapSnd (optCoExpr is') prs))
    
    224
    +                                        (optCoExpr is' e)
    
    225
    +                                  where
    
    226
    +                                    is' = is `add_bndrs` map fst prs
    
    227
    +optCoExpr is (Case e b ty alts) = Case (optCoExpr is e) b ty (map do_alt alts)
    
    228
    +  where
    
    229
    +     is' = is `add_bndr` b
    
    230
    +     do_alt (Alt k bs e) = Alt k bs (optCoExpr (is' `add_bndrs` bs) e)
    
    229 231
     
    
    230
    -optCo :: InScopeSet -> Coercion -> Coercion
    
    231
    -optCo is co = optCoercion (mkEmptySubst is) co
    
    232
    +add_bndr :: (Bool, InScopeSet) -> Var -> (Bool, InScopeSet)
    
    233
    +add_bndr (do_checks, is) b = (do_checks, is `extendInScopeSet` b)
    
    232 234
     
    
    233
    -optCoAlt :: InScopeSet -> CoreAlt -> CoreAlt
    
    234
    -optCoAlt is (Alt k bs e)
    
    235
    -  = Alt k bs (optCoExpr (is `extendInScopeSetList` bs) e)
    
    235
    +add_bndrs :: (Bool, InScopeSet) -> [Var] -> (Bool, InScopeSet)
    
    236
    +add_bndrs (do_checks, is) bs = (do_checks, is `extendInScopeSetList` bs)
    
    237
    +
    
    238
    +optCo :: (Bool, InScopeSet) -> Coercion -> Coercion
    
    239
    +optCo (do_checks, is) co = optCoercionChecking do_checks (mkEmptySubst is) co
    
    236 240
     
    
    237 241
     
    
    238 242
     {- **********************************************************************
    
    ... ... @@ -260,8 +264,8 @@ optCoAlt is (Alt k bs e)
    260 264
     optCoRefl :: Bool -> Subst -> Coercion -> Coercion
    
    261 265
     -- See Note [optCoRefl]
    
    262 266
     optCoRefl check_stuff subst in_co
    
    263
    -  | isEmptyTCvSubst subst = in_co
    
    264
    -  | not check_stuff       = opt_co_refl subst in_co
    
    267
    +  | not check_stuff
    
    268
    +  = opt_co_refl subst in_co
    
    265 269
       | otherwise  -- Do expensive checks
    
    266 270
       = let out_co = opt_co_refl subst in_co
    
    267 271
             (Pair in_l in_r) = coercionKind in_co
    
    ... ... @@ -271,22 +275,29 @@ optCoRefl check_stuff subst in_co
    271 275
             in_co' = substCo subst in_co
    
    272 276
             in_sz = coercionSize in_co'
    
    273 277
             out_sz = coercionSize out_co
    
    274
    -    in if not ((in_l' `eqType` out_l) && (in_r' `eqType` out_r))
    
    275
    -       then pprTrace "Yikes: optReflCo changes type"
    
    276
    -               (vcat [ text "in_l':"  <+> ppr in_l'
    
    277
    -                     , text "in_r':"  <+> ppr in_r'
    
    278
    -                     , text "out_l:" <+> ppr out_l
    
    279
    -                     , text "out_r:" <+> ppr out_r
    
    280
    -                     , text "in_co:" <+> ppr in_co
    
    281
    -                     , text "out_co:" <+> ppr out_co ]) $
    
    282
    -            out_co
    
    283
    -       else if out_sz < in_sz
    
    284
    -            then pprTrace "optCoRefl: size reduction:"
    
    285
    -                   (vcat [ int in_sz <+> text "-->" <+> int out_sz
    
    286
    -                         , text "in_co':" <+> ppr in_co'
    
    287
    -                         , text "out_co:" <+> ppr out_co ]) $
    
    288
    -                 out_co
    
    289
    -       else out_co
    
    278
    +
    
    279
    +        details = setPprDebug False $
    
    280
    +                  vcat [ text "in_l':"  <+> ppr in_l'
    
    281
    +                       , text "in_r':"  <+> ppr in_r'
    
    282
    +                       , text "out_l:" <+> ppr out_l
    
    283
    +                       , text "out_r:" <+> ppr out_r
    
    284
    +                       , text "in_co:" <+> ppr in_co
    
    285
    +                       , text "out_co:" <+> ppr out_co ]
    
    286
    +
    
    287
    +    in pprTraceWhen (not ((in_l' `eqTypeIgnoringMultiplicity` out_l) &&
    
    288
    +                          (in_r' `eqTypeIgnoringMultiplicity` out_r)))
    
    289
    +          "Yikes: optReflCo changes type" details $
    
    290
    +
    
    291
    +       pprTraceWhen (out_sz > in_sz)
    
    292
    +          "Yikes: optReflCo makes coercion bigger"
    
    293
    +          (vcat [ int in_sz <+> text "-->" <+> int out_sz
    
    294
    +                , whenPprDebug details ]) $
    
    295
    +
    
    296
    +       pprTraceWhen (in_sz > out_sz)
    
    297
    +            "optCoRefl: size reduction:"
    
    298
    +            (vcat [ int in_sz <+> text "-->" <+> int out_sz
    
    299
    +                  , whenPprDebug details ])
    
    300
    +       out_co
    
    290 301
     
    
    291 302
     opt_co_refl :: Subst -> InCoercion -> OutCoercion
    
    292 303
     opt_co_refl subst co = go co
    
    ... ... @@ -308,16 +319,18 @@ opt_co_refl subst co = go co
    308 319
         go (HoleCo h)                    = HoleCo $!! go_hole h
    
    309 320
         go (SymCo co)                    = mkSymCo $!! go co
    
    310 321
         go (KindCo co)                   = mkKindCo $!! go co
    
    311
    -    go (SubCo co)                    = mkSubCo $!! go co
    
    322
    +    go (SubCo co)                    = mkSubCo $!! (let co' = go co in
    
    323
    +                                                    if isReflexiveCo co' && not (isReflCo co')
    
    324
    +                                                    then pprTrace "yuike" (ppr co $$ ppr co') co'
    
    325
    +                                                    else co')
    
    312 326
         go (SelCo n co)                  = mkSelCo n $!! go co
    
    313
    -    go (LRCo n co)                   = mkLRCo n $!! go co
    
    314
    -    go (AppCo co1 co2)               = mkAppCo  $!! go co1 $!! go co2
    
    315
    -    go (InstCo co1 co2)              = mkInstCo $!! go co1 $!! go co2
    
    327
    +    go (LRCo n co)                   = mkLRCo n  $!! go co
    
    328
    +    go (AppCo co1 co2)               = mkAppCo   $!! go co1 $!! go co2
    
    329
    +    go (InstCo co1 co2)              = mkInstCo  $!! go co1 $!! go co2
    
    316 330
         go (FunCo r afl afr com coa cor) = mkFunCo2 r afl afr
    
    317 331
                                                $!! go com $!! go coa $!! go cor
    
    318 332
         go (TyConAppCo r tc cos)         = mkTyConAppCo r tc $!! go_s cos
    
    319
    -    go (UnivCo p r lt rt cos)        = mkUnivCo p $!! (go_s cos) $!! r
    
    320
    -                                                  $!! (go_ty lt) $!! (go_ty rt)
    
    333
    +    go (UnivCo p r lt rt cos)        = optUnivCo p $!! go_s cos $!! r $!! go_ty lt $!! go_ty rt
    
    321 334
         go (AxiomCo ax cos)              = mkAxiomCo ax $!! (go_s cos)
    
    322 335
     
    
    323 336
         go (ForAllCo v vl vr mco co)     = mkForAllCo v' vl vr
    
    ... ... @@ -354,25 +367,53 @@ opt_co_refl subst co = go co
    354 367
     data GobbleState = GS OutCoercion (TypeMap GobbleState)
    
    355 368
                        -- The map is keyed by OutType
    
    356 369
     
    
    370
    +optUnivCo :: UnivCoProvenance -> [Coercion]
    
    371
    +          -> Role -> Type -> Type -> Coercion
    
    372
    +optUnivCo prov cos role lty rty
    
    373
    +  | lty `eqTypeIgnoringMultiplicity` rty
    
    374
    +      -- We only Lint multiplicities in the output of the typechecker, as
    
    375
    +      -- described in Note [Linting linearity] in GHC.Core.Lint. This means
    
    376
    +      -- we can use 'eqTypeIgnoringMultiplicity' instead of 'eqType' below.
    
    377
    +      --
    
    378
    +      -- In particular, this gets rid of 'SubMultProv' coercions that were
    
    379
    +      -- introduced for typechecking multiplicities of data constructors, as
    
    380
    +      -- described in Note [Typechecking data constructors] in GHC.Tc.Gen.Head.
    
    381
    +  = mkReflCo role lty
    
    382
    +
    
    383
    +  | otherwise
    
    384
    +  = UnivCo { uco_prov = prov, uco_role = role
    
    385
    +           , uco_lty = lty, uco_rty = rty
    
    386
    +           , uco_deps = cos }
    
    387
    +
    
    357 388
     {- **********************************************************************
    
    358 389
     %*                                                                      *
    
    359 390
                         optCoercion
    
    360 391
     %*                                                                      *
    
    361 392
     %********************************************************************* -}
    
    362 393
     
    
    363
    -optCoercion :: Subst -> Coercion -> NormalCo
    
    394
    +optCoercionChecking :: Bool -> Subst -> Coercion -> NormalCo
    
    364 395
     -- ^ optCoercion applies a substitution to a coercion,
    
    365 396
     --   *and* optimises it to reduce its size
    
    366 397
     -- The substitution is a vestige of an earlier era, when the coercion optimiser
    
    367 398
     --   was called by the Simplifier; now it is always empty
    
    368 399
     --   But I have not removed it in case we ever want it back.
    
    369
    -optCoercion env co
    
    370
    -  | debugIsOn
    
    371
    -  = let out_co = opt_co1 lc NotSwapped co
    
    372
    -        (Pair in_ty1  in_ty2,  in_role)  = coercionKindRole co
    
    400
    +optCoercionChecking do_checks subst in_co
    
    401
    +  | not do_checks
    
    402
    +  = optCoercion1 subst in_co
    
    403
    +
    
    404
    +  | otherwise
    
    405
    +  = let out_co = optCoercion1 subst in_co
    
    406
    +
    
    407
    +        (Pair in_ty1  in_ty2,  in_role)  = coercionKindRole in_co
    
    373 408
             (Pair out_ty1 out_ty2, out_role) = coercionKindRole out_co
    
    374 409
     
    
    375
    -        details = vcat [ text "in_co:" <+> ppr co
    
    410
    +        in_co' = substCo subst in_co
    
    411
    +        Pair in_ty1' in_ty2' = coercionKind in_co'
    
    412
    +
    
    413
    +        in_size  = coercionSize in_co'
    
    414
    +        out_size = coercionSize out_co
    
    415
    +
    
    416
    +        details = vcat [ text "in_co:" <+> ppr in_co
    
    376 417
                            , text "in_ty1:" <+> ppr in_ty1
    
    377 418
                            , text "in_ty2:" <+> ppr in_ty2
    
    378 419
                            , text "out_co:" <+> ppr out_co
    
    ... ... @@ -382,22 +423,34 @@ optCoercion env co
    382 423
                            , text "out_role:" <+> ppr out_role
    
    383 424
                            ]
    
    384 425
         in
    
    385
    -    warnPprTrace (not (isReflCo out_co) && isReflexiveCo out_co)
    
    386
    -                 "optCoercion: reflexive but not refl" details $
    
    426
    +    -- Check that the type isn't changed
    
    427
    +    pprTraceWhen (not ((in_ty1' `eqTypeIgnoringMultiplicity` out_ty1) &&
    
    428
    +                       (in_ty2' `eqTypeIgnoringMultiplicity` out_ty2)))
    
    429
    +                 "optCoercion changes type!!!" details $
    
    430
    +
    
    387 431
         -- The coercion optimiser should usually optimise
    
    388 432
         --     co:ty~ty   -->  Refl ty
    
    389 433
         -- But given a silly `newtype N = MkN N`, the axiom has type (N ~ N),
    
    390 434
         -- and so that can trigger this warning (e.g. test str002).
    
    391 435
         -- Maybe we should optimise that coercion to (Refl N), but it
    
    392 436
         -- just doesn't seem worth the bother
    
    393
    -    out_co
    
    437
    +    pprTraceWhen (not (isReflCo out_co) && isReflexiveCo out_co)
    
    438
    +                 "optCoercion: reflexive but not refl" details $
    
    394 439
     
    
    395
    -  | otherwise
    
    396
    -  = opt_co1 lc NotSwapped co
    
    397
    -  where
    
    398
    -    lc = mkSubstLiftingContext env
    
    399
    ---    ppr_one cv = ppr cv <+> dcolon <+> ppr (coVarKind cv)
    
    440
    +    -- Show a trace if the coercion shrinks
    
    441
    +    pprTraceWhen (in_size > out_size)
    
    442
    +       "optCoercion:size reduction"
    
    443
    +       (vcat [ int in_size <+> text "-->" <+> int out_size
    
    444
    +             , whenPprDebug      $   -- Show details with -dppr-debug
    
    445
    +               setPprDebug False $
    
    446
    +               details ]) $
    
    447
    +    out_co
    
    400 448
     
    
    449
    +optCoercion1 :: Subst -> Coercion -> NormalCo
    
    450
    +-- Starting point for the coercion optimiser: does no checking
    
    451
    +-- but initialises the substitution and calls opt_co1
    
    452
    +optCoercion1 subst co
    
    453
    +  = opt_co1 (mkSubstLiftingContext subst) NotSwapped co
    
    401 454
     
    
    402 455
     type NormalCo    = Coercion
    
    403 456
       -- Invariants:
    
    ... ... @@ -791,19 +844,7 @@ opt_univ env sym prov deps role ty1 ty2
    791 844
             deps' = map (opt_co1 env sym) deps
    
    792 845
             (ty1'', ty2'') = swapSym sym (ty1', ty2')
    
    793 846
         in
    
    794
    -      -- We only Lint multiplicities in the output of the typechecker, as
    
    795
    -      -- described in Note [Linting linearity] in GHC.Core.Lint. This means
    
    796
    -      -- we can use 'eqTypeIgnoringMultiplicity' instead of 'eqType' below.
    
    797
    -      --
    
    798
    -      -- In particular, this gets rid of 'SubMultProv' coercions that were
    
    799
    -      -- introduced for typechecking multiplicities of data constructors, as
    
    800
    -      -- described in Note [Typechecking data constructors] in GHC.Tc.Gen.Head.
    
    801
    -      if ty1'' `eqTypeIgnoringMultiplicity` ty2''
    
    802
    -      then mkReflCo role ty2''
    
    803
    -      else
    
    804
    -        UnivCo { uco_prov = prov, uco_role = role
    
    805
    -               , uco_lty = ty1'', uco_rty = ty2''
    
    806
    -               , uco_deps = deps' }
    
    847
    +    optUnivCo prov deps' role ty1'' ty2''
    
    807 848
     
    
    808 849
     {-
    
    809 850
     opt_univ env PhantomProv cvs _r ty1 ty2
    

  • compiler/GHC/Core/Opt/Pipeline.hs
    ... ... @@ -135,7 +135,6 @@ getCoreToDo dflags hpt_rule_base extra_vars
    135 135
         strictness    = gopt Opt_Strictness                   dflags
    
    136 136
         full_laziness = gopt Opt_FullLaziness                 dflags
    
    137 137
         do_specialise = gopt Opt_Specialise                   dflags
    
    138
    -    do_co_opt     = gopt Opt_OptCoercion                 dflags
    
    139 138
         do_float_in   = gopt Opt_FloatIn                      dflags
    
    140 139
         cse           = gopt Opt_CSE                          dflags
    
    141 140
         spec_constr   = gopt Opt_SpecConstr                   dflags
    
    ... ... @@ -147,6 +146,8 @@ getCoreToDo dflags hpt_rule_base extra_vars
    147 146
         ww_on         = gopt Opt_WorkerWrapper                dflags
    
    148 147
         static_ptrs   = xopt LangExt.StaticPointers           dflags
    
    149 148
         profiling     = ways dflags `hasWay` WayProf
    
    149
    +    do_co_opt     = gopt Opt_OptCoercion                  dflags
    
    150
    +    opt_co_checks = dopt Opt_D_opt_co                     dflags
    
    150 151
     
    
    151 152
         do_simpl3      = const_fold || rules_on -- TODO: any other optimizations benefit from three-phase simplification?
    
    152 153
     
    
    ... ... @@ -230,7 +231,7 @@ getCoreToDo dflags hpt_rule_base extra_vars
    230 231
             -- Without -O, just take what the desugarer produced
    
    231 232
             -- I tried running it right after desugaring, regardless of -O,
    
    232 233
             -- but that was worse (longer compile times).
    
    233
    -        runWhen do_co_opt CoreOptCoercion,
    
    234
    +        runWhen do_co_opt (CoreOptCoercion opt_co_checks),
    
    234 235
     
    
    235 236
             if full_laziness then
    
    236 237
                CoreDoFloatOutwards $ FloatOutSwitches
    
    ... ... @@ -509,8 +510,8 @@ doCorePass pass guts = do
    509 510
         CoreCSE                   -> {-# SCC "CommonSubExpr" #-}
    
    510 511
                                      updateBinds cseProgram
    
    511 512
     
    
    512
    -    CoreOptCoercion           -> {-# SCC "OptCoercion" #-}
    
    513
    -                                 updateBinds optCoProgram
    
    513
    +    CoreOptCoercion checks    -> {-# SCC "OptCoercion" #-}
    
    514
    +                                 updateBinds (optCoProgram checks)
    
    514 515
     
    
    515 516
         CoreLiberateCase          -> {-# SCC "LiberateCase" #-}
    
    516 517
                                      updateBinds (liberateCase (initLiberateCaseOpts dflags))
    

  • compiler/GHC/Core/Opt/Pipeline/Types.hs
    ... ... @@ -52,7 +52,7 @@ data CoreToDo -- These are diff core-to-core passes,
    52 52
       | CoreDoSpecialising
    
    53 53
       | CoreDoSpecConstr
    
    54 54
       | CoreCSE
    
    55
    -  | CoreOptCoercion  -- Run the coercion optimiser
    
    55
    +  | CoreOptCoercion Bool  -- Run the coercion optimiser
    
    56 56
       | CoreDoRuleCheck CompilerPhase String  -- Check for non-application of rules
    
    57 57
                                            -- matching this string
    
    58 58
       | CoreDoNothing                -- Useful when building up
    
    ... ... @@ -82,7 +82,7 @@ instance Outputable CoreToDo where
    82 82
       ppr CoreDoSpecialising       = text "Specialise"
    
    83 83
       ppr CoreDoSpecConstr         = text "SpecConstr"
    
    84 84
       ppr CoreCSE                  = text "Common sub-expression"
    
    85
    -  ppr CoreOptCoercion          = text "Optimise coercions"
    
    85
    +  ppr (CoreOptCoercion {})     = text "Optimise coercions"
    
    86 86
       ppr CoreDesugar              = text "Desugar (before optimization)"
    
    87 87
       ppr CoreDesugarOpt           = text "Desugar (after optimization)"
    
    88 88
       ppr CoreTidy                 = text "Tidy Core"
    

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -284,8 +284,8 @@ data SimplMode = SimplMode -- See comments in GHC.Core.Opt.Simplify.Monad
    284 284
       , sm_rule_opts :: !RuleOpts
    
    285 285
       , sm_case_folding :: !Bool
    
    286 286
       , sm_case_merge :: !Bool
    
    287
    -  , sm_opt_refl_co :: !Bool
    
    288
    -  , sm_check_opt_co :: !Bool
    
    287
    +  , sm_opt_refl_co :: !Bool           -- Use `optCoRefl` on each coercion
    
    288
    +  , sm_check_opt_co :: !Bool          -- Do debug-checking/tracing in `optCoRefl`
    
    289 289
       }
    
    290 290
     
    
    291 291
     -- | See Note [SimplPhase]
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -1390,10 +1390,18 @@ simplCoercionF env co cont
    1390 1390
     
    
    1391 1391
     simplCoercion :: SimplEnv -> InCoercion -> SimplM OutCoercion
    
    1392 1392
     simplCoercion env co
    
    1393
    -  = do { let out_co | sm_opt_refl_co mode = optCoRefl (sm_check_opt_co mode)
    
    1394
    -                                                      (getTCvSubst env) co
    
    1395
    -                    | otherwise          = substCo env co
    
    1396
    -       ; seqCo out_co `seq` return out_co }
    
    1393
    +  = do { let out_co | sm_opt_refl_co mode
    
    1394
    +                    , not (isEmptyTCvSubst subst) || initial_phase
    
    1395
    +                    = optCoRefl (sm_check_opt_co mode) subst co
    
    1396
    +                    | otherwise
    
    1397
    +                    = substCo env co
    
    1398
    +             subst = getTCvSubst env
    
    1399
    +             initial_phase = case sePhase env of
    
    1400
    +                               SimplPhase InitialPhase -> True
    
    1401
    +                               _ -> False
    
    1402
    +
    
    1403
    +       ; seqCo out_co `seq`
    
    1404
    +         return out_co }
    
    1397 1405
       where
    
    1398 1406
         mode = seMode env
    
    1399 1407
     
    

  • compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
    ... ... @@ -68,11 +68,11 @@ initSimplMode dflags phase name = SimplMode
    68 68
       , sm_pre_inline = gopt Opt_SimplPreInlining dflags
    
    69 69
       , sm_float_enable = floatEnable dflags
    
    70 70
       , sm_do_eta_reduction = gopt Opt_DoEtaReduction dflags
    
    71
    -  , sm_arity_opts = initArityOpts dflags
    
    72
    -  , sm_rule_opts = initRuleOpts dflags
    
    71
    +  , sm_arity_opts   = initArityOpts dflags
    
    72
    +  , sm_rule_opts    = initRuleOpts dflags
    
    73 73
       , sm_case_folding = gopt Opt_CaseFolding dflags
    
    74
    -  , sm_case_merge = gopt Opt_CaseMerge dflags
    
    75
    -  , sm_opt_refl_co = gopt Opt_OptReflCoercion dflags
    
    74
    +  , sm_case_merge   = gopt Opt_CaseMerge dflags
    
    75
    +  , sm_opt_refl_co  = gopt Opt_OptReflCoercion dflags
    
    76 76
       , sm_check_opt_co = dopt Opt_D_opt_co dflags
    
    77 77
       }
    
    78 78
     
    

  • compiler/GHC/Driver/Flags.hs
    ... ... @@ -641,8 +641,8 @@ data GeneralFlag
    641 641
        | Opt_InlineGenerics
    
    642 642
        | Opt_InlineGenericsAggressively
    
    643 643
        | Opt_StaticArgumentTransformation
    
    644
    -   | Opt_OptCoercion
    
    645
    -   | Opt_OptReflCoercion
    
    644
    +   | Opt_OptCoercion            -- Run the big-hammer coercion optimiser `optCoercion`
    
    645
    +   | Opt_OptReflCoercion        -- Use the cheap "refl" coercion optimiser `optCoRefl`
    
    646 646
        | Opt_CSE
    
    647 647
        | Opt_StgCSE
    
    648 648
        | Opt_StgLiftLams
    

  • compiler/GHC/Driver/Session.hs
    ... ... @@ -2021,7 +2021,6 @@ dynamic_flags_deps = [
    2021 2021
     
    
    2022 2022
          ------ Language flags -------------------------------------------------
    
    2023 2023
      ++ map (mkFlag turnOn  "f"         setExtensionFlag  ) fLangFlagsDeps
    
    2024
    - ++ map (mkFlag turnOff "fno-"      unSetExtensionFlag) fLangFlagsDeps
    
    2025 2024
      ++ map (mkFlag turnOn  "X"         setExtensionFlag  ) xFlagsDeps
    
    2026 2025
      ++ map (mkFlag turnOff "XNo"       unSetExtensionFlag) xFlagsDeps
    
    2027 2026
      ++ map (mkFlag turnOn  "X"         setLanguage       ) languageFlagsDeps
    

  • compiler/GHC/Utils/Outputable.hs
    ... ... @@ -104,7 +104,7 @@ module GHC.Utils.Outputable (
    104 104
             mkUserStyle, cmdlineParserStyle, Depth(..),
    
    105 105
             withUserStyle, withErrStyle,
    
    106 106
     
    
    107
    -        ifPprDebug, whenPprDebug, getPprDebug,
    
    107
    +        ifPprDebug, whenPprDebug, getPprDebug, setPprDebug,
    
    108 108
     
    
    109 109
             bPutHDoc
    
    110 110
         ) where
    
    ... ... @@ -617,6 +617,9 @@ getPprDebug :: IsOutput doc => (Bool -> doc) -> doc
    617 617
     {-# INLINE CONLIKE getPprDebug #-}
    
    618 618
     getPprDebug d = docWithContext $ \ctx -> d (sdocPprDebug ctx)
    
    619 619
     
    
    620
    +setPprDebug :: Bool -> SDoc -> SDoc
    
    621
    +setPprDebug dbg = updSDocContext (\cxt -> cxt { sdocPprDebug = dbg })
    
    622
    +
    
    620 623
     -- | Says what to do with and without -dppr-debug
    
    621 624
     ifPprDebug :: IsOutput doc => doc -> doc -> doc
    
    622 625
     {-# INLINE CONLIKE ifPprDebug #-}
    

  • compiler/GHC/Utils/Trace.hs
    1 1
     -- | Tracing utilities
    
    2 2
     module GHC.Utils.Trace
    
    3 3
       ( pprTrace
    
    4
    +  , pprTraceWhen
    
    4 5
       , pprTraceM
    
    5 6
       , pprTraceDebug
    
    6 7
       , pprTraceIt
    
    ... ... @@ -36,6 +37,10 @@ import GHC.Stack
    36 37
     import Debug.Trace (trace)
    
    37 38
     import Control.Monad.IO.Class
    
    38 39
     
    
    40
    +pprTraceWhen :: Bool -> String -> SDoc -> a -> a
    
    41
    +pprTraceWhen False _   _   x = x
    
    42
    +pprTraceWhen True  str doc x = pprTrace str doc x
    
    43
    +
    
    39 44
     -- | If debug output is on, show some 'SDoc' on the screen
    
    40 45
     pprTrace :: String -> SDoc -> a -> a
    
    41 46
     pprTrace str doc x