X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fcmm%2FPprCmm.hs;h=dbfd20e424b678e11a5608f4e030154d23485332;hp=714c80e2d37d1a20d032c1afd9353cafb9071a12;hb=0d80489c9b9f2421f65d8dd86c1e50c6bb429715;hpb=5e2dabea8de9ed9c6064bf8ce1570f5ca5742179 diff --git a/compiler/cmm/PprCmm.hs b/compiler/cmm/PprCmm.hs index 714c80e..dbfd20e 100644 --- a/compiler/cmm/PprCmm.hs +++ b/compiler/cmm/PprCmm.hs @@ -32,12 +32,12 @@ -- 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 BlockId import Cmm import CmmUtils import MachOp @@ -51,25 +51,29 @@ import FastString import Data.List import System.IO import Data.Maybe -import Data.Char -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 @@ -81,33 +85,43 @@ 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 Area where + ppr e = pprArea 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 @@ -115,14 +129,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 "")) pprBlockId gc_target,-} + ptext (sLit "update_frame: ") <> + maybe (ptext (sLit "")) 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 "")) pprBlockId gc_target,-} + ptext (sLit "update_frame: ") <> + maybe (ptext (sLit "")) 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)) @@ -148,26 +229,46 @@ 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 (kindlessCmm arg) + _ -> doubleQuotes (ppr $ cmmKind arg) <+> + ppr (kindlessCmm 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) CmmBranch ident -> genBranch ident CmmCondBranch expr ident -> genCondBranch expr ident CmmJump expr params -> genJump expr params + CmmReturn params -> genReturn params CmmSwitch arg ids -> genSwitch arg ids -- -------------------------------------------------------------------------- @@ -177,7 +278,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 +287,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,22 +297,38 @@ genCondBranch expr ident = -- -- jump foo(a, b, c); -- -genJump :: CmmExpr -> [LocalReg] -> SDoc -genJump expr actuals = +genJump :: CmmExpr -> [CmmKinded 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) - , pprActuals actuals + , space + , parens ( commafy $ map pprKinded args ) , semi ] - where - pprActuals [] = empty - pprActuals as = parens ( commafy $ map pprLocalReg as ) +pprKinded :: Outputable a => (CmmKinded a) -> SDoc +pprKinded (CmmKinded a NoHint) = ppr a +pprKinded (CmmKinded a PtrHint) = quotes(text "address") <+> ppr a +pprKinded (CmmKinded a SignedHint) = quotes(text "signed") <+> ppr a +pprKinded (CmmKinded 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 :: [CmmKinded CmmExpr] -> SDoc +genReturn args = + + hcat [ ptext (sLit "return") + , space + , parens ( commafy $ map ppr args ) + , semi ] -- -------------------------------------------------------------------------- -- Tabled jump to local label @@ -225,13 +342,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 @@ -239,14 +356,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 ] -- -------------------------------------------------------------------------- @@ -277,16 +394,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 @@ -318,7 +438,8 @@ pprExpr9 e = CmmLit lit -> pprLit1 lit CmmLoad expr rep -> ppr rep <> brackets( ppr expr ) CmmReg reg -> ppr reg - CmmRegOff reg off -> parens (ppr reg <+> char '+' <+> int off) + CmmRegOff reg off -> parens (ppr reg <+> char '+' <+> int off) + CmmStackSlot a off -> parens (ppr a <+> char '+' <+> int off) CmmMachOp mop args -> genMachOp mop args genMachOp :: MachOp -> [CmmExpr] -> SDoc @@ -339,7 +460,10 @@ genMachOp mop args || isJust (infixMachOp7 mop) || isJust (infixMachOp8 mop) = parens (pprExpr (CmmMachOp mop args)) - | otherwise = char '%' <> pprMachOp mop <> parens (commafy (map pprExpr args)) + | otherwise = char '%' <> ppr_op <> parens (commafy (map pprExpr args)) + where ppr_op = text (map (\c -> if c == ' ' then '_' else c) + (show mop)) + -- replace spaces in (show mop) with underscores, -- -- Unsigned ops on the word size of the machine get nice symbols. @@ -374,8 +498,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 @@ -390,12 +515,11 @@ 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 - CmmString s' -> nest 4 $ text "I8[]" <+> - doubleQuotes (text (map (chr.fromIntegral) s')) + CmmString s' -> nest 4 $ text "I8[]" <+> text (show s') -- -------------------------------------------------------------------------- -- Registers, whether local (temps) or global @@ -403,17 +527,27 @@ pprStatic s = case s of pprReg :: CmmReg -> SDoc pprReg r = case r of - CmmLocal local -> pprLocalReg local + CmmLocal local -> pprLocalReg local CmmGlobal global -> pprGlobalReg global -- -- 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") + +-- Stack areas +pprArea :: Area -> SDoc +pprArea (RegSlot r) = hcat [ text "slot<", ppr r, text ">" ] +pprArea (CallArea id n n') = + hcat [ text "callslot<", ppr id, char '+', ppr n, char '/', ppr n', text ">" ] -- needs to be kept in syn with Cmm.hs.GlobalReg -- @@ -424,33 +558,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 -- @@ -460,5 +595,4 @@ pprBlockId b = ppr $ getUnique b ----------------------------------------------------------------------------- commafy :: [SDoc] -> SDoc -commafy xs = hsep $ punctuate comma xs - +commafy xs = fsep $ punctuate comma xs