diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2022-11-03 17:16:39 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2022-11-10 12:21:13 +0000 |
commit | 2b3d0beec2668963c332b4490328aee256f07766 (patch) | |
tree | 85f68e3e40f8524d2660f6c4476a3380519c7a64 /libraries | |
parent | f9f17b68b144a7ecb91395c1e987bbf4f91c0180 (diff) | |
download | haskell-2b3d0beec2668963c332b4490328aee256f07766.tar.gz |
Make indexError work better
The problem here is described at some length in
Note [Boxity for bottoming functions] and
Note [Reboxed crud for bottoming calls] in GHC.Core.Opt.DmdAnal.
This patch adds a SPECIALISE pragma for indexError, which
makes it much less vulnerable to the problem described in
these Notes.
(This came up in another line of work, where a small change made
indexError do reboxing (in nofib/spectral/simple/table_sort)
that didn't happen before my change. I've opened #22404
to document the fagility.
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/GHC/Ix.hs | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/libraries/base/GHC/Ix.hs b/libraries/base/GHC/Ix.hs index be02b568a2..abbe62c2f1 100644 --- a/libraries/base/GHC/Ix.hs +++ b/libraries/base/GHC/Ix.hs @@ -140,12 +140,30 @@ Note [Out-of-bounds error messages] The default method for 'index' generates hoplelessIndexError, because Ix doesn't have Show as a superclass. For particular base types we can do better, so we override the default method for index. --} --- Abstract these errors from the relevant index functions so that --- the guts of the function will be small enough to inline. +Note [indexError] +~~~~~~~~~~~~~~~~~ +We abstract the guts of constructing an out-of-bounds error into `indexError`. +We give it a NOINLINE pragma, because we don't want to duplicate this +cold-path code. + +We give it a SPECIALISE pragma because we really want it to take +its arguments unboxed, to avoid reboxing code in the caller, and +perhaps even some reboxing code in the hot path of a caller. +See Note [Boxity for bottoming functions] in GHC.Core.Opt.DmdAnal. + +The SPECIALISE pragma means that at least the Int-indexed case +of indexError /will/ unbox its arguments. +The [2] phase is because if we don't give an activation we'll get +the one from the inline pragama (i.e. never) which is a bit silly. +See Note [Activation pragmas for SPECIALISE] in GHC.HsToCore.Binds. +-} + +-- indexError: see Note [indexError] {-# NOINLINE indexError #-} +{-# SPECIALISE [2] indexError :: (Int,Int) -> Int -> String -> b #-} + indexError :: Show a => (a,a) -> a -> String -> b indexError rng i tp = errorWithoutStackTrace (showString "Ix{" . showString tp . showString "}.index: Index " . |