diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2020-04-16 17:43:32 +0200 |
---|---|---|
committer | Andreas Klebinger <klebinger.andreas@gmx.at> | 2020-04-19 12:27:44 +0200 |
commit | 0ed373698572aed88cf91553368a1dfa9767b749 (patch) | |
tree | 0d9f130dfc6eb5fbf5d56d37de53fcefdff92dbf | |
parent | bcafaa82a0223afd5d103e052ab9a097a676e5ea (diff) | |
download | haskell-wip/andreask/inline_div.tar.gz |
Always inline divInt and modInt in phase zero.wip/andreask/inline_div
This prevents the overhead of a function call for
operations which really only need to be a few instructions.
By always inlining them in phase zero we can:
* Match on them via rules in earlier phases.
* Can constant fold on them in phase zero by
rules on their underlying primitives.
This fixes #18067
-rw-r--r-- | libraries/base/GHC/Base.hs | 27 | ||||
-rw-r--r-- | libraries/ghc-prim/GHC/Classes.hs | 4 |
2 files changed, 29 insertions, 2 deletions
diff --git a/libraries/base/GHC/Base.hs b/libraries/base/GHC/Base.hs index 610e2996a8..25d341de87 100644 --- a/libraries/base/GHC/Base.hs +++ b/libraries/base/GHC/Base.hs @@ -1545,9 +1545,36 @@ getTag x = dataToTag# x -- Definitions of the boxed PrimOps; these will be -- used in the case of partial applications, etc. +{- Note [Inlining divInt, modInt] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + divInt and modInt are implemented by calling unboxed + variants, which themselves are implemented in terms of + the quotInt#/remInt# primOps. + + My marking the boxed versions as INLINE[1] we achieve two things: + + * The strength reduction rules which are operating on divInt#/remInt# + can already fire in phase 1. + * We can inline any constant argument in Phase zero optimizing the + general case somewhat. + + This solves #18067 where we observed divInt ending up + as a uninlined call to divInt# at times. + + TODO: It might be good to apply the same pattern to + quotRemInt and divModInt. But I have not looked at this + yet. + +-} + {-# INLINE quotInt #-} {-# INLINE remInt #-} +-- See Note [Inlining divInt, modInt] +{-# INLINE[1] divInt #-} +{-# INLINE[1] modInt #-} + quotInt, remInt, divInt, modInt :: Int -> Int -> Int (I# x) `quotInt` (I# y) = I# (x `quotInt#` y) (I# x) `remInt` (I# y) = I# (x `remInt#` y) diff --git a/libraries/ghc-prim/GHC/Classes.hs b/libraries/ghc-prim/GHC/Classes.hs index 4ccfe914bd..43364f40e4 100644 --- a/libraries/ghc-prim/GHC/Classes.hs +++ b/libraries/ghc-prim/GHC/Classes.hs @@ -545,8 +545,8 @@ not False = True -- put them -- These functions have built-in rules. -{-# NOINLINE [0] divInt# #-} -{-# NOINLINE [0] modInt# #-} +{-# INLINE [0] divInt# #-} +{-# INLINE [0] modInt# #-} divInt# :: Int# -> Int# -> Int# x# `divInt#` y# -- Be careful NOT to overflow if we do any additional arithmetic |