summaryrefslogtreecommitdiff
path: root/compiler/GHC/StgToCmm
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2021-07-07 18:47:25 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-07-15 23:29:09 -0400
commit41d6cfc4d36ba93d82f16f9a83ea69f4e02c3810 (patch)
tree067308ecd598d42523238a96ac400a40edbe9f28 /compiler/GHC/StgToCmm
parentde98a0ce8f184c9653477ee41602f999c7a381e1 (diff)
downloadhaskell-41d6cfc4d36ba93d82f16f9a83ea69f4e02c3810.tar.gz
Add Word64#/Int64# primops
Word64#/Int64# are only used on 32-bit architectures. Before this patch, operations on these types were directly using the FFI. Now we use real primops that are then lowered into ccalls. The advantage of doing this is that we can now perform constant folding on Word64#/Int64# (#19024). Most of this work was done by John Ericson in !3658. However this patch doesn't go as far as e.g. changing Word64 to always be using Word64#. Noticeable performance improvements T9203(normal) run/alloc 89870808.0 66662456.0 -25.8% GOOD haddock.Cabal(normal) run/alloc 14215777340.8 12780374172.0 -10.1% GOOD haddock.base(normal) run/alloc 15420020877.6 13643834480.0 -11.5% GOOD Metric Decrease: T9203 haddock.Cabal haddock.base
Diffstat (limited to 'compiler/GHC/StgToCmm')
-rw-r--r--compiler/GHC/StgToCmm/Prim.hs68
1 files changed, 67 insertions, 1 deletions
diff --git a/compiler/GHC/StgToCmm/Prim.hs b/compiler/GHC/StgToCmm/Prim.hs
index 2db8e4cd38..542372105e 100644
--- a/compiler/GHC/StgToCmm/Prim.hs
+++ b/compiler/GHC/StgToCmm/Prim.hs
@@ -1,4 +1,4 @@
-
+{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
@@ -16,6 +16,8 @@ module GHC.StgToCmm.Prim (
shouldInlinePrimOp
) where
+#include "MachDeps.h"
+
import GHC.Prelude hiding ((<*>))
import GHC.Platform
@@ -1080,6 +1082,10 @@ emitPrimOp dflags primop = case primop of
Word16ToInt16Op -> \args -> opNop args
Int32ToWord32Op -> \args -> opNop args
Word32ToInt32Op -> \args -> opNop args
+#if WORD_SIZE_IN_BITS < 64
+ Int64ToWord64Op -> \args -> opNop args
+ Word64ToInt64Op -> \args -> opNop args
+#endif
IntToWordOp -> \args -> opNop args
WordToIntOp -> \args -> opNop args
IntToAddrOp -> \args -> opNop args
@@ -1332,6 +1338,54 @@ emitPrimOp dflags primop = case primop of
Word32LtOp -> \args -> opTranslate args (MO_U_Lt W32)
Word32NeOp -> \args -> opTranslate args (MO_Ne W32)
+#if WORD_SIZE_IN_BITS < 64
+-- Int64# signed ops
+
+ Int64ToIntOp -> \args -> opTranslate64 args (\w -> MO_SS_Conv w (wordWidth platform)) MO_I64_ToI
+ IntToInt64Op -> \args -> opTranslate64 args (\w -> MO_SS_Conv (wordWidth platform) w) MO_I64_FromI
+ Int64NegOp -> \args -> opTranslate64 args MO_S_Neg MO_x64_Neg
+ Int64AddOp -> \args -> opTranslate64 args MO_Add MO_x64_Add
+ Int64SubOp -> \args -> opTranslate64 args MO_Sub MO_x64_Sub
+ Int64MulOp -> \args -> opTranslate64 args MO_Mul MO_x64_Mul
+ Int64QuotOp -> \args -> opTranslate64 args MO_S_Quot MO_I64_Quot
+ Int64RemOp -> \args -> opTranslate64 args MO_S_Rem MO_I64_Rem
+
+ Int64SllOp -> \args -> opTranslate64 args MO_Shl MO_x64_Shl
+ Int64SraOp -> \args -> opTranslate64 args MO_S_Shr MO_I64_Shr
+ Int64SrlOp -> \args -> opTranslate64 args MO_U_Shr MO_W64_Shr
+
+ Int64EqOp -> \args -> opTranslate64 args MO_Eq MO_x64_Eq
+ Int64GeOp -> \args -> opTranslate64 args MO_S_Ge MO_I64_Ge
+ Int64GtOp -> \args -> opTranslate64 args MO_S_Gt MO_I64_Gt
+ Int64LeOp -> \args -> opTranslate64 args MO_S_Le MO_I64_Le
+ Int64LtOp -> \args -> opTranslate64 args MO_S_Lt MO_I64_Lt
+ Int64NeOp -> \args -> opTranslate64 args MO_Ne MO_x64_Ne
+
+-- Word64# unsigned ops
+
+ Word64ToWordOp -> \args -> opTranslate64 args (\w -> MO_UU_Conv w (wordWidth platform)) MO_W64_ToW
+ WordToWord64Op -> \args -> opTranslate64 args (\w -> MO_UU_Conv (wordWidth platform) w) MO_W64_FromW
+ Word64AddOp -> \args -> opTranslate64 args MO_Add MO_x64_Add
+ Word64SubOp -> \args -> opTranslate64 args MO_Sub MO_x64_Sub
+ Word64MulOp -> \args -> opTranslate64 args MO_Mul MO_x64_Mul
+ Word64QuotOp -> \args -> opTranslate64 args MO_U_Quot MO_W64_Quot
+ Word64RemOp -> \args -> opTranslate64 args MO_U_Rem MO_W64_Rem
+
+ Word64AndOp -> \args -> opTranslate64 args MO_And MO_x64_And
+ Word64OrOp -> \args -> opTranslate64 args MO_Or MO_x64_Or
+ Word64XorOp -> \args -> opTranslate64 args MO_Xor MO_x64_Xor
+ Word64NotOp -> \args -> opTranslate64 args MO_Not MO_x64_Not
+ Word64SllOp -> \args -> opTranslate64 args MO_Shl MO_x64_Shl
+ Word64SrlOp -> \args -> opTranslate64 args MO_U_Shr MO_W64_Shr
+
+ Word64EqOp -> \args -> opTranslate64 args MO_Eq MO_x64_Eq
+ Word64GeOp -> \args -> opTranslate64 args MO_U_Ge MO_W64_Ge
+ Word64GtOp -> \args -> opTranslate64 args MO_U_Gt MO_W64_Gt
+ Word64LeOp -> \args -> opTranslate64 args MO_U_Le MO_W64_Le
+ Word64LtOp -> \args -> opTranslate64 args MO_U_Lt MO_W64_Lt
+ Word64NeOp -> \args -> opTranslate64 args MO_Ne MO_x64_Ne
+#endif
+
-- Char# ops
CharEqOp -> \args -> opTranslate args (MO_Eq (wordWidth platform))
@@ -1649,6 +1703,18 @@ emitPrimOp dflags primop = case primop of
let stmt = mkAssign (CmmLocal res) (CmmMachOp mop args)
emit stmt
+#if WORD_SIZE_IN_BITS < 64
+ opTranslate64
+ :: [CmmExpr]
+ -> (Width -> MachOp)
+ -> CallishMachOp
+ -> PrimopCmmEmit
+ opTranslate64 args mkMop callish =
+ case platformWordSize platform of
+ PW4 -> opCallish args callish
+ PW8 -> opTranslate args $ mkMop W64
+#endif
+
-- | Basically a "manual" case, rather than one of the common repetitive forms
-- above. The results are a parameter to the returned function so we know the
-- choice of variant never depends on them.