Simon Peyton Jones pushed to branch wip/T26615 at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/Core/Opt/SpecConstr.hs
    ... ... @@ -1864,7 +1864,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs
    1864 1864
         return (nullUsage, spec_info, [])
    
    1865 1865
     
    
    1866 1866
       | not (isNeverActive (idInlineActivation fn))
    
    1867
    -      -- See Note [Transfer activation]
    
    1867
    +      -- See (SCRA1) in Note [SpecConstr: rule activation]
    
    1868 1868
           -- Don't specialise OPAQUE things, see Note [OPAQUE pragma].
    
    1869 1869
           -- Since OPAQUE things are always never-active (see
    
    1870 1870
           -- GHC.Parser.PostProcess.mkOpaquePragma) this guard never fires for
    
    ... ... @@ -2075,7 +2075,7 @@ mkSeqs seqees res_ty rhs =
    2075 2075
             = rhs
    
    2076 2076
     
    
    2077 2077
     specConstrRuleActivation :: InlinePragmaInfo -> ActivationGhc
    
    2078
    --- See Note [SpecConstr rule activation]
    
    2078
    +-- See Note [SpecConstr: rule activation]
    
    2079 2079
     specConstrRuleActivation fn_prag
    
    2080 2080
       = activeAfter $ nextPhase $ beginPhase $ inlinePragmaActivation fn_prag
    
    2081 2081
     
    
    ... ... @@ -2129,7 +2129,7 @@ The void argument must follow the foralls, lest the forall be
    2129 2129
     ill-kinded.  See Note [Worker/wrapper needs to add void arg last] in
    
    2130 2130
     GHC.Core.Opt.WorkWrap.Utils.
    
    2131 2131
     
    
    2132
    -Note [SpecConstr rule activation]
    
    2132
    +Note [SpecConstr: rule activation]
    
    2133 2133
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2134 2134
     When should the RULE generated by SpecConstr be activated?
    
    2135 2135
     See the function `specConstrRuleActivation`.
    
    ... ... @@ -2163,15 +2163,13 @@ Goal 1: "SC:1" won't fire in f's unfolding;
    2163 2163
        see Note [What is active in the RHS of a RULE or unfolding?]
    
    2164 2164
     
    
    2165 2165
     Goal 2: "SPEC:f" has the same activation as `f`;
    
    2166
    -  see Note [Auto-specialisation and RULES]).  So "SPEC:f" will fire
    
    2166
    +  see Note [Specialise: rule activation].  So "SPEC:f" will fire
    
    2167 2167
       before "SC:1"
    
    2168 2168
     
    
    2169
    -Other points:
    
    2170
    -
    
    2171
    -* c.f. Note [Auto-specialisation and RULES] in GHC.Core.Opt.Specialise.
    
    2172
    -* his in turn means there is no point in specialising NOINLINE things,
    
    2173
    -so we test for that.
    
    2169
    +Wrinkles
    
    2174 2170
     
    
    2171
    +(SCRA1) If `f` is NOINLINE we arguably don't want a specialisation at all.
    
    2172
    +  See (SRA1) in GHC.Core.Opt.Specialise.  At least that's the choice for now.
    
    2175 2173
     
    
    2176 2174
     Note [generaliseDictPats]
    
    2177 2175
     ~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -1588,7 +1588,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1588 1588
       |  notNull calls_for_me               -- And there are some calls to specialise
    
    1589 1589
       && not (isNeverActive (idInlineActivation fn))
    
    1590 1590
             -- Don't specialise NOINLINE things
    
    1591
    -        -- See Note [Auto-specialisation and RULES]
    
    1591
    +        -- See (SRA1) in Note [Specialise: rule activation]
    
    1592 1592
             --
    
    1593 1593
             -- Don't specialise OPAQUE things, see Note [OPAQUE pragma].
    
    1594 1594
             -- Since OPAQUE things are always never-active (see
    
    ... ... @@ -1619,7 +1619,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1619 1619
         fn_unf    = realIdUnfolding fn  -- Ignore loop-breaker-ness here
    
    1620 1620
         fn_prag   = idInlinePragma fn
    
    1621 1621
         rule_act  = inlinePragmaActivation fn_prag
    
    1622
    -                -- rule_act: see Note [Auto-specialisation and RULES]
    
    1622
    +                -- rule_act: see Note [Specialise: rule activation]
    
    1623 1623
         is_active :: ActivationGhc -> Bool
    
    1624 1624
         is_active = isActive (SimplPhaseRange (beginPhase rule_act) (endPhase rule_act))
    
    1625 1625
              -- is_active: rule_act is the activation we are going to put in the new
    
    ... ... @@ -2361,8 +2361,8 @@ argument pattern. Wrinkles
    2361 2361
     (SC3) Annoyingly, we /also/ eliminate duplicates in `filterCalls`.
    
    2362 2362
        See (MP3) in Note [Specialising polymorphic dictionaries]
    
    2363 2363
     
    
    2364
    -Note [Auto-specialisation and RULES]
    
    2365
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2364
    +Note [Specialise: rule activation]
    
    2365
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2366 2366
     Consider:
    
    2367 2367
        g :: Num a => a -> a
    
    2368 2368
        g = ...
    
    ... ... @@ -2383,15 +2383,22 @@ also add
    2383 2383
             RULE f g_spec = 0
    
    2384 2384
     
    
    2385 2385
     But that's a bit complicated.  For now we lean on the programmer:
    
    2386
    - * Set the activation of the RULE is the same as the activation of the Id,
    
    2386
    +
    
    2387
    + * Make the activation of the RULE be the same as the activation of the Id,
    
    2387 2388
        i.e. (idInlineActivation g)
    
    2388 2389
     
    
    2389 2390
     So if `g` says {-# NOINLINE[2] g #-}, then the auto-spec rule will also not be
    
    2390 2391
     active until phase 2.  And that's what programmers should jolly well do anyway,
    
    2391 2392
     even aside from specialisation, to ensure that `g` doesn't inline too early.
    
    2392 2393
     
    
    2393
    -This in turn means that the RULE would never fire for a NOINLINE
    
    2394
    -thing so not much point in generating a specialisation at all.
    
    2394
    +Wrinkles
    
    2395
    +
    
    2396
    +(SRA1) This in turn means that the RULE would never fire for a NOINLINE thing
    
    2397
    +   so not much point in generating a specialisation at all.  This is a
    
    2398
    +   bit moot: it's not unreasonable to have a (NOINLINE) specialisation for a
    
    2399
    +   NOINLINE function.  But currently we don't.  And hence we don't create
    
    2400
    +   a specialisation for an OPAQUE function either (see Note [OPAQUE pragma]
    
    2401
    +   in Language.Haskell.Syntax.Binds.InlinePragma.
    
    2395 2402
     
    
    2396 2403
     Note [Specialisation shape]
    
    2397 2404
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Core/Opt/WorkWrap.hs
    ... ... @@ -499,7 +499,7 @@ When should the wrapper inlining be active?
    499 499
           {-# SPECIALISE foo :: (Int,Int) -> Bool -> Int #-}
    
    500 500
           {-# NOINLINE [n] foo #-}
    
    501 501
         then specialisation will generate a SPEC rule active from Phase n.
    
    502
    -    See Note [Auto-specialisation and RULES] in GHC.Core.Opt.Specialise
    
    502
    +    See Note [Specialise: rule activation] in GHC.Core.Opt.Specialise
    
    503 503
         This SPEC specialisation rule will compete with inlining, but we don't
    
    504 504
         mind that, because if inlining succeeds, it should be better.
    
    505 505
     
    

  • compiler/GHC/Core/Rules.hs
    ... ... @@ -231,7 +231,7 @@ mkSpecRule dflags this_mod is_auto inl_act herald fn bndrs args rhs
    231 231
       where
    
    232 232
         rule = mkRule this_mod is_auto is_local
    
    233 233
                       rule_name
    
    234
    -                  inl_act       -- Note [Auto-specialisation and RULES]
    
    234
    +                  inl_act       -- Note [Specialise: rule activation]
    
    235 235
                       (idName fn)
    
    236 236
                       bndrs args rhs
    
    237 237
     
    

  • testsuite/tests/simplCore/should_compile/spec-inline.stderr
    ... ... @@ -17,7 +17,7 @@ Roman.foo3
    17 17
     
    
    18 18
     Rec {
    
    19 19
     -- RHS size: {terms: 40, types: 5, coercions: 0, joins: 0/0}
    
    20
    -Roman.foo_$s$wgo [Occ=LoopBreaker]
    
    20
    +Roman.foo_$s$wgo [InlPrag=[2], Occ=LoopBreaker]
    
    21 21
       :: GHC.Internal.Prim.Int#
    
    22 22
          -> GHC.Internal.Prim.Int# -> GHC.Internal.Prim.Int#
    
    23 23
     [GblId, Arity=2, Str=<A><L>, Unf=OtherCon []]
    
    ... ... @@ -141,7 +141,7 @@ foo
    141 141
     
    
    142 142
     
    
    143 143
     ------ Local rules for imported ids --------
    
    144
    -"SC:$wgo0" [2]
    
    144
    +"SC:$wgo0" [1]
    
    145 145
         forall (sc :: GHC.Internal.Prim.Int#)
    
    146 146
                (sc1 :: GHC.Internal.Prim.Int#).
    
    147 147
           Roman.$wgo (GHC.Internal.Maybe.Just