[Git][ghc/ghc][wip/bgamari/sized] 3 commits: CodeToByteCode: Fix handling of narrow datacon fields

Ben Gamari gitlab at gitlab.haskell.org
Mon Nov 2 21:05:25 UTC 2020



Ben Gamari pushed to branch wip/bgamari/sized at Glasgow Haskell Compiler / GHC


Commits:
7a15e68f by Ben Gamari at 2020-11-02T16:03:55-05:00
CodeToByteCode: Fix handling of narrow datacon fields

Handle the non-word-size cases specifically and emit the appropriate
bytecode instructions.

- - - - -
88197dc3 by Ben Gamari at 2020-11-02T16:04:22-05:00
Constant folding for extend/narrow

- - - - -
92c9c279 by Ben Gamari at 2020-11-02T16:05:15-05:00
StgToCmm: Normalize padding

- - - - -


5 changed files:

- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/CoreToByteCode.hs
- compiler/GHC/StgToCmm/DataCon.hs
- compiler/GHC/Types/Literal.hs
- testsuite/tests/simplCore/should_compile/T8832.stdout


Changes:

=====================================
compiler/GHC/Core/Opt/ConstantFold.hs
=====================================
@@ -199,40 +199,34 @@ primOpRules nm = \case
 
    -- coercions
 
-   Int8ExtendOp   -> mkPrimOpRule nm 1 [ do [Var primop_id `App` e] <- getArgs
-                                            matchPrimOpId Int8NarrowOp primop_id
-                                            return (Var (mkPrimOpId Narrow8IntOp) `App` e) ]
-   Int16ExtendOp  -> mkPrimOpRule nm 1 [ do [Var primop_id `App` e] <- getArgs
-                                            matchPrimOpId Int16NarrowOp primop_id
-                                            return (Var (mkPrimOpId Narrow16IntOp) `App` e) ]
-   Int32ExtendOp  -> mkPrimOpRule nm 1 [ do [Var primop_id `App` e] <- getArgs
-                                            matchPrimOpId Int32NarrowOp primop_id
-                                            return (Var (mkPrimOpId Narrow32IntOp) `App` e) ]
-   Int8NarrowOp   -> mkPrimOpRule nm 1 [ subsumedByPrimOp Int8NarrowOp
+   Int8ExtendOp   -> mkPrimOpRule nm 1 [ liftLitPlatform extendIntLit ]
+   Int16ExtendOp  -> mkPrimOpRule nm 1 [ liftLitPlatform extendIntLit ]
+   Int32ExtendOp  -> mkPrimOpRule nm 1 [ liftLitPlatform extendIntLit ]
+   Int8NarrowOp   -> mkPrimOpRule nm 1 [ liftLit narrowInt8Lit
+                                       , subsumedByPrimOp Int8NarrowOp
                                        , narrowSubsumesAnd AndIOp Int8NarrowOp 8 ]
-   Int16NarrowOp  -> mkPrimOpRule nm 1 [ subsumedByPrimOp Int8NarrowOp
+   Int16NarrowOp  -> mkPrimOpRule nm 1 [ liftLit narrowInt16Lit
+                                       , subsumedByPrimOp Int8NarrowOp
                                        , subsumedByPrimOp Int16NarrowOp
                                        , narrowSubsumesAnd AndIOp Int16NarrowOp 16 ]
-   Int32NarrowOp  -> mkPrimOpRule nm 1 [ subsumedByPrimOp Int8NarrowOp
+   Int32NarrowOp  -> mkPrimOpRule nm 1 [ liftLit narrowInt32Lit
+                                       , subsumedByPrimOp Int8NarrowOp
                                        , subsumedByPrimOp Int16NarrowOp
                                        , subsumedByPrimOp Int32NarrowOp
                                        , narrowSubsumesAnd AndIOp Int32NarrowOp 32 ]
 
-   Word8ExtendOp  -> mkPrimOpRule nm 1 [ do [Var primop_id `App` e] <- getArgs
-                                            matchPrimOpId Word8NarrowOp primop_id
-                                            return (Var (mkPrimOpId Narrow8WordOp) `App` e) ]
-   Word16ExtendOp -> mkPrimOpRule nm 1 [ do [Var primop_id `App` e] <- getArgs
-                                            matchPrimOpId Word16NarrowOp primop_id
-                                            return (Var (mkPrimOpId Narrow16WordOp) `App` e) ]
-   Word32ExtendOp -> mkPrimOpRule nm 1 [ do [Var primop_id `App` e] <- getArgs
-                                            matchPrimOpId Word32NarrowOp primop_id
-                                            return (Var (mkPrimOpId Narrow32WordOp) `App` e) ]
-   Word8NarrowOp  -> mkPrimOpRule nm 1 [ subsumedByPrimOp Word8NarrowOp
+   Word8ExtendOp  -> mkPrimOpRule nm 1 [ liftLitPlatform extendWordLit ]
+   Word16ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendWordLit ]
+   Word32ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendWordLit ]
+   Word8NarrowOp  -> mkPrimOpRule nm 1 [ liftLit narrowWord8Lit
+                                       , subsumedByPrimOp Word8NarrowOp
                                        , narrowSubsumesAnd AndOp Word8NarrowOp 8 ]
-   Word16NarrowOp -> mkPrimOpRule nm 1 [ subsumedByPrimOp Word8NarrowOp
+   Word16NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowWord16Lit
+                                       , subsumedByPrimOp Word8NarrowOp
                                        , subsumedByPrimOp Word16NarrowOp
                                        , narrowSubsumesAnd AndOp Word16NarrowOp 16 ]
-   Word32NarrowOp -> mkPrimOpRule nm 1 [ subsumedByPrimOp Word8NarrowOp
+   Word32NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowWord32Lit
+                                       , subsumedByPrimOp Word8NarrowOp
                                        , subsumedByPrimOp Word16NarrowOp
                                        , subsumedByPrimOp Word32NarrowOp
                                        , narrowSubsumesAnd AndOp Word32NarrowOp 32 ]


=====================================
compiler/GHC/CoreToByteCode.hs
=====================================
@@ -1633,30 +1633,39 @@ pushAtom d p (AnnVar var)
 
 pushAtom _ _ (AnnLit lit) = do
      platform <- targetPlatform <$> getDynFlags
-     let code rep
-             = let size_words = WordOff (argRepSizeW platform rep)
-               in  return (unitOL (PUSH_UBX lit (trunc16W size_words)),
-                           wordsToBytes platform size_words)
+     let code :: PrimRep -> BcM (BCInstrList, ByteOff)
+         code rep =
+            return (unitOL instr, size_bytes)
+          where
+            size_bytes = ByteOff $ primRepSizeB platform rep
+            -- Here we handle the non-word-width cases specifically since we
+            -- must emit different bytecode for them.
+            instr =
+              case size_bytes of
+                1  -> PUSH_UBX8 lit
+                2  -> PUSH_UBX16 lit
+                4  -> PUSH_UBX32 lit
+                _  -> PUSH_UBX lit (trunc16W $ bytesToWords platform size_bytes)
 
      case lit of
-        LitLabel _ _ _  -> code N
-        LitFloat _      -> code F
-        LitDouble _     -> code D
-        LitChar _       -> code N
-        LitNullAddr     -> code N
-        LitString _     -> code N
-        LitRubbish      -> code N
+        LitLabel _ _ _  -> code AddrRep
+        LitFloat _      -> code FloatRep
+        LitDouble _     -> code DoubleRep
+        LitChar _       -> code WordRep
+        LitNullAddr     -> code AddrRep
+        LitString _     -> code AddrRep
+        LitRubbish      -> code WordRep
         LitNumber nt _  -> case nt of
-          LitNumInt     -> code N
-          LitNumWord    -> code N
-          LitNumInt8    -> code (toArgRep Int8Rep)
-          LitNumWord8   -> code (toArgRep Word8Rep)
-          LitNumInt16   -> code (toArgRep Int16Rep)
-          LitNumWord16  -> code (toArgRep Word16Rep)
-          LitNumInt32   -> code (toArgRep Int32Rep)
-          LitNumWord32  -> code (toArgRep Word32Rep)
-          LitNumInt64   -> code L
-          LitNumWord64  -> code L
+          LitNumInt     -> code IntRep
+          LitNumWord    -> code WordRep
+          LitNumInt8    -> code Int8Rep
+          LitNumWord8   -> code Word8Rep
+          LitNumInt16   -> code Int16Rep
+          LitNumWord16  -> code Word16Rep
+          LitNumInt32   -> code Int32Rep
+          LitNumWord32  -> code Word32Rep
+          LitNumInt64   -> code Int64Rep
+          LitNumWord64  -> code Word64Rep
           -- No LitInteger's or LitNatural's should be left by the time this is
           -- called. CorePrep should have converted them all to a real core
           -- representation.


=====================================
compiler/GHC/StgToCmm/DataCon.hs
=====================================
@@ -102,6 +102,21 @@ cgTopRhsCon dflags id con args
              nv_args_w_offsets) =
                  mkVirtHeapOffsetsWithPadding profile StdHeader (addArgReps args)
 
+        ; let
+            -- Decompose padding into units of length 8, 4, 2, or 1 bytes to
+            -- allow the implementation of mk_payload to use widthFromBytes,
+            -- which only handles these cases.
+            fix_padding (x@(Padding n off) : rest)
+              | n == 0                 = fix_padding rest
+              | n `elem` [1,2,4,8]     = x : fix_padding rest
+              | n > 8                  = add_pad 8
+              | n > 4                  = add_pad 4
+              | n > 2                  = add_pad 2
+              | otherwise              = add_pad 1
+              where add_pad m = Padding m off : fix_padding (Padding (n-m) (off+m) : rest)
+            fix_padding (x : rest)     = x : fix_padding rest
+            fix_padding []             = []
+
             mk_payload (Padding len _) = return (CmmInt 0 (widthFromBytes len))
             mk_payload (FieldOff arg _) = do
                 amode <- getArgAmode arg
@@ -117,7 +132,7 @@ cgTopRhsCon dflags id con args
             info_tbl = mkDataConInfoTable profile con True ptr_wds nonptr_wds
 
 
-        ; payload <- mapM mk_payload nv_args_w_offsets
+        ; payload <- mapM mk_payload (fix_padding nv_args_w_offsets)
                 -- NB1: nv_args_w_offsets is sorted into ptrs then non-ptrs
                 -- NB2: all the amodes should be Lits!
                 --      TODO (osa): Why?


=====================================
compiler/GHC/Types/Literal.hs
=====================================
@@ -46,9 +46,11 @@ module GHC.Types.Literal
 
         -- ** Coercions
         , wordToIntLit, intToWordLit
-        , narrowLit
         , narrow8IntLit, narrow16IntLit, narrow32IntLit
         , narrow8WordLit, narrow16WordLit, narrow32WordLit
+        , narrowInt8Lit, narrowInt16Lit, narrowInt32Lit
+        , narrowWord8Lit, narrowWord16Lit, narrowWord32Lit
+        , extendIntLit, extendWordLit
         , int8Lit, int16Lit, int32Lit
         , word8Lit, word16Lit, word32Lit
         , charToIntLit, intToCharLit
@@ -614,16 +616,31 @@ intToWordLit platform (LitNumber LitNumInt i)
 intToWordLit _ l = pprPanic "intToWordLit" (ppr l)
 
 -- | Narrow a literal number (unchecked result range)
-narrowLit :: forall a. Integral a => Proxy a -> Literal -> Literal
-narrowLit _ (LitNumber nt i) = LitNumber nt (toInteger (fromInteger i :: a))
-narrowLit _ l                = pprPanic "narrowLit" (ppr l)
-
-narrow8IntLit   = narrowLit (Proxy :: Proxy Int8)
-narrow16IntLit  = narrowLit (Proxy :: Proxy Int16)
-narrow32IntLit  = narrowLit (Proxy :: Proxy Int32)
-narrow8WordLit  = narrowLit (Proxy :: Proxy Word8)
-narrow16WordLit = narrowLit (Proxy :: Proxy Word16)
-narrow32WordLit = narrowLit (Proxy :: Proxy Word32)
+narrowLit' :: forall a. Integral a => Proxy a -> LitNumType -> Literal -> Literal
+narrowLit' _ nt' (LitNumber nt i) = LitNumber nt' (toInteger (fromInteger i :: a))
+narrowLit' _ nt' l                = pprPanic "narrowLit" (ppr l)
+
+narrow8IntLit   = narrowLit' (Proxy :: Proxy Int8)   LitNumInt
+narrow16IntLit  = narrowLit' (Proxy :: Proxy Int16)  LitNumInt
+narrow32IntLit  = narrowLit' (Proxy :: Proxy Int32)  LitNumInt
+narrow8WordLit  = narrowLit' (Proxy :: Proxy Word8)  LitNumWord
+narrow16WordLit = narrowLit' (Proxy :: Proxy Word16) LitNumWord
+narrow32WordLit = narrowLit' (Proxy :: Proxy Word32) LitNumWord
+
+narrowInt8Lit   = narrowLit' (Proxy :: Proxy Int8)   LitNumInt8
+narrowInt16Lit  = narrowLit' (Proxy :: Proxy Int16)  LitNumInt16
+narrowInt32Lit  = narrowLit' (Proxy :: Proxy Int32)  LitNumInt32
+narrowWord8Lit  = narrowLit' (Proxy :: Proxy Word8)  LitNumWord8
+narrowWord16Lit = narrowLit' (Proxy :: Proxy Word16) LitNumWord16
+narrowWord32Lit = narrowLit' (Proxy :: Proxy Word32) LitNumWord32
+
+-- | Extend a fixed-width literal (e.g. 'Int16#') to a word-sized literal (e.g.
+-- 'Int#').
+extendWordLit, extendIntLit :: Platform -> Literal -> Literal
+extendWordLit platform (LitNumber _nt i) = mkLitWord platform i
+extendWordLit platform l                 = pprPanic "extendWordLit" (ppr l)
+extendIntLit  platform (LitNumber _nt i) = mkLitInt platform i
+extendIntLit  platform l                 = pprPanic "extendIntLit" (ppr l)
 
 int8Lit (LitNumber _ i)   = mkLitInt8 i
 int8Lit l                 = pprPanic "int8Lit" (ppr l)


=====================================
testsuite/tests/simplCore/should_compile/T8832.stdout
=====================================
@@ -1,11 +1,11 @@
 i = GHC.Types.I# 0#
-i8 = GHC.Int.I8# (GHC.Prim.narrowInt8# 0#)
-i16 = GHC.Int.I16# (GHC.Prim.narrowInt16# 0#)
-i32 = GHC.Int.I32# (GHC.Prim.narrowInt32# 0#)
+i8 = GHC.Int.I8# 0#8
+i16 = GHC.Int.I16# 0#16
+i32 = GHC.Int.I32# 0#32
 i64 = GHC.Int.I64# 0#
 w = GHC.Types.W# 0##
-w8 = GHC.Word.W8# (GHC.Prim.narrowWord8# 0##)
-w16 = GHC.Word.W16# (GHC.Prim.narrowWord16# 0##)
-w32 = GHC.Word.W32# (GHC.Prim.narrowWord32# 0##)
+w8 = GHC.Word.W8# 0##8
+w16 = GHC.Word.W16# 0##16
+w32 = GHC.Word.W32# 0##32
 w64 = GHC.Word.W64# 0##
 z = 0



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/001378cb146868d220c8f55b43251d3b7d71ddd1...92c9c27937704e8e1aea19a12ae01b4eeb268964

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/001378cb146868d220c8f55b43251d3b7d71ddd1...92c9c27937704e8e1aea19a12ae01b4eeb268964
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20201102/69d6ea48/attachment-0001.html>


More information about the ghc-commits mailing list