Comments only
[ghc-hetmet.git] / compiler / cmm / ZipCfgCmmRep.hs
index 71e206e..d4ed3cf 100644 (file)
@@ -1,4 +1,4 @@
-{-# OPTIONS -Wall -fno-warn-name-shadowing #-}
+
 
 -- This module is pure representation and should be imported only by
 -- clients that need to manipulate representation and know what
@@ -7,6 +7,7 @@
 
 module ZipCfgCmmRep
   ( CmmZ, CmmTopZ, CmmGraph, CmmBlock, CmmAGraph, Middle(..), Last(..), Convention(..)
+  , ValueDirection(..)
   )
 where
 
@@ -14,8 +15,8 @@ where
 
 import CmmExpr
 import Cmm ( GenCmm(..), GenCmmTop(..), CmmStatic, CmmInfo
-           , CmmCallTarget(..), CmmActuals, CmmFormalsWithoutKinds, CmmFormals
-           , CmmStmt(CmmJump, CmmSwitch) -- imported in order to call ppr
+           , CmmCallTarget(..), CmmActuals, CmmFormals
+           , CmmStmt(CmmSwitch) -- imported in order to call ppr
            )
 import PprCmm()
 
@@ -29,10 +30,12 @@ import ZipCfg
 import MkZipCfg
 
 import Maybes
-import Outputable hiding (empty)
-import qualified Outputable as PP
+import Outputable
 import Prelude hiding (zip, unzip, last)
 
+----------------------------------------------------------------------
+----- Type synonyms and definitions
+
 type CmmGraph  = LGraph Middle Last
 type CmmAGraph = AGraph Middle Last
 type CmmBlock  = Block  Middle Last
@@ -50,37 +53,41 @@ data Middle
 
   | MidUnsafeCall                -- An "unsafe" foreign call;
      CmmCallTarget               -- just a fat machine instructoin
-     CmmFormals              -- zero or more results
+     CmmFormals                  -- zero or more results
      CmmActuals                  -- zero or more arguments
 
-  | CopyIn    -- Move parameters or results from conventional locations to registers
-              -- Note [CopyIn invariant]
+  | CopyIn    -- Move incoming parameters or results from conventional
+              -- locations to registers.  Note [CopyIn invariant]
         Convention 
-        CmmFormals      
+        CmmFormals      -- eventually [CmmKind] will be used only for foreign
+                        -- calls and will migrate into 'Convention' (helping to
+                        -- drain "the swamp"), leaving this as [LocalReg]
         C_SRT           -- Static things kept alive by this block
-  | CopyOut Convention CmmFormals 
-
-data Last
-  = LastReturn CmmActuals          -- Return from a function,
-                                  -- with these return values.
 
-  | LastJump   CmmExpr CmmActuals
-        -- Tail call to another procedure
+  | CopyOut Convention CmmActuals
+              -- Move outgoing parameters or results from registers to
+              -- conventional locations.  Every 'LastReturn',
+              -- 'LastJump', or 'LastCall' must be dominated by a
+              -- matching 'CopyOut' in the same basic block.
+              -- As above, '[CmmKind]' will migrate into the foreign calling
+              -- convention, leaving the actuals as '[CmmExpr]'.
 
-  | LastBranch BlockId CmmFormalsWithoutKinds
-        -- To another block in the same procedure
-        -- The parameters are unused at present.
-
-  | LastCall {                   -- A call (native or safe foreign)
-        cml_target :: CmmCallTarget,
-        cml_actual :: CmmActuals,        -- Zero or more arguments
-        cml_next   :: Maybe BlockId }  -- BlockId of continuation, if call returns
+data Last
+  = LastBranch BlockId  -- Goto another block in the same procedure
 
   | LastCondBranch {            -- conditional branch
         cml_pred :: CmmExpr,
         cml_true, cml_false :: BlockId
     }
 
+  | LastReturn          -- Return from a function; values in a previous CopyOut node
+
+  | LastJump CmmExpr    -- Tail call to another procedure; args in a CopyOut node
+
+  | LastCall {                   -- A call (native or safe foreign); args in CopyOut node
+        cml_target :: CmmExpr,   -- never a CmmPrim to a CallishMachOp!
+        cml_cont   :: Maybe BlockId }  -- BlockId of continuation, if call returns
+
   | LastSwitch CmmExpr [Maybe BlockId]   -- Table branch
         -- The scrutinee is zero-based; 
         --      zero -> first block
@@ -88,62 +95,66 @@ data Last
         -- Undefined outside range, and when there's a Nothing
 
 data Convention
-  = Argument CCallConv  -- Used for function formal params
-  | Result CCallConv    -- Used for function results
-
-  | Local       -- Used for control transfers within a (pre-CPS) procedure
-                -- All jump sites known, never pushed on the stack (hence no SRT)
-                -- You can choose whatever calling convention
-                -- you please (provided you make sure
-                -- all the call sites agree)!
+  = ConventionStandard CCallConv ValueDirection
+  | ConventionPrivate
+                -- Used for control transfers within a (pre-CPS) procedure All
+                -- jump sites known, never pushed on the stack (hence no SRT)
+                -- You can choose whatever calling convention you please
+                -- (provided you make sure all the call sites agree)!
+                -- This data type eventually to be extended to record the convention. 
+
   deriving Eq
 
--- ^ In a complete LGraph for a procedure, the [[Exit]] node should not
--- appear, but it is useful in a subgraph (e.g., replacement for a node).
+data ValueDirection = Arguments | Results
+  -- Arguments go with procedure definitions, jumps, and arguments to calls
+  -- Results go with returns and with results of calls.
+  deriving Eq
 
 {-
 Note [CopyIn invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~
-In principle, CopyIn ought to be a First node, but in practice, the
+One might wish for CopyIn to be a First node, but in practice, the
 possibility raises all sorts of hairy issues with graph splicing,
 rewriting, and so on.  In the end, NR finds it better to make the
-placement of CopyIn a dynamic invariant.  This change will complicate
-the dataflow fact for the proc-point calculation, but it should make
-things easier in many other respects.  
+placement of CopyIn a dynamic invariant; it should normally be the first
+Middle node in the basic block in which it occurs.
 -}
 
+----------------------------------------------------------------------
+----- Instance declarations for control flow
+
 instance HavingSuccessors Last where
     succs = cmmSuccs
     fold_succs = fold_cmm_succs
 
 instance LastNode Last where
-    mkBranchNode id = LastBranch id []
-    isBranchNode (LastBranch _ []) = True
+    mkBranchNode id = LastBranch id
+    isBranchNode (LastBranch _) = True
     isBranchNode _ = False
-    branchNodeTarget (LastBranch id []) = id
+    branchNodeTarget (LastBranch id) = id
     branchNodeTarget _ = panic "asked for target of non-branch"
 
 cmmSuccs :: Last -> [BlockId]
-cmmSuccs (LastReturn {})          = []
-cmmSuccs (LastJump {})            = [] 
-cmmSuccs (LastBranch id _)        = [id]
-cmmSuccs (LastCall _ _ (Just id)) = [id]
-cmmSuccs (LastCall _ _ Nothing)   = []
-cmmSuccs (LastCondBranch _ t f)   = [f, t]  -- meets layout constraint
-cmmSuccs (LastSwitch _ edges)     = catMaybes edges
+cmmSuccs (LastReturn {})        = []
+cmmSuccs (LastJump {})          = [] 
+cmmSuccs (LastBranch id)        = [id]
+cmmSuccs (LastCall _ (Just id)) = [id]
+cmmSuccs (LastCall _ Nothing)   = []
+cmmSuccs (LastCondBranch _ t f) = [f, t]  -- meets layout constraint
+cmmSuccs (LastSwitch _ edges)   = catMaybes edges
 
 fold_cmm_succs :: (BlockId -> a -> a) -> Last -> a -> a
 fold_cmm_succs _f (LastReturn {})          z = z
 fold_cmm_succs _f (LastJump {})            z = z
-fold_cmm_succs  f (LastBranch id _)        z = f id z
-fold_cmm_succs  f (LastCall _ _ (Just id)) z = f id z
-fold_cmm_succs _f (LastCall _ _ Nothing)   z = z
+fold_cmm_succs  f (LastBranch id)          z = f id z
+fold_cmm_succs  f (LastCall _ (Just id))   z = f id z
+fold_cmm_succs _f (LastCall _ Nothing)     z = z
 fold_cmm_succs  f (LastCondBranch _ te fe) z = f te (f fe z)
 fold_cmm_succs  f (LastSwitch _ edges)     z = foldl (flip f) z $ catMaybes edges
 
 
-----------------------------------------------------------------
--- prettyprinting (avoids recursive imports)
+----------------------------------------------------------------------
+----- Instance declarations for prettyprinting (avoids recursive imports)
 
 instance Outputable Middle where
     ppr s = pprMiddle s
@@ -157,12 +168,10 @@ instance Outputable Convention where
 instance DF.DebugNodes Middle Last
 
 instance Outputable CmmGraph where
-    ppr = pprCmmGraphAsRep
+    ppr = pprLgraph
 
-pprCmmGraphAsRep :: CmmGraph -> SDoc
-pprCmmGraphAsRep g = vcat (map ppr_block blocks)
-    where blocks = postorder_dfs g
-          ppr_block (Block id tail) = hang (ppr id <> colon) 4 (ppr tail)
+debugPpr :: Bool
+debugPpr = debugIsOn
 
 pprMiddle :: Middle -> SDoc    
 pprMiddle stmt = (case stmt of
@@ -175,9 +184,8 @@ pprMiddle stmt = (case stmt of
              ptext SLIT("foreign") <+> doubleQuotes(ppr conv) <+> ptext SLIT("...")
 
     CopyOut conv args ->
-        if null args then PP.empty
-        else ptext SLIT("CopyOut") <+> doubleQuotes(ppr conv) <+>
-             parens (commafy (map pprHinted args))
+        ptext SLIT("next, pass") <+> doubleQuotes(ppr conv) <+>
+        parens (commafy (map pprHinted args))
 
     --  // text
     MidComment s -> text "//" <+> ftext s
@@ -194,7 +202,7 @@ pprMiddle stmt = (case stmt of
     -- ToDo ppr volatile
     MidUnsafeCall (CmmCallee fn cconv) results args ->
         hcat [ if null results
-                  then PP.empty
+                  then empty
                   else parens (commafy $ map ppr results) <>
                        ptext SLIT(" = "),
                ptext SLIT("call"), space, 
@@ -209,15 +217,17 @@ pprMiddle stmt = (case stmt of
         pprMiddle (MidUnsafeCall (CmmCallee (CmmLit lbl) CCallConv) results args)
         where
           lbl = CmmLabel (mkForeignLabel (mkFastString (show op)) Nothing False)
-  ) <+> text "//" <+>
-  case stmt of
-    MidNop {} -> text "MidNop"
-    CopyIn {} -> text "CopyIn"
-    CopyOut {} -> text "CopyOut"
-    MidComment {} -> text "MidComment"
-    MidAssign {} -> text "MidAssign"
-    MidStore {} -> text "MidStore"
-    MidUnsafeCall {} -> text "MidUnsafeCall"
+  ) <>
+  if debugPpr then empty
+  else text " //" <+>
+       case stmt of
+         MidNop {}     -> text "MidNop"
+         CopyIn {}     -> text "CopyIn"
+         CopyOut {}    -> text "CopyOut"
+         MidComment {} -> text "MidComment"
+         MidAssign {}  -> text "MidAssign"
+         MidStore {}   -> text "MidStore"
+         MidUnsafeCall {} -> text "MidUnsafeCall"
 
 
 pprHinted :: Outputable a => (a, MachHint) -> SDoc
@@ -228,45 +238,37 @@ pprHinted (a, FloatHint)  = doubleQuotes (text "float")   <+> ppr a
 
 pprLast :: Last -> SDoc    
 pprLast stmt = (case stmt of
-    LastBranch ident args     -> genBranchWithArgs ident args
+    LastBranch ident          -> ptext SLIT("goto") <+> ppr ident <> semi
     LastCondBranch expr t f   -> genFullCondBranch expr t f
-    LastJump expr params      -> ppr $ CmmJump expr params
-    LastReturn results        -> hcat [ ptext SLIT("return"), space
-                                      , parens ( commafy $ map pprHinted results )
-                                      , semi ]
+    LastJump expr             -> hcat [ ptext SLIT("jump"), space, pprFun expr
+                                      , ptext SLIT("(...)"), semi]
+    LastReturn                -> hcat [ ptext SLIT("return"), space 
+                                      , ptext SLIT("(...)"), semi]
     LastSwitch arg ids        -> ppr $ CmmSwitch arg ids
-    LastCall tgt params k     -> genCall tgt params k
-  ) <+> text "//" <+>
-  case stmt of
-    LastBranch {} -> text "LastBranch"
-    LastCondBranch {} -> text "LastCondBranch"
-    LastJump {} -> text "LastJump"
-    LastReturn {} -> text "LastReturn"
-    LastSwitch {} -> text "LastSwitch"
-    LastCall {} -> text "LastCall"
-
-
-genCall :: CmmCallTarget -> CmmActuals -> Maybe BlockId -> SDoc
-genCall (CmmCallee fn cconv) args k =
-        hcat [ ptext SLIT("foreign"), space
-             , doubleQuotes(ppr cconv), space
-             , target fn, parens  ( commafy $ map pprHinted args ), space
+    LastCall tgt k            -> genBareCall tgt k
+  ) <>
+  if debugPpr then empty
+  else text " //" <+>
+       case stmt of
+         LastBranch {} -> text "LastBranch"
+         LastCondBranch {} -> text "LastCondBranch"
+         LastJump {} -> text "LastJump"
+         LastReturn {} -> text "LastReturn"
+         LastSwitch {} -> text "LastSwitch"
+         LastCall {} -> text "LastCall"
+
+genBareCall :: CmmExpr -> Maybe BlockId -> SDoc
+genBareCall fn k =
+        hcat [ ptext SLIT("call"), space
+             , pprFun fn, ptext SLIT("(...)"), space
              , case k of Nothing -> ptext SLIT("never returns")
                          Just k -> ptext SLIT("returns to") <+> ppr k
              , semi ]
         where
-            target t@(CmmLit _) = ppr t
-            target fn'          = parens (ppr fn')
-
-genCall (CmmPrim op) args k =
-    hcat [ text "%", text (show op), parens  ( commafy $ map pprHinted args ),
-           ptext SLIT("returns to"), space, ppr k,
-           semi ]
 
-genBranchWithArgs :: (Outputable id, Outputable arg) => id -> [arg] -> SDoc
-genBranchWithArgs ident [] = ptext SLIT("goto") <+> ppr ident <> semi
-genBranchWithArgs ident args = ptext SLIT("goto") <+> ppr ident <+>
-                               parens (commafy (map ppr args)) <> semi
+pprFun :: CmmExpr -> SDoc
+pprFun f@(CmmLit _) = ppr f
+pprFun f = parens (ppr f)
 
 genFullCondBranch :: Outputable id => CmmExpr -> id -> id -> SDoc
 genFullCondBranch expr t f =
@@ -279,9 +281,8 @@ genFullCondBranch expr t f =
          ]
 
 pprConvention :: Convention -> SDoc
-pprConvention (Argument c) = ppr c
-pprConvention (Result c) = ppr c
-pprConvention Local = text "<local>"
+pprConvention (ConventionStandard c _) = ppr c
+pprConvention (ConventionPrivate {}  ) = text "<private-convention>"
 
 commafy :: [SDoc] -> SDoc
 commafy xs = hsep $ punctuate comma xs