[GHC] #9431: integer-gmp small Integer multiplication does two multiplications on x86

#9431: integer-gmp small Integer multiplication does two multiplications on x86 -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.9 Keywords: | Operating System: Architecture: Unknown/Multiple | Unknown/Multiple Difficulty: Unknown | Type of failure: Blocked By: | None/Unknown Related Tickets: | Test Case: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- `timesInteger` begins thusly: {{{ timesInteger :: Integer -> Integer -> Integer timesInteger (S# i) (S# j) = if isTrue# (mulIntMayOflo# i j ==# 0#) then S# (i *# j) else -- ... }}} The x86 backend implements `mulIntMayOflo#` as a (word, word) -> double word multiplication, followed by bit manipulation to test for overflow of the low word. Then, if there was no overflow, on the next line we multiply the operands again. We should be able to do better here. We need a new primop that combines `mulIntMayOflo#` with the actual multiplication result, at least in the non-overflow case (though with some more work we might be able to turn the double word result directly into a large Integer), and then we need to update `timesInteger` to use it. The LLVM backend probably has the same behavior, though it might be smart enough to notice that the multiplication is repeated; I haven't checked its assembly output. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9431 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9431: integer-gmp small Integer multiplication does two multiplications on x86 -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.9 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by hvr): It'd be interesting to know *why* `mulIntMayOflo#` was introduced instead of a version that'd output the non-overflowing result as well. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9431#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9431: integer-gmp small Integer multiplication does two multiplications on x86 -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.9 Component: Compiler | Keywords: (NCG) | Architecture: Unknown/Multiple Resolution: | Difficulty: Unknown Operating System: | Blocked By: Unknown/Multiple | Related Tickets: Type of failure: Runtime | performance bug | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by thomie): * cc: simonmar (added) * failure: None/Unknown => Runtime performance bug * component: Compiler => Compiler (NCG) Comment: For reference, from `libraries/integer-gmp2/src/GHC/Integer/Type.hs`: {{{#!haskell -- | Multiply two 'Integer's timesInteger :: Integer -> Integer -> Integer timesInteger _ (S# 0#) = S# 0# timesInteger (S# 0#) _ = S# 0# timesInteger x (S# 1#) = x timesInteger (S# 1#) y = y timesInteger x (S# -1#) = negateInteger x timesInteger (S# -1#) y = negateInteger y timesInteger (S# x#) (S# y#) = case mulIntMayOflo# x# y# of 0# -> S# (x# *# y#) _ -> timesInt2Integer x# y# }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9431#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC