sheaf pushed to branch wip/T26878 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -304,58 +304,58 @@ mkCast expr co
    304 304
     ********************************************************************* -}
    
    305 305
     
    
    306 306
     -- | Wraps the given expression in the source annotation, dropping the
    
    307
    +-- annotation if possible.  So
    
    308
    +--   mkTick t e = Tick t e
    
    309
    +-- except that we may optimise by pushing `t` inwards or dropping it
    
    307 310
     mkTick :: CoreTickish -> CoreExpr -> CoreExpr
    
    308
    -mkTick :: CoreTickish -> CoreExpr -> CoreExpr
    
    311
    +mkTick t orig_expr = mkTick' orig_expr
    
    309 312
      where
    
    310 313
       -- Some ticks (cost-centres) can be split in two, with the
    
    311 314
       -- non-counting part having laxer placement properties.
    
    312
    -  -- non-counting part having laxer placement properties.
    
    315
    +  can_split = tickishCanSplit t
    
    313 316
     
    
    314
    -
    
    315
    -  -- mkTick' handles floating of ticks *into* the expression.
    
    316
    -  mkTick' :: (CoreExpr -> CoreExpr) -- Apply before adding tick (float with)
    
    317
    -                                    -- Always a composition of (Tick t) wrappers
    
    318
    -          -> CoreExpr               -- Current expression
    
    319
    -          -> CoreExpr
    
    320
    -          -- So in the call (mkTick' rest e), the expression
    
    321
    -          --   (rest e)
    
    322
    -          -- has the same type as e
    
    323
    -          -- Returns an expression equivalent to (Tick t (rest e))
    
    324
    -  mkTick' rest expr = case expr of
    
    325
    -    -- Float ticks into unsafe coerce the same way we would do with a cast.
    
    326
    -    Case scrut bndr ty alts@[Alt ac abs _rhs]
    
    327
    -      | Just rhs <- isUnsafeEqualityCase scrut bndr alts
    
    317
    +  stop_here e = Tick t e   -- Just wrap `t` around the current expression
    
    318
    +                           -- That's the default option!
    
    328 319
     
    
    329
    -
    
    330
    -    -- Cost centre ticks should never be reordered relative to each
    
    320
    +  -- mkTick' handles floating of tick `t` *into* the expression.
    
    321
    +  mkTick' :: CoreExpr -> CoreExpr
    
    322
    +  mkTick' expr = case expr of
    
    331 323
         Tick t2 e
    
    332
    -    Tick t2 e
    
    324
    +      | ProfNote { profNoteCC = cc1, profNoteCount = cnt1, profNoteScope = scope1 } <- t
    
    325
    +      , ProfNote { profNoteCC = cc2, profNoteCount = cnt2, profNoteScope = scope2 } <- t2
    
    326
    +      ->
    
    327
    +        -- If the two ticks share the same cost centre and at most one of them
    
    328
    +        -- counts, then we can merge the two.
    
    329
    +        if cc1 == cc2 && (not cnt1 || not cnt2)
    
    330
    +        then
    
    331
    +          let t' = ProfNote { profNoteCC    = cc1
    
    332
    +                            , profNoteCount = cnt1 || cnt2
    
    333
    +                            , profNoteScope = scope1 || scope2
    
    334
    +                            }
    
    335
    +          in mkTick t' expr
    
    336
    +        else
    
    337
    +          -- Cost centre ticks for different cost centres should never be reordered
    
    338
    +          -- relative to each other. Therefore we can stop whenever two collide.
    
    339
    +          stop_here expr
    
    340
    +
    
    341
    +      | tickishPlace t2 /= tickishPlace t
    
    342
    +      -> -- Otherwise, we assume that ticks of different
    
    343
    +         -- placements float through each other.
    
    344
    +         Tick t2 $ mkTick' e
    
    345
    +
    
    346
    +      -- For source note ticks, this is where we make sure to
    
    347
    +      -- not introduce redundant ticks.
    
    348
    +      | tickishContains t t2 -> mkTick' e  -- Drop t2
    
    349
    +      | tickishContains t2 t -> expr       -- Drop t
    
    333 350
     
    
    334
    -
    
    335
    -    -- Otherwise we assume that ticks of different placements float
    
    336
    -    -- through each other.
    
    337
    -      | tickishPlace t2 /= tickishPlace t -> Tick t2 $ mkTick' rest e
    
    338
    -
    
    339
    -    -- For annotations this is where we make sure to not introduce
    
    340
    -    -- redundant ticks.
    
    341
    -      | tickishContains t t2              -> mkTick' rest e  -- Drop t2
    
    342
    -      | tickishContains t2 t              -> rest e          -- Drop t
    
    343
    -      | otherwise                         -> mkTick' (rest . Tick t2) e
    
    344
    -
    
    345
    -    -- Ticks don't care about types, so we just float all ticks
    
    346
    -    -- through them. Note that it's not enough to check for these
    
    347
    -    -- cases top-level. While mkTick will never produce Core with type
    
    348
    -    -- expressions below ticks, such constructs can be the result of
    
    349
    -    -- unfoldings. We therefore make an effort to put everything into
    
    350
    -    -- the right place no matter what we start with.
    
    351
    -    Cast e co   -> mkCast (mkTick' rest e) co
    
    351
    +      | otherwise
    
    352
    +      -> stop_here expr   -- Always safe
    
    352 353
     
    
    353 354
         Lam x e
    
    354 355
           -- Always float through type lambdas. Even for non-type lambdas,
    
    355 356
           -- floating is allowed for all but the most strict placement rule.
    
    356 357
           | not (isRuntimeVar x) || tickishPlace t /= PlaceRuntime
    
    357
    -      | not (isRuntimeVar x) || tickishPlace t /= PlaceRuntime
    
    358
    +      -> Lam x $ mkTick' e
    
    358 359
     
    
    359 360
           -- If it is both counting and scoped, we split the tick into its
    
    360 361
           -- two components, often allowing us to keep the counting tick on
    
    ... ... @@ -363,26 +363,41 @@ mkTick t orig_expr = mkTick' id orig_expr
    363 363
           -- The point of this is that the counting tick can probably be
    
    364 364
           -- floated, and the lambda may then be in a position to be
    
    365 365
           -- beta-reduced.
    
    366
    -      | canSplit
    
    367
    -      -> Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
    
    366
    +      | can_split
    
    367
    +      -> Tick (mkNoScope t) $ Lam x $ mkTick (mkNoCount t) e
    
    368 368
     
    
    369 369
         App f arg
    
    370 370
           -- Always float through type applications.
    
    371 371
           | not (isRuntimeArg arg)
    
    372
    -      -> App (mkTick' rest f) arg
    
    372
    +      -> App (mkTick' f) arg
    
    373 373
     
    
    374 374
           -- We can also float through constructor applications, placement
    
    375 375
           -- permitting. Again we can split.
    
    376
    -      | isSaturatedConApp expr && (tickishPlace t==PlaceCostCentre || canSplit)
    
    376
    +      | isSaturatedConApp expr
    
    377
    +      , tickishPlace t == PlaceCostCentre || can_split
    
    377 378
           -> if tickishPlace t == PlaceCostCentre
    
    378
    -         then rest $ tickHNFArgs t expr
    
    379
    -         else Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
    
    379
    +         then tickHNFArgs t expr
    
    380
    +         else Tick (mkNoScope t) $ tickHNFArgs (mkNoCount t) expr
    
    381
    +
    
    382
    +    -- Ticks don't care about types, so we just float all ticks
    
    383
    +    -- through them. Note that it's not enough to check for these
    
    384
    +    -- cases at the top-level. While mkTick will never produce Core with type
    
    385
    +    -- expressions below ticks, such constructs can be the result of
    
    386
    +    -- unfoldings. We therefore make an effort to put everything into
    
    387
    +    -- the right place no matter what we start with.
    
    388
    +    Cast e co   -> mkCast (mkTick' e) co
    
    389
    +
    
    390
    +    -- Float ticks into 'unsafeCoerce' the same way we would do with a cast.
    
    391
    +    Case scrut bndr ty alts@[Alt ac abs _rhs]
    
    392
    +      | Just rhs <- isUnsafeEqualityCase scrut bndr alts
    
    393
    +      -> Case scrut bndr ty [Alt ac abs (mkTick' rhs)]
    
    380 394
     
    
    381 395
         Var x
    
    382
    -      | notFunction && tickishPlace t == PlaceCostCentre
    
    383
    -      -> rest expr  -- Drop t
    
    384
    -      | notFunction && canSplit
    
    385
    -      -> Tick (mkNoScope t) $ rest expr
    
    396
    +      | notFunction
    
    397
    +      , tickishPlace t == PlaceCostCentre || can_split
    
    398
    +      -> if tickishPlace t == PlaceCostCentre
    
    399
    +         then expr -- Drop tick t entirely
    
    400
    +         else Tick (mkNoScope t) expr
    
    386 401
           where
    
    387 402
             -- SCCs can be eliminated on variables provided the variable
    
    388 403
             -- is not a function.  In these cases the SCC makes no difference:
    
    ... ... @@ -392,12 +407,24 @@ mkTick t orig_expr = mkTick' id orig_expr
    392 407
             -- when the function is called, so we must retain those.
    
    393 408
             notFunction = not (isFunTy (idType x))
    
    394 409
     
    
    410
    +    Coercion co
    
    411
    +      -- Make sure to drop SCCs around coercions, to avoid generating Core
    
    412
    +      -- of the form 'let co = scc<foo> <Int>_N' (which Core Lint isn't happy with).
    
    413
    +      -- See #26941.
    
    414
    +      | tickishPlace t == PlaceCostCentre
    
    415
    +      -> Coercion co -- Drop tick t entirely
    
    416
    +      | can_split
    
    417
    +      -> Tick (mkNoScope t) expr
    
    418
    +
    
    395 419
         Lit{}
    
    396 420
           | tickishPlace t == PlaceCostCentre
    
    397
    -      -> rest expr   -- Drop t
    
    421
    +      -> expr   -- Drop tick t entirely
    
    422
    +      | can_split
    
    423
    +      -> Tick (mkNoScope t) expr
    
    398 424
     
    
    399
    -    -- Catch-all: Annotate where we stand
    
    400
    -    _any -> Tick t $ rest expr
    
    425
    +    -- Catch-all: Annotate where we stand.
    
    426
    +    -- Used for Type, Let, most Cases
    
    427
    +    _any -> Tick t expr
    
    401 428
     
    
    402 429
     mkTicks :: [CoreTickish] -> CoreExpr -> CoreExpr
    
    403 430
     mkTicks ticks expr = foldr mkTick expr ticks
    

  • testsuite/tests/simplCore/should_compile/T26941.hs
    1
    +{-# LANGUAGE DataKinds #-}
    
    2
    +{-# LANGUAGE GADTs #-}
    
    3
    +{-# LANGUAGE TypeOperators #-}
    
    4
    +
    
    5
    +module T26941 where
    
    6
    +
    
    7
    +import GHC.TypeLits
    
    8
    +
    
    9
    +import T26941_aux ( SMayNat(SKnown), ListH, shxHead )
    
    10
    +
    
    11
    +shsHead :: ListH (Just n : sh) Int -> SNat n
    
    12
    +shsHead shx =
    
    13
    +  case shxHead shx of
    
    14
    +    SKnown SNat -> SNat

  • testsuite/tests/simplCore/should_compile/T26941_aux.hs
    1
    +{-# LANGUAGE DataKinds #-}
    
    2
    +{-# LANGUAGE GADTs #-}
    
    3
    +{-# LANGUAGE StandaloneKindSignatures #-}
    
    4
    +{-# LANGUAGE TypeOperators #-}
    
    5
    +
    
    6
    +module T26941_aux where
    
    7
    +
    
    8
    +import Data.Kind
    
    9
    +import GHC.TypeLits
    
    10
    +
    
    11
    +shxHead :: ListH (n : sh) i -> SMayNat i n
    
    12
    +shxHead list = {-# SCC "bad_scc" #-}
    
    13
    +  ( case list of (i `ConsKnown` _) -> SKnown i )
    
    14
    +
    
    15
    +type ListH :: [Maybe Nat] -> Type -> Type
    
    16
    +data ListH sh i where
    
    17
    +  ConsKnown :: SNat n -> ListH sh i -> ListH (Just n : sh) i
    
    18
    +
    
    19
    +data SMayNat i n where
    
    20
    +  SKnown :: SNat n -> SMayNat i (Just n)

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -568,6 +568,8 @@ test('T26117', [grep_errmsg(r'==')], compile, ['-O -ddump-simpl -dsuppress-uniqu
    568 568
     test('T26349',  normal, compile, ['-O -ddump-rules'])
    
    569 569
     test('T26681',  normal, compile, ['-O'])
    
    570 570
     
    
    571
    +test('T26941', [extra_files(['T26941_aux.hs']), req_profiling], multimod_compile, ['T26941', '-v0 -O -prof'])
    
    572
    +
    
    571 573
     # T26709: we expect three `case` expressions not four
    
    572 574
     test('T26709', [grep_errmsg(r'case')],
    
    573 575
            multimod_compile,