diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2021-07-07 18:47:25 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-07-15 23:29:09 -0400 |
commit | 41d6cfc4d36ba93d82f16f9a83ea69f4e02c3810 (patch) | |
tree | 067308ecd598d42523238a96ac400a40edbe9f28 /compiler/GHC/StgToCmm | |
parent | de98a0ce8f184c9653477ee41602f999c7a381e1 (diff) | |
download | haskell-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.hs | 68 |
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. |