Automatically add SCCs to INLINABLE bindings
authorDavid Feuer <david.feuer@gmail.com>
Fri, 12 May 2017 18:37:36 +0000 (14:37 -0400)
committerDavid Feuer <David.Feuer@gmail.com>
Fri, 12 May 2017 18:37:37 +0000 (14:37 -0400)
Instead of excluding `isAnyInlinePragma`, just exclude
`isInlinePragma`. This makes GHC behave as documented;
the user's guide only indicates that GHC does not automatically
add SCCs to `INLINE` bindings.

Fixes #12962.

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: DemiMarie, osa1, Mikolaj, simonpj, rwbarton, thomie

GHC Trac Issues: #12962

Differential Revision: https://phabricator.haskell.org/D3550

compiler/deSugar/Coverage.hs
testsuite/tests/profiling/should_run/T12962.hs [new file with mode: 0644]
testsuite/tests/profiling/should_run/T12962.prof.sample [new file with mode: 0644]
testsuite/tests/profiling/should_run/all.T
testsuite/tests/profiling/should_run/profinline001.prof.sample

index f4fb42c..2421333 100644 (file)
@@ -274,11 +274,12 @@ addTickLHsBind (L pos bind@(AbsBinds { abs_binds   = binds,
                       | ABE{ abe_poly = pid, abe_mono = mid } <- abs_exports
                       , idName pid `elemNameSet` (exports env) ] }
 
+   -- See Note [inline sccs]
    add_inlines env =
      env{ inlines = inlines env `extendVarSetList`
                       [ mid
                       | ABE{ abe_poly = pid, abe_mono = mid } <- abs_exports
-                      , isAnyInlinePragma (idInlinePragma pid) ] }
+                      , isInlinePragma (idInlinePragma pid) ] }
 
 addTickLHsBind (L pos bind@(AbsBindsSig { abs_sig_bind   = val_bind
                                         , abs_sig_export = poly_id }))
@@ -298,8 +299,9 @@ addTickLHsBind (L pos bind@(AbsBindsSig { abs_sig_bind   = val_bind
     | otherwise
     = env
 
+  -- See Note [inline sccs]
   add_inlines mono_id env
-    | isAnyInlinePragma (idInlinePragma poly_id)
+    | isInlinePragma (idInlinePragma poly_id)
     = env { inlines = inlines env `extendVarSet` mono_id }
     | otherwise
     = env
@@ -310,7 +312,8 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id)  }))) = do
   density <- getDensity
 
   inline_ids <- liftM inlines getEnv
-  let inline   = isAnyInlinePragma (idInlinePragma id)
+  -- See Note [inline sccs]
+  let inline   = isInlinePragma (idInlinePragma id)
                  || id `elemVarSet` inline_ids
 
   -- See Note [inline sccs]
@@ -406,6 +409,11 @@ bindTick density name pos fvs = do
 -- (see #6131)
 --
 -- So for now we do not add any ticks to INLINE functions at all.
+--
+-- We used to use isAnyInlinePragma to figure out whether to avoid adding
+-- ticks for this purpose. However, #12962 indicates that this contradicts
+-- the documentation on profiling (which only mentions INLINE pragmas).
+-- So now we're more careful about what we avoid adding ticks to.
 
 -- -----------------------------------------------------------------------------
 -- Decorate an LHsExpr with ticks
diff --git a/testsuite/tests/profiling/should_run/T12962.hs b/testsuite/tests/profiling/should_run/T12962.hs
new file mode 100644 (file)
index 0000000..b21dbc0
--- /dev/null
@@ -0,0 +1,21 @@
+{-# OPTIONS_GHC -fprof-auto-top #-}
+
+-- We want to make sure that 'foo' gets a cost center
+-- automatically even though it is INLINABLE. INLINE functions
+-- do not get cost centers automatically.
+
+import Data.List (zipWith3)
+import Control.Exception (evaluate)
+
+{-# INLINABLE foo #-}
+foo :: Num a => a -> a -> a -> a
+foo a b c = a * b + c
+
+{-# NOINLINE niz3 #-}
+niz3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
+niz3 x y z = zipWith3 x y z
+
+blah :: [Int]
+blah = replicate 100 1
+
+main = evaluate $ sum $ niz3 foo blah blah blah
diff --git a/testsuite/tests/profiling/should_run/T12962.prof.sample b/testsuite/tests/profiling/should_run/T12962.prof.sample
new file mode 100644 (file)
index 0000000..025e9e0
--- /dev/null
@@ -0,0 +1,32 @@
+       Thu May 11 13:42 2017 Time and Allocation Profiling Report  (Final)
+
+          T12962 +RTS -hc -p -RTS
+
+       total time  =        0.00 secs   (0 ticks @ 1000 us, 1 processor)
+       total alloc =      57,392 bytes  (excludes profiling overheads)
+
+COST CENTRE MODULE           SRC                %time %alloc
+
+MAIN        MAIN             <built-in>           0.0    1.2
+CAF         GHC.IO.Handle.FD <entire-module>      0.0   60.5
+CAF         GHC.IO.Encoding  <entire-module>      0.0    4.8
+CAF         GHC.Conc.Signal  <entire-module>      0.0    1.1
+foo         Main             T12962.hs:8:1-21     0.0    2.8
+niz3        Main             T12962.hs:12:1-27    0.0   20.9
+blah        Main             T12962.hs:15:1-22    0.0    8.3
+
+
+                                                                        individual      inherited
+COST CENTRE  MODULE                SRC               no.     entries  %time %alloc   %time %alloc
+
+MAIN         MAIN                  <built-in>        110          0    0.0    1.2     0.0  100.0
+ CAF         Main                  <entire-module>   219          0    0.0    0.0     0.0   32.1
+  blah       Main                  T12962.hs:15:1-22 223          1    0.0    8.3     0.0    8.3
+  main       Main                  T12962.hs:17:1-47 220          1    0.0    0.0     0.0   23.8
+   niz3      Main                  T12962.hs:12:1-27 222          1    0.0   20.9     0.0   23.7
+    foo      Main                  T12962.hs:8:1-21  224        100    0.0    2.8     0.0    2.8
+ CAF         GHC.Conc.Signal       <entire-module>   214          0    0.0    1.1     0.0    1.1
+ CAF         GHC.IO.Encoding       <entire-module>   204          0    0.0    4.8     0.0    4.8
+ CAF         GHC.IO.Encoding.Iconv <entire-module>   202          0    0.0    0.3     0.0    0.3
+ CAF         GHC.IO.Handle.FD      <entire-module>   194          0    0.0   60.5     0.0   60.5
+ main        Main                  T12962.hs:17:1-47 221          0    0.0    0.0     0.0    0.0
index ec5f154..530d2fc 100644 (file)
@@ -130,3 +130,5 @@ test('toplevel_scc_1',
      [extra_ways(['prof_no_auto']), only_ways(['prof_no_auto'])],
      compile_and_run,
      [''])
+
+test('T12962', [], compile_and_run, [''])
index b1f10ed..b07b196 100644 (file)
@@ -1,28 +1,31 @@
-       Fri Jun  3 10:46 2016 Time and Allocation Profiling Report  (Final)
+       Fri May 12 12:12 2017 Time and Allocation Profiling Report  (Final)
 
-          profinline001 +RTS -p -RTS
+          profinline001 +RTS -hc -p -RTS
 
        total time  =        0.00 secs   (0 ticks @ 1000 us, 1 processor)
-       total alloc =      49,392 bytes  (excludes profiling overheads)
+       total alloc =      48,592 bytes  (excludes profiling overheads)
 
 COST CENTRE MODULE           SRC                      %time %alloc
 
-CAF         GHC.IO.Handle.FD <entire-module>            0.0   69.9
-CAF         GHC.IO.Encoding  <entire-module>            0.0    5.6
+MAIN        MAIN             <built-in>                 0.0    1.7
+CAF         GHC.IO.Handle.FD <entire-module>            0.0   71.4
+CAF         GHC.IO.Encoding  <entire-module>            0.0    5.7
 CAF         GHC.Conc.Signal  <entire-module>            0.0    1.3
-main        Main             profinline001.hs:3:1-19    0.0   20.8
+main        Main             profinline001.hs:3:1-19    0.0   19.3
 
 
-                                                                             individual      inherited
-COST CENTRE MODULE                SRC                     no.     entries  %time %alloc   %time %alloc
+                                                                               individual      inherited
+COST CENTRE  MODULE                SRC                      no.     entries  %time %alloc   %time %alloc
 
-MAIN        MAIN                  <built-in>               44          0    0.0    0.7     0.0  100.0
- CAF        Main                  <entire-module>          87          0    0.0    0.7     0.0   21.8
-  main      Main                  profinline001.hs:3:1-19  88          1    0.0   20.8     0.0   21.1
-   f        Main                  profinline001.hs:6:1-21  89          1    0.0    0.3     0.0    0.4
-    g       Main                  profinline001.hs:8:1-11  90          1    0.0    0.0     0.0    0.0
- CAF        GHC.Conc.Signal       <entire-module>          79          0    0.0    1.3     0.0    1.3
- CAF        GHC.IO.Encoding       <entire-module>          76          0    0.0    5.6     0.0    5.6
- CAF        GHC.IO.Handle.FD      <entire-module>          74          0    0.0   69.9     0.0   69.9
- CAF        GHC.IO.Handle.Text    <entire-module>          72          0    0.0    0.2     0.0    0.2
- CAF        GHC.IO.Encoding.Iconv <entire-module>          55          0    0.0    0.5     0.0    0.5
+MAIN         MAIN                  <built-in>               110          0    0.0    1.7     0.0  100.0
+ CAF         Main                  <entire-module>          219          0    0.0    0.0     0.0    0.3
+  main       Main                  profinline001.hs:3:1-19  220          1    0.0    0.3     0.0    0.3
+   f         Main                  profinline001.hs:6:1-21  222          1    0.0    0.0     0.0    0.0
+    g        Main                  profinline001.hs:8:1-11  223          1    0.0    0.0     0.0    0.0
+    i        Main                  profinline001.hs:14:1-11 224          1    0.0    0.0     0.0    0.0
+ CAF         GHC.Conc.Signal       <entire-module>          214          0    0.0    1.3     0.0    1.3
+ CAF         GHC.IO.Encoding       <entire-module>          204          0    0.0    5.7     0.0    5.7
+ CAF         GHC.IO.Encoding.Iconv <entire-module>          202          0    0.0    0.4     0.0    0.4
+ CAF         GHC.IO.Handle.FD      <entire-module>          194          0    0.0   71.4     0.0   71.4
+ CAF         GHC.IO.Handle.Text    <entire-module>          192          0    0.0    0.2     0.0    0.2
+ main        Main                  profinline001.hs:3:1-19  221          0    0.0   18.9     0.0   18.9