summaryrefslogtreecommitdiff
path: root/libraries/ghc-prim
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2017-02-23 14:41:08 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2017-02-24 09:04:46 +0000
commita6e13d502ef46de854ec1babcd764ccce68c95e3 (patch)
treef6ace9b7af1b394546a885f1b2bb0699b67ccc37 /libraries/ghc-prim
parentc88b7c9a06e387c3b9bdb359b9e1e4f3a9fba696 (diff)
downloadhaskell-a6e13d502ef46de854ec1babcd764ccce68c95e3.tar.gz
Make exprIsConApp_maybe work better for literals strings
There are two things here * Use exprIsLiteral_maybe to "look through" a variable bound to a literal string. * Add CONLIKE to the NOINLINE pragma for unpackCString# and unpackCStringUtf8# See Trac #13317, Trac #10844, and Note [exprIsConApp_maybe on literal strings] in CoreSubst I did a nofib run and got essentially zero change except for one 2.2% improvement in allocation for 'pretty'.
Diffstat (limited to 'libraries/ghc-prim')
-rw-r--r--libraries/ghc-prim/GHC/CString.hs21
1 files changed, 16 insertions, 5 deletions
diff --git a/libraries/ghc-prim/GHC/CString.hs b/libraries/ghc-prim/GHC/CString.hs
index 19e6f75b1f..2adb13d8a0 100644
--- a/libraries/ghc-prim/GHC/CString.hs
+++ b/libraries/ghc-prim/GHC/CString.hs
@@ -34,9 +34,8 @@ import GHC.Prim
-- stuff uses Strings in the representation, so to give representations for
-- ghc-prim types we need unpackCString#
-{-
-Note [Inlining unpackCString#]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{- Note [Inlining unpackCString#]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There's really no point in ever inlining things like unpackCString# as the loop
doesn't specialise in an interesting way and we can't deforest the list
constructors (we'd want to use unpackFoldrCString# for this). Moreover, it's
@@ -57,10 +56,22 @@ to match unpackCString#,
* stream fusion rules; e.g. in the `text` library,
unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
= unpackCString# a
+
+Moreover, we want to make it CONLIKE, so that:
+
+* the rules in PrelRules will fire when the string is let-bound.
+ E.g. the eqString rule in PrelRules
+ eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2) = s1==s2
+
+* exprIsConApp_maybe will see the string when we ahve
+ let x = unpackCString# "foo"#
+ ...(case x of algs)...
+
+All of this goes for unpackCStringUtf8# too.
-}
unpackCString# :: Addr# -> [Char]
-{-# NOINLINE unpackCString# #-}
+{-# NOINLINE CONLIKE unpackCString# #-}
unpackCString# addr
= unpack 0#
where
@@ -110,7 +121,7 @@ unpackFoldrCString# addr f z
-- There's really no point in inlining this for the same reasons as
-- unpackCString. See Note [Inlining unpackCString#] above for details.
unpackCStringUtf8# :: Addr# -> [Char]
-{-# NOINLINE unpackCStringUtf8# #-}
+{-# NOINLINE CONLIKE unpackCStringUtf8# #-}
unpackCStringUtf8# addr
= unpack 0#
where