minor changes to Cmm left over from September 2007
[ghc-hetmet.git] / compiler / cmm / PprCmm.hs
index b718ec9..24b1287 100644 (file)
 -- A useful example pass over Cmm is in nativeGen/MachCodeGen.hs
 --
 
-module PprCmm (        
-       writeCmms, pprCmms, pprCmm, pprStmt, pprExpr
-  ) where
-
-#include "HsVersions.h"
+module PprCmm
+    ( writeCmms, pprCmms, pprCmm, pprStmt, pprExpr, pprSection, pprStatic, pprLit
+    )
+where
 
 import Cmm
+import CmmExpr
 import CmmUtils
 import MachOp
 import CLabel
@@ -52,23 +52,28 @@ import Data.List
 import System.IO
 import Data.Maybe
 
-pprCmms :: [Cmm] -> SDoc
+pprCmms :: (Outputable info, Outputable g) => [GenCmm CmmStatic info g] -> SDoc
 pprCmms cmms = pprCode CStyle (vcat (intersperse separator $ map ppr cmms))
         where
-          separator = space $$ ptext SLIT("-------------------") $$ space
+          separator = space $$ ptext (sLit "-------------------") $$ space
 
 writeCmms :: Handle -> [Cmm] -> IO ()
 writeCmms handle cmms = printForC handle (pprCmms cmms)
 
 -----------------------------------------------------------------------------
 
-instance Outputable Cmm where
+instance (Outputable d, Outputable info, Outputable g)
+    => Outputable (GenCmm d info g) where
     ppr c = pprCmm c
 
-instance Outputable CmmTop where
+instance (Outputable d, Outputable info, Outputable i)
+       => Outputable (GenCmmTop d info i) where
     ppr t = pprTop t
 
-instance Outputable CmmBasicBlock where
+instance (Outputable instr) => Outputable (ListGraph instr) where
+    ppr (ListGraph blocks) = vcat (map ppr blocks)
+
+instance (Outputable instr) => Outputable (GenBasicBlock instr) where
     ppr b = pprBBlock b
 
 instance Outputable CmmStmt where
@@ -80,33 +85,40 @@ instance Outputable CmmExpr where
 instance Outputable CmmReg where
     ppr e = pprReg e
 
+instance Outputable CmmLit where
+    ppr l = pprLit l
+
+instance Outputable LocalReg where
+    ppr e = pprLocalReg e
+
 instance Outputable GlobalReg where
     ppr e = pprGlobalReg e
 
+instance Outputable CmmStatic where
+    ppr e = pprStatic e
+
+instance Outputable CmmInfo where
+    ppr e = pprInfo e
+
+
+
 -----------------------------------------------------------------------------
 
-pprCmm :: Cmm -> SDoc
+pprCmm :: (Outputable d, Outputable info, Outputable g) => GenCmm d info g -> SDoc
 pprCmm (Cmm tops) = vcat $ intersperse (text "") $ map pprTop tops
 
 -- --------------------------------------------------------------------------
--- Top level `procedure' blocks. The info tables, if not null, are
--- printed in the style of C--'s 'stackdata' declaration, just inside
--- the proc body, and are labelled with the procedure name ++ "_info".
+-- Top level `procedure' blocks.
 --
-pprTop :: CmmTop -> SDoc
-pprTop (CmmProc info lbl params blocks )
+pprTop         :: (Outputable d, Outputable info, Outputable i)
+       => GenCmmTop d info i -> SDoc
 
-  = vcat [ pprCLabel lbl <> parens (commafy $ map pprLocalReg params) <+> lbrace
-         , nest 8 $ pprInfo info lbl
-         , nest 4 $ vcat (map ppr blocks)
-         , rbrace ]
+pprTop (CmmProc info lbl params graph )
 
-  where
-    pprInfo [] _  = empty
-    pprInfo i label = 
-        (hang (pprCLabel (entryLblToInfoLbl label) <+> lbrace )
-            4 $ vcat (map pprStatic i))
-        $$ rbrace
+  = vcat [ pprCLabel lbl <> parens (commafy $ map ppr params) <+> lbrace
+         , nest 8 $ lbrace <+> ppr info $$ rbrace
+         , nest 4 $ ppr graph
+         , rbrace ]
 
 -- --------------------------------------------------------------------------
 -- We follow [1], 4.5
@@ -114,14 +126,81 @@ pprTop (CmmProc info lbl params blocks )
 --      section "data" { ... }
 --
 pprTop (CmmData section ds) = 
-    (hang (pprSection section <+> lbrace) 4 (vcat (map pprStatic ds)))
+    (hang (pprSection section <+> lbrace) 4 (vcat (map ppr ds)))
     $$ rbrace
 
+-- --------------------------------------------------------------------------
+instance Outputable CmmSafety where
+  ppr CmmUnsafe = ptext (sLit "_unsafe_call_")
+  ppr (CmmSafe srt) = ppr srt
+
+-- --------------------------------------------------------------------------
+-- Info tables. The current pretty printer needs refinement
+-- but will work for now.
+--
+-- For ideas on how to refine it, they used to be printed in the
+-- style of C--'s 'stackdata' declaration, just inside the proc body,
+-- and were labelled with the procedure name ++ "_info".
+pprInfo :: CmmInfo -> SDoc
+pprInfo (CmmInfo _gc_target update_frame CmmNonInfoTable) =
+    vcat [{-ptext (sLit "gc_target: ") <>
+                maybe (ptext (sLit "<none>")) pprBlockId gc_target,-}
+          ptext (sLit "update_frame: ") <>
+                maybe (ptext (sLit "<none>")) pprUpdateFrame update_frame]
+pprInfo (CmmInfo _gc_target update_frame
+         (CmmInfoTable (ProfilingInfo closure_type closure_desc) tag info)) =
+    vcat [{-ptext (sLit "gc_target: ") <>
+                maybe (ptext (sLit "<none>")) pprBlockId gc_target,-}
+          ptext (sLit "update_frame: ") <>
+                maybe (ptext (sLit "<none>")) pprUpdateFrame update_frame,
+          ptext (sLit "type: ") <> pprLit closure_type,
+          ptext (sLit "desc: ") <> pprLit closure_desc,
+          ptext (sLit "tag: ") <> integer (toInteger tag),
+          pprTypeInfo info]
+
+pprTypeInfo :: ClosureTypeInfo -> SDoc
+pprTypeInfo (ConstrInfo layout constr descr) =
+    vcat [ptext (sLit "ptrs: ") <> integer (toInteger (fst layout)),
+          ptext (sLit "nptrs: ") <> integer (toInteger (snd layout)),
+          ptext (sLit "constructor: ") <> integer (toInteger constr),
+          pprLit descr]
+pprTypeInfo (FunInfo layout srt fun_type arity _args slow_entry) =
+    vcat [ptext (sLit "ptrs: ") <> integer (toInteger (fst layout)),
+          ptext (sLit "nptrs: ") <> integer (toInteger (snd layout)),
+          ptext (sLit "srt: ") <> ppr srt,
+          ptext (sLit "fun_type: ") <> integer (toInteger fun_type),
+          ptext (sLit "arity: ") <> integer (toInteger arity),
+          --ptext (sLit "args: ") <> ppr args, -- TODO: needs to be printed
+          ptext (sLit "slow: ") <> pprLit slow_entry
+         ]
+pprTypeInfo (ThunkInfo layout srt) =
+    vcat [ptext (sLit "ptrs: ") <> integer (toInteger (fst layout)),
+          ptext (sLit "nptrs: ") <> integer (toInteger (snd layout)),
+          ptext (sLit "srt: ") <> ppr srt]
+pprTypeInfo (ThunkSelectorInfo offset srt) =
+    vcat [ptext (sLit "ptrs: ") <> integer (toInteger offset),
+          ptext (sLit "srt: ") <> ppr srt]
+pprTypeInfo (ContInfo stack srt) =
+    vcat [ptext (sLit "stack: ") <> ppr stack,
+          ptext (sLit "srt: ") <> ppr srt]
+
+pprUpdateFrame :: UpdateFrame -> SDoc
+pprUpdateFrame (UpdateFrame expr args) = 
+    hcat [ ptext (sLit "jump")
+         , space
+         , if isTrivialCmmExpr expr
+                then pprExpr expr
+                else case expr of
+                    CmmLoad (CmmReg _) _ -> pprExpr expr 
+                    _ -> parens (pprExpr expr)
+         , space
+         , parens  ( commafy $ map ppr args ) ]
+
 
 -- --------------------------------------------------------------------------
 -- Basic blocks look like assembly blocks.
 --      lbl: stmt ; stmt ; .. 
-pprBBlock :: CmmBasicBlock -> SDoc
+pprBBlock :: Outputable stmt => GenBasicBlock stmt -> SDoc
 pprBBlock (BasicBlock ident stmts) =
     hang (pprBlockId ident <> colon) 4 (vcat (map ppr stmts))
 
@@ -147,20 +226,39 @@ pprStmt stmt = case stmt of
 
     -- call "ccall" foo(x, y)[r1, r2];
     -- ToDo ppr volatile
-    CmmCall (CmmForeignCall fn cconv) results args _volatile ->
-        hcat [ ptext SLIT("call"), space, 
+    CmmCall (CmmCallee fn cconv) results args safety ret ->
+        hcat [ if null results
+                  then empty
+                  else parens (commafy $ map ppr results) <>
+                       ptext (sLit " = "),
+               ptext (sLit "foreign"), space, 
                doubleQuotes(ppr cconv), space,
                target fn, parens  ( commafy $ map ppr args ),
-               (if null results
-                    then empty
-                    else brackets( commafy $ map ppr results)), semi ]
+               brackets (ppr safety), 
+               case ret of CmmMayReturn -> empty
+                           CmmNeverReturns -> ptext (sLit " never returns"),
+               semi ]
         where
-            target (CmmLit lit) = pprLit lit
-            target fn'          = parens (ppr fn')
-
-    CmmCall (CmmPrim op) results args volatile ->
-        pprStmt (CmmCall (CmmForeignCall (CmmLit lbl) CCallConv)
-                        results args volatile)
+          ---- With the following three functions, I was going somewhere
+          ---- useful, but I don't remember where.  Probably making 
+          ---- emitted Cmm output look better. ---NR, 2 May 2008
+         _pp_lhs | null results = empty
+                 | otherwise    = commafy (map ppr_ar results) <+> equals
+               -- Don't print the hints on a native C-- call
+         ppr_ar arg = case cconv of
+                           CmmCallConv -> ppr (hintlessCmm arg)
+                           _           -> doubleQuotes (ppr $ cmmHint arg) <+>
+                                           ppr (hintlessCmm arg)
+         _pp_conv = case cconv of
+                     CmmCallConv -> empty
+                     _ -> ptext (sLit "foreign") <+> doubleQuotes (ppr cconv)
+
+          target (CmmLit lit) = pprLit lit
+          target fn'          = parens (ppr fn')
+
+    CmmCall (CmmPrim op) results args safety ret ->
+        pprStmt (CmmCall (CmmCallee (CmmLit lbl) CCallConv)
+                        results args safety ret)
         where
           lbl = CmmLabel (mkForeignLabel (mkFastString (show op)) Nothing False)
 
@@ -177,7 +275,7 @@ pprStmt stmt = case stmt of
 --
 genBranch :: BlockId -> SDoc
 genBranch ident = 
-    ptext SLIT("goto") <+> pprBlockId ident <> semi
+    ptext (sLit "goto") <+> pprBlockId ident <> semi
 
 -- --------------------------------------------------------------------------
 -- Conditional. [1], section 6.4
@@ -186,9 +284,9 @@ genBranch ident =
 --
 genCondBranch :: CmmExpr -> BlockId -> SDoc
 genCondBranch expr ident =
-    hsep [ ptext SLIT("if")
+    hsep [ ptext (sLit "if")
          , parens(ppr expr)
-         , ptext SLIT("goto")
+         , ptext (sLit "goto")
          , pprBlockId ident <> semi ]
 
 -- --------------------------------------------------------------------------
@@ -196,28 +294,35 @@ genCondBranch expr ident =
 --
 --     jump foo(a, b, c);
 --
-genJump :: CmmExpr -> [(CmmExpr, MachHint)] -> SDoc
+genJump :: CmmExpr -> [CmmHinted CmmExpr] -> SDoc
 genJump expr args = 
 
-    hcat [ ptext SLIT("jump")
+    hcat [ ptext (sLit "jump")
          , space
          , if isTrivialCmmExpr expr
                 then pprExpr expr
                 else case expr of
                     CmmLoad (CmmReg _) _ -> pprExpr expr 
                     _ -> parens (pprExpr expr)
-         , parens  ( commafy $ map ppr args )
+         , space
+         , parens  ( commafy $ map pprHinted args )
          , semi ]
 
+pprHinted :: Outputable a => (CmmHinted a) -> SDoc
+pprHinted (CmmHinted a NoHint)     = ppr a
+pprHinted (CmmHinted a PtrHint)    = quotes(text "address") <+> ppr a
+pprHinted (CmmHinted a SignedHint) = quotes(text "signed")  <+> ppr a
+pprHinted (CmmHinted a FloatHint)  = quotes(text "float")   <+> ppr a
+
 -- --------------------------------------------------------------------------
 -- Return from a function. [1], Section 6.8.2 of version 1.128
 --
 --     return (a, b, c);
 --
-genReturn :: [(CmmExpr, MachHint)] -> SDoc
+genReturn :: [CmmHinted CmmExpr] -> SDoc
 genReturn args = 
 
-    hcat [ ptext SLIT("return")
+    hcat [ ptext (sLit "return")
          , space
          , parens  ( commafy $ map ppr args )
          , semi ]
@@ -234,13 +339,13 @@ genSwitch expr maybe_ids
 
     = let pairs = groupBy snds (zip [0 .. ] maybe_ids )
 
-      in hang (hcat [ ptext SLIT("switch [0 .. ") 
+      in hang (hcat [ ptext (sLit "switch [0 .. ") 
                     , int (length maybe_ids - 1)
-                    , ptext SLIT("] ")
+                    , ptext (sLit "] ")
                     , if isTrivialCmmExpr expr
                         then pprExpr expr
                         else parens (pprExpr expr)
-                    , ptext SLIT(" {") 
+                    , ptext (sLit " {") 
                     ]) 
             4 (vcat ( map caseify pairs )) $$ rbrace
 
@@ -248,14 +353,14 @@ genSwitch expr maybe_ids
       snds a b = (snd a) == (snd b)
 
       caseify :: [(Int,Maybe BlockId)] -> SDoc
-      caseify ixs@((i,Nothing):_)
-        = ptext SLIT("/* impossible: ") <> hcat (intersperse comma (map (int.fst) ixs))
-               <> ptext SLIT(" */")
+      caseify ixs@((_,Nothing):_)
+        = ptext (sLit "/* impossible: ") <> hcat (intersperse comma (map (int.fst) ixs))
+               <> ptext (sLit " */")
       caseify as 
         = let (is,ids) = unzip as 
-          in hsep [ ptext SLIT("case")
+          in hsep [ ptext (sLit "case")
                   , hcat (punctuate comma (map int is))
-                  , ptext SLIT(": goto")
+                  , ptext (sLit ": goto")
                   , pprBlockId (head [ id | Just id <- ids]) <> semi ]
 
 -- --------------------------------------------------------------------------
@@ -286,16 +391,19 @@ pprExpr e
 -- a default conservative behaviour.
 
 -- %nonassoc '>=' '>' '<=' '<' '!=' '=='
+pprExpr1, pprExpr7, pprExpr8 :: CmmExpr -> SDoc
 pprExpr1 (CmmMachOp op [x,y]) | Just doc <- infixMachOp1 op
    = pprExpr7 x <+> doc <+> pprExpr7 y
 pprExpr1 e = pprExpr7 e
 
-infixMachOp1 (MO_Eq     _) = Just (ptext SLIT("=="))
-infixMachOp1 (MO_Ne     _) = Just (ptext SLIT("!="))
-infixMachOp1 (MO_Shl    _) = Just (ptext SLIT("<<"))
-infixMachOp1 (MO_U_Shr  _) = Just (ptext SLIT(">>"))
-infixMachOp1 (MO_U_Ge   _) = Just (ptext SLIT(">="))
-infixMachOp1 (MO_U_Le   _) = Just (ptext SLIT("<="))
+infixMachOp1, infixMachOp7, infixMachOp8 :: MachOp -> Maybe SDoc
+
+infixMachOp1 (MO_Eq     _) = Just (ptext (sLit "=="))
+infixMachOp1 (MO_Ne     _) = Just (ptext (sLit "!="))
+infixMachOp1 (MO_Shl    _) = Just (ptext (sLit "<<"))
+infixMachOp1 (MO_U_Shr  _) = Just (ptext (sLit ">>"))
+infixMachOp1 (MO_U_Ge   _) = Just (ptext (sLit ">="))
+infixMachOp1 (MO_U_Le   _) = Just (ptext (sLit "<="))
 infixMachOp1 (MO_U_Gt   _) = Just (char '>')
 infixMachOp1 (MO_U_Lt   _) = Just (char '<')
 infixMachOp1 _             = Nothing
@@ -386,8 +494,9 @@ pprLit lit = case lit of
     CmmLabelDiffOff clbl1 clbl2 i -> pprCLabel clbl1 <> char '-'  
                                   <> pprCLabel clbl2 <> ppr_offset i
 
-pprLit1 lit@(CmmLabelOff clbl i) = parens (pprLit lit)
-pprLit1 lit                      = pprLit lit
+pprLit1 :: CmmLit -> SDoc
+pprLit1 lit@(CmmLabelOff {}) = parens (pprLit lit)
+pprLit1 lit                  = pprLit lit
 
 ppr_offset :: Int -> SDoc
 ppr_offset i
@@ -402,7 +511,7 @@ ppr_offset i
 --
 pprStatic :: CmmStatic -> SDoc
 pprStatic s = case s of
-    CmmStaticLit lit   -> nest 4 $ ptext SLIT("const") <+> pprLit lit <> semi
+    CmmStaticLit lit   -> nest 4 $ ptext (sLit "const") <+> pprLit lit <> semi
     CmmUninitialised i -> nest 4 $ text "I8" <> brackets (int i)
     CmmAlign i         -> nest 4 $ text "align" <+> int i
     CmmDataLabel clbl  -> pprCLabel clbl <> colon
@@ -421,10 +530,14 @@ pprReg r
 -- We only print the type of the local reg if it isn't wordRep
 --
 pprLocalReg :: LocalReg -> SDoc
-pprLocalReg (LocalReg uniq rep) 
-    = hcat [ char '_', ppr uniq, 
-            (if rep == wordRep 
-                then empty else dcolon <> ppr rep) ]
+pprLocalReg (LocalReg uniq rep follow) 
+    = hcat [ char '_', ppr uniq, ty ] where
+  ty = if rep == wordRep && follow == GCKindNonPtr
+                then empty
+                else dcolon <> ptr <> ppr rep
+  ptr = if follow == GCKindNonPtr
+                then empty
+                else doubleQuotes (text "ptr")
 
 -- needs to be kept in syn with Cmm.hs.GlobalReg
 --
@@ -435,33 +548,34 @@ pprGlobalReg gr
         FloatReg   n   -> char 'F' <> int n
         DoubleReg  n   -> char 'D' <> int n
         LongReg    n   -> char 'L' <> int n
-        Sp             -> ptext SLIT("Sp")
-        SpLim          -> ptext SLIT("SpLim")
-        Hp             -> ptext SLIT("Hp")
-        HpLim          -> ptext SLIT("HpLim")
-        CurrentTSO     -> ptext SLIT("CurrentTSO")
-        CurrentNursery -> ptext SLIT("CurrentNursery")
-        HpAlloc        -> ptext SLIT("HpAlloc")
-        GCEnter1       -> ptext SLIT("stg_gc_enter_1")
-        GCFun          -> ptext SLIT("stg_gc_fun")
-        BaseReg        -> ptext SLIT("BaseReg")
-        PicBaseReg     -> ptext SLIT("PicBaseReg")
+        Sp             -> ptext (sLit "Sp")
+        SpLim          -> ptext (sLit "SpLim")
+        Hp             -> ptext (sLit "Hp")
+        HpLim          -> ptext (sLit "HpLim")
+        CurrentTSO     -> ptext (sLit "CurrentTSO")
+        CurrentNursery -> ptext (sLit "CurrentNursery")
+        HpAlloc        -> ptext (sLit "HpAlloc")
+        GCEnter1       -> ptext (sLit "stg_gc_enter_1")
+        GCFun          -> ptext (sLit "stg_gc_fun")
+        BaseReg        -> ptext (sLit "BaseReg")
+        PicBaseReg     -> ptext (sLit "PicBaseReg")
 
 -- --------------------------------------------------------------------------
 -- data sections
 --
 pprSection :: Section -> SDoc
 pprSection s = case s of
-    Text              -> section <+> doubleQuotes (ptext SLIT("text"))
-    Data              -> section <+> doubleQuotes (ptext SLIT("data"))
-    ReadOnlyData      -> section <+> doubleQuotes (ptext SLIT("readonly"))
+    Text              -> section <+> doubleQuotes (ptext (sLit "text"))
+    Data              -> section <+> doubleQuotes (ptext (sLit "data"))
+    ReadOnlyData      -> section <+> doubleQuotes (ptext (sLit "readonly"))
+    ReadOnlyData16    -> section <+> doubleQuotes (ptext (sLit "readonly16"))
     RelocatableReadOnlyData
-                      -> section <+> doubleQuotes (ptext SLIT("relreadonly"))
-    UninitialisedData -> section <+> doubleQuotes (ptext SLIT("uninitialised"))
+                      -> section <+> doubleQuotes (ptext (sLit "relreadonly"))
+    UninitialisedData -> section <+> doubleQuotes (ptext (sLit "uninitialised"))
     OtherSection s'   -> section <+> doubleQuotes (text s')
  where
-    section = ptext SLIT("section")
-       
+    section = ptext (sLit "section")
+
 -- --------------------------------------------------------------------------
 -- Basic block ids
 --
@@ -471,5 +585,4 @@ pprBlockId b = ppr $ getUnique b
 -----------------------------------------------------------------------------
 
 commafy :: [SDoc] -> SDoc
-commafy xs = hsep $ punctuate comma xs
-
+commafy xs = fsep $ punctuate comma xs