[Git][ghc/ghc][wip/T24359] 2 commits: Split up SPECIALISE pragmas in GHC.Internal.Real
sheaf (@sheaf)
gitlab at gitlab.haskell.org
Tue Dec 3 10:47:49 UTC 2024
sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC
Commits:
977a3b5c by sheaf at 2024-12-03T11:47:40+01:00
Split up SPECIALISE pragmas in GHC.Internal.Real
- - - - -
63c0155f by sheaf at 2024-12-03T11:47:40+01:00
update user's guide for SPECIALISE expression syntax
- - - - -
3 changed files:
- docs/users_guide/exts/pragmas.rst
- docs/users_guide/using-warnings.rst
- libraries/ghc-internal/src/GHC/Internal/Real.hs
Changes:
=====================================
docs/users_guide/exts/pragmas.rst
=====================================
@@ -692,24 +692,26 @@ The :pragma:`RULES` pragma lets you specify rewrite rules. It is described in
single: pragma, SPECIALIZE
single: overloading, death to
-.. pragma:: SPECIALIZE ⟨name⟩ :: ⟨type⟩
+.. pragma:: SPECIALIZE ⟨expr⟩
- Ask that GHC specialize a polymorphic value to a particular type.
+ Ask that GHC specialize a polymorphic value.
(UK spelling also accepted.) For key overloaded functions, you can
-create extra versions (NB: at the cost of larger code) specialised to particular
-types. Thus, if you have an overloaded function:
+create extra versions (NB: at the cost of larger code), specialised to specific
+arguments. Thus, if you have an overloaded function:
::
hammeredLookup :: Ord key => [(key, value)] -> key -> value
If it is heavily used on lists with ``Widget`` keys, you could
-specialise it as follows:
+specialise it with either of the following forms (the second syntax,
+introduced in GHC 9.14, additionally requires :extension:`TypeApplications`):
::
{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
+ {-# SPECIALIZE hammeredLookup @Widget #-}
- A ``SPECIALIZE`` pragma for a function can be put anywhere its type
signature could be put. Moreover, you can also ``SPECIALIZE`` an
@@ -755,15 +757,14 @@ specialise it as follows:
specialisation is done too early, the optimisation rules might fail
to fire.
-- The type in a ``SPECIALIZE`` pragma can be any type that is less
- polymorphic than the type of the original function. In concrete
- terms, if the original function is ``f`` then the pragma
+- The ``SPECIALIZE`` pragma is valid only if the expression is well-typed.
+ For example, a specialize pragma of the form
::
{-# SPECIALIZE f :: <type> #-}
- is valid if and only if the definition
+ is valid only if the definition
::
@@ -777,6 +778,7 @@ specialise it as follows:
f :: Eq a => a -> b -> b
{-# SPECIALISE f :: Int -> b -> b #-}
+ {-# SPECIALISE f @Float #-}
g :: (Eq a, Ix b) => a -> b -> b
{-# SPECIALISE g :: (Eq a) => a -> Int -> Int #-}
@@ -789,12 +791,28 @@ specialise it as follows:
fire very well. If you use this kind of specialisation, let us know
how well it works.
+- Since GHC 9.14, it is also possible to specialise a function at specific
+ value arguments, e.g.: ::
+
+ fn :: Bool -> Int -> Double
+ fn b i = ...
+ where
+ ... = if b then helper1 else helper2
+ {-# SPECIALISE fn True #-}
+ {-# SPECIALISE fn False #-}
+
+ This will make two copies of ``fn``, one for ``True`` and one for ``False``.
+ These will then be optimised to make direct calls to ``helper1`` or ``helper2``,
+ respectively, instead of dispatching on ``b`` at runtime.
+ Call sites (that use a literal ``True`` or ``False``) will be rewritten
+ to use the specialised versions.
+
.. _specialize-inline:
``SPECIALIZE INLINE``
~~~~~~~~~~~~~~~~~~~~~
-.. pragma:: SPECIALIZE INLINE ⟨name⟩ :: ⟨type⟩
+.. pragma:: SPECIALIZE INLINE ⟨expr⟩
:where: top-level
=====================================
docs/users_guide/using-warnings.rst
=====================================
@@ -423,6 +423,20 @@ of ``-W(no-)*``.
such as a `LANGUAGE` or `OPTIONS_GHC` pragma, appears in the body of
the module instead.
+.. ghc-flag:: -Wdeprecated-pragmas
+ :shortdesc: warn about deprecated pragmas
+ :type: dynamic
+ :reverse: -Wno-deprecated-pragmas
+ :category:
+
+ :since: 9.14
+
+ :default: on
+
+ Emits a warning when using a deprecated form of a SPECIALISE pragma which
+ uses multiple comma-separated type signatures (deprecated and scheduled
+ to be removed in GHC 9.18).
+
.. ghc-flag:: -Wmissed-specialisations
:shortdesc: warn when specialisation of an imported, overloaded function
fails.
@@ -477,6 +491,27 @@ of ``-W(no-)*``.
Alias for :ghc-flag:`-Wall-missed-specialisations`
+.. ghc-flag:: -Wuseless-specialisations
+ :shortdesc: warn on useless SPECIALISE pragmas
+ :type: dynamic
+ :reverse: -Wno-useless-specialisations
+ :category:
+
+ :since: 9.14
+
+ :default: on
+
+ Emits a warning if GHC detects a useless SPECIALISE pragma, such as a
+ SPECIALISE pragma on a non-overloaded function, for example
+ ``{-# SPECIALISE id :: Int -> Int #-}``.
+
+.. ghc-flag:: -Wuseless-specializations
+ :shortdesc: alias for :ghc-flag:`-Wuseless-specialisations`
+ :type: dynamic
+ :reverse: -Wno-useless-specializations
+
+ Alias for :ghc-flag:`-Wuseless-specialisations`
+
.. ghc-flag:: -Wextended-warnings
:shortdesc: warn about uses of functions & types that have WARNING or
DEPRECATED pragmas, across all categories
=====================================
libraries/ghc-internal/src/GHC/Internal/Real.hs
=====================================
@@ -746,10 +746,9 @@ x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = powImpl x0 y0
-{-# SPECIALISE powImpl ::
- Integer -> Integer -> Integer,
- Integer -> Int -> Integer,
- Int -> Int -> Int #-}
+{-# SPECIALISE powImpl :: Integer -> Integer -> Integer #-}
+{-# SPECIALISE powImpl :: Integer -> Int -> Integer #-}
+{-# SPECIALISE powImpl :: Int -> Int -> Int #-}
{-# INLINABLE powImpl #-} -- See Note [Inlining (^)]
powImpl :: (Num a, Integral b) => a -> b -> a
-- powImpl : x0 ^ y0 = (x ^ y)
@@ -757,10 +756,9 @@ powImpl x y | even y = powImpl (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = powImplAcc (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-{-# SPECIALISE powImplAcc ::
- Integer -> Integer -> Integer -> Integer,
- Integer -> Int -> Integer -> Integer,
- Int -> Int -> Int -> Int #-}
+{-# SPECIALISE powImplAcc :: Integer -> Integer -> Integer -> Integer #-}
+{-# SPECIALISE powImplAcc :: Integer -> Int -> Integer -> Integer #-}
+{-# SPECIALISE powImplAcc :: Int -> Int -> Int -> Int #-}
{-# INLINABLE powImplAcc #-} -- See Note [Inlining (^)]
powImplAcc :: (Num a, Integral b) => a -> b -> a -> a
-- powImplAcc : x0 ^ y0 = (x ^ y) * z
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dade6ff3f6267aad0bd4f32ff778ae5a129aa15a...63c0155f0b908bad7ea557d2e85cef02d5e108e1
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dade6ff3f6267aad0bd4f32ff778ae5a129aa15a...63c0155f0b908bad7ea557d2e85cef02d5e108e1
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20241203/2e8ab79d/attachment-0001.html>
More information about the ghc-commits
mailing list