{-# LANGUAGE GADTs #-}
module Debug (
  DebugBlock(..), dblIsEntry,
  cmmDebugGen,
  cmmDebugLabels,
  cmmDebugLink,
  debugToMap,
  
  UnwindTable, UnwindPoint(..),
  UnwindExpr(..), toUnwindExpr
  ) where
import GhcPrelude
import BlockId
import CLabel
import Cmm
import CmmUtils
import CoreSyn
import FastString      ( nilFS, mkFastString )
import Module
import Outputable
import PprCore         ()
import PprCmmExpr      ( pprExpr )
import SrcLoc
import Util            ( seqList )
import Hoopl.Block
import Hoopl.Collections
import Hoopl.Graph
import Hoopl.Label
import Data.Maybe
import Data.List     ( minimumBy, nubBy )
import Data.Ord      ( comparing )
import qualified Data.Map as Map
import Data.Either   ( partitionEithers )
data DebugBlock =
  DebugBlock
  { DebugBlock -> Label
dblProcedure  :: !Label        
  , DebugBlock -> Label
dblLabel      :: !Label        
  , DebugBlock -> CLabel
dblCLabel     :: !CLabel       
  , DebugBlock -> Bool
dblHasInfoTbl :: !Bool         
  , DebugBlock -> Maybe DebugBlock
dblParent     :: !(Maybe DebugBlock)
    
  , DebugBlock -> [CmmTickish]
dblTicks      :: ![CmmTickish] 
  , DebugBlock -> Maybe CmmTickish
dblSourceTick
            :: !(Maybe CmmTickish) 
  , DebugBlock -> Maybe Int
dblPosition   :: !(Maybe Int)  
                                   
                                   
  , DebugBlock -> [UnwindPoint]
dblUnwind     :: [UnwindPoint]
  , DebugBlock -> [DebugBlock]
dblBlocks     :: ![DebugBlock] 
  }
dblIsEntry :: DebugBlock -> Bool
dblIsEntry :: DebugBlock -> Bool
dblIsEntry blk :: DebugBlock
blk = DebugBlock -> Label
dblProcedure DebugBlock
blk Label -> Label -> Bool
forall a. Eq a => a -> a -> Bool
== DebugBlock -> Label
dblLabel DebugBlock
blk
instance Outputable DebugBlock where
  ppr :: DebugBlock -> SDoc
ppr blk :: DebugBlock
blk = (if DebugBlock -> Label
dblProcedure DebugBlock
blk Label -> Label -> Bool
forall a. Eq a => a -> a -> Bool
== DebugBlock -> Label
dblLabel DebugBlock
blk
             then String -> SDoc
text "proc "
             else if DebugBlock -> Bool
dblHasInfoTbl DebugBlock
blk
                  then String -> SDoc
text "pp-blk "
                  else String -> SDoc
text "blk ") SDoc -> SDoc -> SDoc
<>
            Label -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DebugBlock -> Label
dblLabel DebugBlock
blk) SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DebugBlock -> CLabel
dblCLabel DebugBlock
blk)) SDoc -> SDoc -> SDoc
<+>
            (SDoc -> (CmmTickish -> SDoc) -> Maybe CmmTickish -> SDoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe SDoc
empty CmmTickish -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DebugBlock -> Maybe CmmTickish
dblSourceTick DebugBlock
blk)) SDoc -> SDoc -> SDoc
<+>
            (SDoc -> (Int -> SDoc) -> Maybe Int -> SDoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> SDoc
text "removed") ((String -> SDoc
text "pos " SDoc -> SDoc -> SDoc
<>) (SDoc -> SDoc) -> (Int -> SDoc) -> Int -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr)
                   (DebugBlock -> Maybe Int
dblPosition DebugBlock
blk)) SDoc -> SDoc -> SDoc
<+>
            ([UnwindPoint] -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DebugBlock -> [UnwindPoint]
dblUnwind DebugBlock
blk)) SDoc -> SDoc -> SDoc
<+>
            (if [DebugBlock] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
blk) then SDoc
empty else [DebugBlock] -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
blk))
type BlockContext = (CmmBlock, RawCmmDecl)
cmmDebugGen :: ModLocation -> RawCmmGroup -> [DebugBlock]
cmmDebugGen :: ModLocation -> RawCmmGroup -> [DebugBlock]
cmmDebugGen modLoc :: ModLocation
modLoc decls :: RawCmmGroup
decls = (CmmTickScope -> DebugBlock) -> [CmmTickScope] -> [DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe CmmTickish -> CmmTickScope -> DebugBlock
blocksForScope Maybe CmmTickish
forall a. Maybe a
Nothing) [CmmTickScope]
topScopes
  where
      blockCtxs :: Map.Map CmmTickScope [BlockContext]
      blockCtxs :: Map CmmTickScope [BlockContext]
blockCtxs = RawCmmGroup -> Map CmmTickScope [BlockContext]
blockContexts RawCmmGroup
decls
      
      
      (topScopes :: [CmmTickScope]
topScopes, childScopes :: [(CmmTickScope, CmmTickScope)]
childScopes)
        = [Either CmmTickScope (CmmTickScope, CmmTickScope)]
-> ([CmmTickScope], [(CmmTickScope, CmmTickScope)])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either CmmTickScope (CmmTickScope, CmmTickScope)]
 -> ([CmmTickScope], [(CmmTickScope, CmmTickScope)]))
-> [Either CmmTickScope (CmmTickScope, CmmTickScope)]
-> ([CmmTickScope], [(CmmTickScope, CmmTickScope)])
forall a b. (a -> b) -> a -> b
$ (CmmTickScope -> Either CmmTickScope (CmmTickScope, CmmTickScope))
-> [CmmTickScope]
-> [Either CmmTickScope (CmmTickScope, CmmTickScope)]
forall a b. (a -> b) -> [a] -> [b]
map (\a :: CmmTickScope
a -> CmmTickScope
-> CmmTickScope -> Either CmmTickScope (CmmTickScope, CmmTickScope)
forall t. t -> CmmTickScope -> Either t (CmmTickScope, t)
findP CmmTickScope
a CmmTickScope
a) ([CmmTickScope]
 -> [Either CmmTickScope (CmmTickScope, CmmTickScope)])
-> [CmmTickScope]
-> [Either CmmTickScope (CmmTickScope, CmmTickScope)]
forall a b. (a -> b) -> a -> b
$ Map CmmTickScope [BlockContext] -> [CmmTickScope]
forall k a. Map k a -> [k]
Map.keys Map CmmTickScope [BlockContext]
blockCtxs
      findP :: t -> CmmTickScope -> Either t (CmmTickScope, t)
findP tsc :: t
tsc GlobalScope = t -> Either t (CmmTickScope, t)
forall a b. a -> Either a b
Left t
tsc 
      findP tsc :: t
tsc scp :: CmmTickScope
scp | CmmTickScope
scp' CmmTickScope -> Map CmmTickScope [BlockContext] -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map CmmTickScope [BlockContext]
blockCtxs = (CmmTickScope, t) -> Either t (CmmTickScope, t)
forall a b. b -> Either a b
Right (CmmTickScope
scp', t
tsc)
                    | Bool
otherwise                   = t -> CmmTickScope -> Either t (CmmTickScope, t)
findP t
tsc CmmTickScope
scp'
        where 
              
              
              scp' :: CmmTickScope
scp' | SubScope _ scp' :: CmmTickScope
scp' <- CmmTickScope
scp      = CmmTickScope
scp'
                   | CombinedScope scp' :: CmmTickScope
scp' _ <- CmmTickScope
scp = CmmTickScope
scp'
                   | Bool
otherwise                   = String -> CmmTickScope
forall a. String -> a
panic "findP impossible"
      scopeMap :: Map CmmTickScope [CmmTickScope]
scopeMap = ((CmmTickScope, CmmTickScope)
 -> Map CmmTickScope [CmmTickScope]
 -> Map CmmTickScope [CmmTickScope])
-> Map CmmTickScope [CmmTickScope]
-> [(CmmTickScope, CmmTickScope)]
-> Map CmmTickScope [CmmTickScope]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((CmmTickScope
 -> CmmTickScope
 -> Map CmmTickScope [CmmTickScope]
 -> Map CmmTickScope [CmmTickScope])
-> (CmmTickScope, CmmTickScope)
-> Map CmmTickScope [CmmTickScope]
-> Map CmmTickScope [CmmTickScope]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry CmmTickScope
-> CmmTickScope
-> Map CmmTickScope [CmmTickScope]
-> Map CmmTickScope [CmmTickScope]
forall k a. Ord k => k -> a -> Map k [a] -> Map k [a]
insertMulti) Map CmmTickScope [CmmTickScope]
forall k a. Map k a
Map.empty [(CmmTickScope, CmmTickScope)]
childScopes
      
      
      
      
      
      
      
      
      
      
      
      ticksToCopy :: CmmTickScope -> [CmmTickish]
      ticksToCopy :: CmmTickScope -> [CmmTickish]
ticksToCopy (CombinedScope scp :: CmmTickScope
scp s :: CmmTickScope
s) = CmmTickScope -> [CmmTickish]
go CmmTickScope
s
        where go :: CmmTickScope -> [CmmTickish]
go s :: CmmTickScope
s | CmmTickScope
scp CmmTickScope -> CmmTickScope -> Bool
`isTickSubScope` CmmTickScope
s   = [] 
                   | SubScope _ s' :: CmmTickScope
s' <- CmmTickScope
s       = [CmmTickish]
ticks [CmmTickish] -> [CmmTickish] -> [CmmTickish]
forall a. [a] -> [a] -> [a]
++ CmmTickScope -> [CmmTickish]
go CmmTickScope
s'
                   | CombinedScope s1 :: CmmTickScope
s1 s2 :: CmmTickScope
s2 <- CmmTickScope
s = [CmmTickish]
ticks [CmmTickish] -> [CmmTickish] -> [CmmTickish]
forall a. [a] -> [a] -> [a]
++ CmmTickScope -> [CmmTickish]
go CmmTickScope
s1 [CmmTickish] -> [CmmTickish] -> [CmmTickish]
forall a. [a] -> [a] -> [a]
++ CmmTickScope -> [CmmTickish]
go CmmTickScope
s2
                   | Bool
otherwise                = String -> [CmmTickish]
forall a. String -> a
panic "ticksToCopy impossible"
                where ticks :: [CmmTickish]
ticks = [BlockContext] -> [CmmTickish]
forall b. [(Block CmmNode C C, b)] -> [CmmTickish]
bCtxsTicks ([BlockContext] -> [CmmTickish]) -> [BlockContext] -> [CmmTickish]
forall a b. (a -> b) -> a -> b
$ [BlockContext] -> Maybe [BlockContext] -> [BlockContext]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [BlockContext] -> [BlockContext])
-> Maybe [BlockContext] -> [BlockContext]
forall a b. (a -> b) -> a -> b
$ CmmTickScope
-> Map CmmTickScope [BlockContext] -> Maybe [BlockContext]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup CmmTickScope
s Map CmmTickScope [BlockContext]
blockCtxs
      ticksToCopy _ = []
      bCtxsTicks :: [(Block CmmNode C C, b)] -> [CmmTickish]
bCtxsTicks = ((Block CmmNode C C, b) -> [CmmTickish])
-> [(Block CmmNode C C, b)] -> [CmmTickish]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Block CmmNode C C -> [CmmTickish]
blockTicks (Block CmmNode C C -> [CmmTickish])
-> ((Block CmmNode C C, b) -> Block CmmNode C C)
-> (Block CmmNode C C, b)
-> [CmmTickish]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block CmmNode C C, b) -> Block CmmNode C C
forall a b. (a, b) -> a
fst)
      
      
      
      
      
      bestSrcTick :: [CmmTickish] -> CmmTickish
bestSrcTick = (CmmTickish -> CmmTickish -> Ordering)
-> [CmmTickish] -> CmmTickish
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy ((CmmTickish -> Int) -> CmmTickish -> CmmTickish -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing CmmTickish -> Int
rangeRating)
      rangeRating :: CmmTickish -> Int
rangeRating (SourceNote span :: RealSrcSpan
span _)
        | RealSrcSpan -> FastString
srcSpanFile RealSrcSpan
span FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
thisFile = 1
        | Bool
otherwise                    = 2 :: Int
      rangeRating note :: CmmTickish
note                 = String -> SDoc -> Int
forall a. HasCallStack => String -> SDoc -> a
pprPanic "rangeRating" (CmmTickish -> SDoc
forall a. Outputable a => a -> SDoc
ppr CmmTickish
note)
      thisFile :: FastString
thisFile = FastString -> (String -> FastString) -> Maybe String -> FastString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe FastString
nilFS String -> FastString
mkFastString (Maybe String -> FastString) -> Maybe String -> FastString
forall a b. (a -> b) -> a -> b
$ ModLocation -> Maybe String
ml_hs_file ModLocation
modLoc
      
      
      
      
      blocksForScope :: Maybe CmmTickish -> CmmTickScope -> DebugBlock
      blocksForScope :: Maybe CmmTickish -> CmmTickScope -> DebugBlock
blocksForScope cstick :: Maybe CmmTickish
cstick scope :: CmmTickScope
scope = Bool -> BlockContext -> DebugBlock
mkBlock Bool
True ([BlockContext] -> BlockContext
forall a. [a] -> a
head [BlockContext]
bctxs)
        where bctxs :: [BlockContext]
bctxs = Maybe [BlockContext] -> [BlockContext]
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe [BlockContext] -> [BlockContext])
-> Maybe [BlockContext] -> [BlockContext]
forall a b. (a -> b) -> a -> b
$ CmmTickScope
-> Map CmmTickScope [BlockContext] -> Maybe [BlockContext]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup CmmTickScope
scope Map CmmTickScope [BlockContext]
blockCtxs
              nested :: [CmmTickScope]
nested = [CmmTickScope] -> Maybe [CmmTickScope] -> [CmmTickScope]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [CmmTickScope] -> [CmmTickScope])
-> Maybe [CmmTickScope] -> [CmmTickScope]
forall a b. (a -> b) -> a -> b
$ CmmTickScope
-> Map CmmTickScope [CmmTickScope] -> Maybe [CmmTickScope]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup CmmTickScope
scope Map CmmTickScope [CmmTickScope]
scopeMap
              childs :: [DebugBlock]
childs = (BlockContext -> DebugBlock) -> [BlockContext] -> [DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> BlockContext -> DebugBlock
mkBlock Bool
False) ([BlockContext] -> [BlockContext]
forall a. [a] -> [a]
tail [BlockContext]
bctxs) [DebugBlock] -> [DebugBlock] -> [DebugBlock]
forall a. [a] -> [a] -> [a]
++
                       (CmmTickScope -> DebugBlock) -> [CmmTickScope] -> [DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe CmmTickish -> CmmTickScope -> DebugBlock
blocksForScope Maybe CmmTickish
stick) [CmmTickScope]
nested
              mkBlock :: Bool -> BlockContext -> DebugBlock
              mkBlock :: Bool -> BlockContext -> DebugBlock
mkBlock top :: Bool
top (block :: Block CmmNode C C
block, prc :: RawCmmDecl
prc)
                = $WDebugBlock :: Label
-> Label
-> CLabel
-> Bool
-> Maybe DebugBlock
-> [CmmTickish]
-> Maybe CmmTickish
-> Maybe Int
-> [UnwindPoint]
-> [DebugBlock]
-> DebugBlock
DebugBlock { dblProcedure :: Label
dblProcedure    = GenCmmGraph CmmNode -> Label
forall (n :: * -> * -> *). GenCmmGraph n -> Label
g_entry GenCmmGraph CmmNode
graph
                             , dblLabel :: Label
dblLabel        = Label
label
                             , dblCLabel :: CLabel
dblCLabel       = case Maybe CmmStatics
info of
                                 Just (Statics infoLbl :: CLabel
infoLbl _)   -> CLabel
infoLbl
                                 Nothing
                                   | GenCmmGraph CmmNode -> Label
forall (n :: * -> * -> *). GenCmmGraph n -> Label
g_entry GenCmmGraph CmmNode
graph Label -> Label -> Bool
forall a. Eq a => a -> a -> Bool
== Label
label -> CLabel
entryLbl
                                   | Bool
otherwise              -> Label -> CLabel
blockLbl Label
label
                             , dblHasInfoTbl :: Bool
dblHasInfoTbl   = Maybe CmmStatics -> Bool
forall a. Maybe a -> Bool
isJust Maybe CmmStatics
info
                             , dblParent :: Maybe DebugBlock
dblParent       = Maybe DebugBlock
forall a. Maybe a
Nothing
                             , dblTicks :: [CmmTickish]
dblTicks        = [CmmTickish]
ticks
                             , dblPosition :: Maybe Int
dblPosition     = Maybe Int
forall a. Maybe a
Nothing 
                             , dblSourceTick :: Maybe CmmTickish
dblSourceTick   = Maybe CmmTickish
stick
                             , dblBlocks :: [DebugBlock]
dblBlocks       = [DebugBlock]
blocks
                             , dblUnwind :: [UnwindPoint]
dblUnwind       = []
                             }
                where (CmmProc infos :: LabelMap CmmStatics
infos entryLbl :: CLabel
entryLbl _ graph :: GenCmmGraph CmmNode
graph) = RawCmmDecl
prc
                      label :: Label
label = Block CmmNode C C -> Label
forall (thing :: * -> * -> *) x.
NonLocal thing =>
thing C x -> Label
entryLabel Block CmmNode C C
block
                      info :: Maybe CmmStatics
info = KeyOf LabelMap -> LabelMap CmmStatics -> Maybe CmmStatics
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
Label
label LabelMap CmmStatics
infos
                      blocks :: [DebugBlock]
blocks | Bool
top       = [DebugBlock] -> [DebugBlock] -> [DebugBlock]
forall a b. [a] -> b -> b
seqList [DebugBlock]
childs [DebugBlock]
childs
                             | Bool
otherwise = []
              
              
              isSourceTick :: Tickish id -> Bool
isSourceTick SourceNote {} = Bool
True
              isSourceTick _             = Bool
False
              
              
              ticks :: [CmmTickish]
ticks = (CmmTickish -> CmmTickish -> Bool) -> [CmmTickish] -> [CmmTickish]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy ((CmmTickish -> CmmTickish -> Bool)
-> CmmTickish -> CmmTickish -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip CmmTickish -> CmmTickish -> Bool
forall b. Eq b => Tickish b -> Tickish b -> Bool
tickishContains) ([CmmTickish] -> [CmmTickish]) -> [CmmTickish] -> [CmmTickish]
forall a b. (a -> b) -> a -> b
$
                      [BlockContext] -> [CmmTickish]
forall b. [(Block CmmNode C C, b)] -> [CmmTickish]
bCtxsTicks [BlockContext]
bctxs [CmmTickish] -> [CmmTickish] -> [CmmTickish]
forall a. [a] -> [a] -> [a]
++ CmmTickScope -> [CmmTickish]
ticksToCopy CmmTickScope
scope
              stick :: Maybe CmmTickish
stick = case (CmmTickish -> Bool) -> [CmmTickish] -> [CmmTickish]
forall a. (a -> Bool) -> [a] -> [a]
filter CmmTickish -> Bool
forall id. Tickish id -> Bool
isSourceTick [CmmTickish]
ticks of
                []     -> Maybe CmmTickish
cstick
                sticks :: [CmmTickish]
sticks -> CmmTickish -> Maybe CmmTickish
forall a. a -> Maybe a
Just (CmmTickish -> Maybe CmmTickish) -> CmmTickish -> Maybe CmmTickish
forall a b. (a -> b) -> a -> b
$! [CmmTickish] -> CmmTickish
bestSrcTick ([CmmTickish]
sticks [CmmTickish] -> [CmmTickish] -> [CmmTickish]
forall a. [a] -> [a] -> [a]
++ Maybe CmmTickish -> [CmmTickish]
forall a. Maybe a -> [a]
maybeToList Maybe CmmTickish
cstick)
blockContexts :: RawCmmGroup -> Map.Map CmmTickScope [BlockContext]
blockContexts :: RawCmmGroup -> Map CmmTickScope [BlockContext]
blockContexts decls :: RawCmmGroup
decls = ([BlockContext] -> [BlockContext])
-> Map CmmTickScope [BlockContext]
-> Map CmmTickScope [BlockContext]
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map [BlockContext] -> [BlockContext]
forall a. [a] -> [a]
reverse (Map CmmTickScope [BlockContext]
 -> Map CmmTickScope [BlockContext])
-> Map CmmTickScope [BlockContext]
-> Map CmmTickScope [BlockContext]
forall a b. (a -> b) -> a -> b
$ (RawCmmDecl
 -> Map CmmTickScope [BlockContext]
 -> Map CmmTickScope [BlockContext])
-> Map CmmTickScope [BlockContext]
-> RawCmmGroup
-> Map CmmTickScope [BlockContext]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr RawCmmDecl
-> Map CmmTickScope [BlockContext]
-> Map CmmTickScope [BlockContext]
walkProc Map CmmTickScope [BlockContext]
forall k a. Map k a
Map.empty RawCmmGroup
decls
  where walkProc :: RawCmmDecl
                 -> Map.Map CmmTickScope [BlockContext]
                 -> Map.Map CmmTickScope [BlockContext]
        walkProc :: RawCmmDecl
-> Map CmmTickScope [BlockContext]
-> Map CmmTickScope [BlockContext]
walkProc CmmData{}                 m :: Map CmmTickScope [BlockContext]
m = Map CmmTickScope [BlockContext]
m
        walkProc prc :: RawCmmDecl
prc@(CmmProc _ _ _ graph :: GenCmmGraph CmmNode
graph) m :: Map CmmTickScope [BlockContext]
m
          | LabelMap (Block CmmNode C C) -> Bool
forall (map :: * -> *) a. IsMap map => map a -> Bool
mapNull LabelMap (Block CmmNode C C)
blocks = Map CmmTickScope [BlockContext]
m
          | Bool
otherwise      = (LabelSet, Map CmmTickScope [BlockContext])
-> Map CmmTickScope [BlockContext]
forall a b. (a, b) -> b
snd ((LabelSet, Map CmmTickScope [BlockContext])
 -> Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
-> Map CmmTickScope [BlockContext]
forall a b. (a -> b) -> a -> b
$ RawCmmDecl
-> [Block CmmNode C C]
-> (LabelSet, Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
walkBlock RawCmmDecl
prc [Block CmmNode C C]
entry (LabelSet
emptyLbls, Map CmmTickScope [BlockContext]
m)
          where blocks :: LabelMap (Block CmmNode C C)
blocks = GenCmmGraph CmmNode -> LabelMap (Block CmmNode C C)
toBlockMap GenCmmGraph CmmNode
graph
                entry :: [Block CmmNode C C]
entry  = [KeyOf LabelMap -> LabelMap (Block CmmNode C C) -> Block CmmNode C C
forall a. KeyOf LabelMap -> LabelMap a -> a
mapFind (GenCmmGraph CmmNode -> Label
forall (n :: * -> * -> *). GenCmmGraph n -> Label
g_entry GenCmmGraph CmmNode
graph) LabelMap (Block CmmNode C C)
blocks]
                emptyLbls :: LabelSet
emptyLbls = LabelSet
forall set. IsSet set => set
setEmpty :: LabelSet
        walkBlock :: RawCmmDecl -> [Block CmmNode C C]
                  -> (LabelSet, Map.Map CmmTickScope [BlockContext])
                  -> (LabelSet, Map.Map CmmTickScope [BlockContext])
        walkBlock :: RawCmmDecl
-> [Block CmmNode C C]
-> (LabelSet, Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
walkBlock _   []             c :: (LabelSet, Map CmmTickScope [BlockContext])
c            = (LabelSet, Map CmmTickScope [BlockContext])
c
        walkBlock prc :: RawCmmDecl
prc (block :: Block CmmNode C C
block:blocks :: [Block CmmNode C C]
blocks) (visited :: LabelSet
visited, m :: Map CmmTickScope [BlockContext]
m)
          | ElemOf LabelSet
Label
lbl ElemOf LabelSet -> LabelSet -> Bool
forall set. IsSet set => ElemOf set -> set -> Bool
`setMember` LabelSet
visited
          = RawCmmDecl
-> [Block CmmNode C C]
-> (LabelSet, Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
walkBlock RawCmmDecl
prc [Block CmmNode C C]
blocks (LabelSet
visited, Map CmmTickScope [BlockContext]
m)
          | Bool
otherwise
          = RawCmmDecl
-> [Block CmmNode C C]
-> (LabelSet, Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
walkBlock RawCmmDecl
prc [Block CmmNode C C]
blocks ((LabelSet, Map CmmTickScope [BlockContext])
 -> (LabelSet, Map CmmTickScope [BlockContext]))
-> (LabelSet, Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
forall a b. (a -> b) -> a -> b
$
            RawCmmDecl
-> [Block CmmNode C C]
-> (LabelSet, Map CmmTickScope [BlockContext])
-> (LabelSet, Map CmmTickScope [BlockContext])
walkBlock RawCmmDecl
prc [Block CmmNode C C]
succs
              (ElemOf LabelSet
Label
lbl ElemOf LabelSet -> LabelSet -> LabelSet
forall set. IsSet set => ElemOf set -> set -> set
`setInsert` LabelSet
visited,
               CmmTickScope
-> BlockContext
-> Map CmmTickScope [BlockContext]
-> Map CmmTickScope [BlockContext]
forall k a. Ord k => k -> a -> Map k [a] -> Map k [a]
insertMulti CmmTickScope
scope (Block CmmNode C C
block, RawCmmDecl
prc) Map CmmTickScope [BlockContext]
m)
          where CmmEntry lbl scope = Block CmmNode C C -> CmmNode C O
forall (n :: * -> * -> *) x. Block n C x -> n C O
firstNode Block CmmNode C C
block
                (CmmProc _ _ _ graph :: GenCmmGraph CmmNode
graph) = RawCmmDecl
prc
                succs :: [Block CmmNode C C]
succs = (Label -> Block CmmNode C C) -> [Label] -> [Block CmmNode C C]
forall a b. (a -> b) -> [a] -> [b]
map ((Label -> LabelMap (Block CmmNode C C) -> Block CmmNode C C)
-> LabelMap (Block CmmNode C C) -> Label -> Block CmmNode C C
forall a b c. (a -> b -> c) -> b -> a -> c
flip Label -> LabelMap (Block CmmNode C C) -> Block CmmNode C C
forall a. KeyOf LabelMap -> LabelMap a -> a
mapFind (GenCmmGraph CmmNode -> LabelMap (Block CmmNode C C)
toBlockMap GenCmmGraph CmmNode
graph))
                            (CmmNode O C -> [Label]
forall (thing :: * -> * -> *) e.
NonLocal thing =>
thing e C -> [Label]
successors (Block CmmNode C C -> CmmNode O C
forall (n :: * -> * -> *) x. Block n x C -> n O C
lastNode Block CmmNode C C
block))
        mapFind :: KeyOf LabelMap -> LabelMap a -> a
mapFind = a -> KeyOf LabelMap -> LabelMap a -> a
forall (map :: * -> *) a. IsMap map => a -> KeyOf map -> map a -> a
mapFindWithDefault (String -> a
forall a. HasCallStack => String -> a
error "contextTree: block not found!")
insertMulti :: Ord k => k -> a -> Map.Map k [a] -> Map.Map k [a]
insertMulti :: k -> a -> Map k [a] -> Map k [a]
insertMulti k :: k
k v :: a
v = ([a] -> [a] -> [a]) -> k -> [a] -> Map k [a] -> Map k [a]
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith (([a] -> [a]) -> [a] -> [a] -> [a]
forall a b. a -> b -> a
const (a
va -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) k
k [a
v]
cmmDebugLabels :: (i -> Bool) -> GenCmmGroup d g (ListGraph i) -> [Label]
cmmDebugLabels :: (i -> Bool) -> GenCmmGroup d g (ListGraph i) -> [Label]
cmmDebugLabels isMeta :: i -> Bool
isMeta nats :: GenCmmGroup d g (ListGraph i)
nats = [Label] -> [Label] -> [Label]
forall a b. [a] -> b -> b
seqList [Label]
lbls [Label]
lbls
  where 
        
        
        
        
        
        
        lbls :: [Label]
lbls = (GenBasicBlock i -> Label) -> [GenBasicBlock i] -> [Label]
forall a b. (a -> b) -> [a] -> [b]
map GenBasicBlock i -> Label
forall i. GenBasicBlock i -> Label
blockId ([GenBasicBlock i] -> [Label]) -> [GenBasicBlock i] -> [Label]
forall a b. (a -> b) -> a -> b
$ (GenBasicBlock i -> Bool) -> [GenBasicBlock i] -> [GenBasicBlock i]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GenBasicBlock i -> Bool) -> GenBasicBlock i -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenBasicBlock i -> Bool
allMeta) ([GenBasicBlock i] -> [GenBasicBlock i])
-> [GenBasicBlock i] -> [GenBasicBlock i]
forall a b. (a -> b) -> a -> b
$ (GenCmmDecl d g (ListGraph i) -> [GenBasicBlock i])
-> GenCmmGroup d g (ListGraph i) -> [GenBasicBlock i]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap GenCmmDecl d g (ListGraph i) -> [GenBasicBlock i]
forall d h i. GenCmmDecl d h (ListGraph i) -> [GenBasicBlock i]
getBlocks GenCmmGroup d g (ListGraph i)
nats
        getBlocks :: GenCmmDecl d h (ListGraph i) -> [GenBasicBlock i]
getBlocks (CmmProc _ _ _ (ListGraph bs :: [GenBasicBlock i]
bs)) = [GenBasicBlock i]
bs
        getBlocks _other :: GenCmmDecl d h (ListGraph i)
_other                         = []
        allMeta :: GenBasicBlock i -> Bool
allMeta (BasicBlock _ instrs :: [i]
instrs) = (i -> Bool) -> [i] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all i -> Bool
isMeta [i]
instrs
cmmDebugLink :: [Label] -> LabelMap [UnwindPoint]
             -> [DebugBlock] -> [DebugBlock]
cmmDebugLink :: [Label] -> LabelMap [UnwindPoint] -> [DebugBlock] -> [DebugBlock]
cmmDebugLink labels :: [Label]
labels unwindPts :: LabelMap [UnwindPoint]
unwindPts blocks :: [DebugBlock]
blocks = (DebugBlock -> DebugBlock) -> [DebugBlock] -> [DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map DebugBlock -> DebugBlock
link [DebugBlock]
blocks
  where blockPos :: LabelMap Int
        blockPos :: LabelMap Int
blockPos = [(KeyOf LabelMap, Int)] -> LabelMap Int
forall (map :: * -> *) a. IsMap map => [(KeyOf map, a)] -> map a
mapFromList ([(KeyOf LabelMap, Int)] -> LabelMap Int)
-> [(KeyOf LabelMap, Int)] -> LabelMap Int
forall a b. (a -> b) -> a -> b
$ ([Label] -> [Int] -> [(Label, Int)])
-> [Int] -> [Label] -> [(Label, Int)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip [Label] -> [Int] -> [(Label, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [0..] [Label]
labels
        link :: DebugBlock -> DebugBlock
link block :: DebugBlock
block = DebugBlock
block { dblPosition :: Maybe Int
dblPosition = KeyOf LabelMap -> LabelMap Int -> Maybe Int
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup (DebugBlock -> Label
dblLabel DebugBlock
block) LabelMap Int
blockPos
                           , dblBlocks :: [DebugBlock]
dblBlocks   = (DebugBlock -> DebugBlock) -> [DebugBlock] -> [DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map DebugBlock -> DebugBlock
link (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
block)
                           , dblUnwind :: [UnwindPoint]
dblUnwind   = [UnwindPoint] -> Maybe [UnwindPoint] -> [UnwindPoint]
forall a. a -> Maybe a -> a
fromMaybe [UnwindPoint]
forall a. Monoid a => a
mempty
                                         (Maybe [UnwindPoint] -> [UnwindPoint])
-> Maybe [UnwindPoint] -> [UnwindPoint]
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> LabelMap [UnwindPoint] -> Maybe [UnwindPoint]
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup (DebugBlock -> Label
dblLabel DebugBlock
block) LabelMap [UnwindPoint]
unwindPts
                           }
debugToMap :: [DebugBlock] -> LabelMap DebugBlock
debugToMap :: [DebugBlock] -> LabelMap DebugBlock
debugToMap = [LabelMap DebugBlock] -> LabelMap DebugBlock
forall (map :: * -> *) a. IsMap map => [map a] -> map a
mapUnions ([LabelMap DebugBlock] -> LabelMap DebugBlock)
-> ([DebugBlock] -> [LabelMap DebugBlock])
-> [DebugBlock]
-> LabelMap DebugBlock
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DebugBlock -> LabelMap DebugBlock)
-> [DebugBlock] -> [LabelMap DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map DebugBlock -> LabelMap DebugBlock
forall (map :: * -> *).
(IsMap map, KeyOf map ~ Label) =>
DebugBlock -> map DebugBlock
go
   where go :: DebugBlock -> map DebugBlock
go b :: DebugBlock
b = KeyOf map -> DebugBlock -> map DebugBlock -> map DebugBlock
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert (DebugBlock -> Label
dblLabel DebugBlock
b) DebugBlock
b (map DebugBlock -> map DebugBlock)
-> map DebugBlock -> map DebugBlock
forall a b. (a -> b) -> a -> b
$ [map DebugBlock] -> map DebugBlock
forall (map :: * -> *) a. IsMap map => [map a] -> map a
mapUnions ([map DebugBlock] -> map DebugBlock)
-> [map DebugBlock] -> map DebugBlock
forall a b. (a -> b) -> a -> b
$ (DebugBlock -> map DebugBlock) -> [DebugBlock] -> [map DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map DebugBlock -> map DebugBlock
go (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
b)
data UnwindPoint = UnwindPoint !CLabel !UnwindTable
instance Outputable UnwindPoint where
  ppr :: UnwindPoint -> SDoc
ppr (UnwindPoint lbl :: CLabel
lbl uws :: UnwindTable
uws) =
      SDoc -> SDoc
braces (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
lblSDoc -> SDoc -> SDoc
<>SDoc
colon
      SDoc -> SDoc -> SDoc
<+> [SDoc] -> SDoc
hsep (SDoc -> [SDoc] -> [SDoc]
punctuate SDoc
comma ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ ((GlobalReg, Maybe UnwindExpr) -> SDoc)
-> [(GlobalReg, Maybe UnwindExpr)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (GlobalReg, Maybe UnwindExpr) -> SDoc
forall a a. (Outputable a, Outputable a) => (a, a) -> SDoc
pprUw ([(GlobalReg, Maybe UnwindExpr)] -> [SDoc])
-> [(GlobalReg, Maybe UnwindExpr)] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ UnwindTable -> [(GlobalReg, Maybe UnwindExpr)]
forall k a. Map k a -> [(k, a)]
Map.toList UnwindTable
uws)
    where
      pprUw :: (a, a) -> SDoc
pprUw (g :: a
g, expr :: a
expr) = a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
g SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '=' SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
expr
type UnwindTable = Map.Map GlobalReg (Maybe UnwindExpr)
data UnwindExpr = UwConst !Int                  
                | UwReg !GlobalReg !Int         
                | UwDeref UnwindExpr            
                | UwLabel CLabel
                | UwPlus UnwindExpr UnwindExpr
                | UwMinus UnwindExpr UnwindExpr
                | UwTimes UnwindExpr UnwindExpr
                deriving (UnwindExpr -> UnwindExpr -> Bool
(UnwindExpr -> UnwindExpr -> Bool)
-> (UnwindExpr -> UnwindExpr -> Bool) -> Eq UnwindExpr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnwindExpr -> UnwindExpr -> Bool
$c/= :: UnwindExpr -> UnwindExpr -> Bool
== :: UnwindExpr -> UnwindExpr -> Bool
$c== :: UnwindExpr -> UnwindExpr -> Bool
Eq)
instance Outputable UnwindExpr where
  pprPrec :: Rational -> UnwindExpr -> SDoc
pprPrec _ (UwConst i :: Int
i)     = Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
i
  pprPrec _ (UwReg g :: GlobalReg
g 0)     = GlobalReg -> SDoc
forall a. Outputable a => a -> SDoc
ppr GlobalReg
g
  pprPrec p :: Rational
p (UwReg g :: GlobalReg
g x :: Int
x)     = Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec Rational
p (UnwindExpr -> UnwindExpr -> UnwindExpr
UwPlus (GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
g 0) (Int -> UnwindExpr
UwConst Int
x))
  pprPrec _ (UwDeref e :: UnwindExpr
e)     = Char -> SDoc
char '*' SDoc -> SDoc -> SDoc
<> Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 3 UnwindExpr
e
  pprPrec _ (UwLabel l :: CLabel
l)     = Rational -> CLabel -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 3 CLabel
l
  pprPrec p :: Rational
p (UwPlus e0 :: UnwindExpr
e0 e1 :: UnwindExpr
e1)  | Rational
p Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= 0
                            = Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 0 UnwindExpr
e0 SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '+' SDoc -> SDoc -> SDoc
<> Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 0 UnwindExpr
e1
  pprPrec p :: Rational
p (UwMinus e0 :: UnwindExpr
e0 e1 :: UnwindExpr
e1) | Rational
p Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= 0
                            = Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 1 UnwindExpr
e0 SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<> Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 1 UnwindExpr
e1
  pprPrec p :: Rational
p (UwTimes e0 :: UnwindExpr
e0 e1 :: UnwindExpr
e1) | Rational
p Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= 1
                            = Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 2 UnwindExpr
e0 SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '*' SDoc -> SDoc -> SDoc
<> Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 2 UnwindExpr
e1
  pprPrec _ other :: UnwindExpr
other           = SDoc -> SDoc
parens (Rational -> UnwindExpr -> SDoc
forall a. Outputable a => Rational -> a -> SDoc
pprPrec 0 UnwindExpr
other)
toUnwindExpr :: CmmExpr -> UnwindExpr
toUnwindExpr :: CmmExpr -> UnwindExpr
toUnwindExpr (CmmLit (CmmInt i :: Integer
i _))       = Int -> UnwindExpr
UwConst (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
i)
toUnwindExpr (CmmLit (CmmLabel l :: CLabel
l))       = CLabel -> UnwindExpr
UwLabel CLabel
l
toUnwindExpr (CmmRegOff (CmmGlobal g :: GlobalReg
g) i :: Int
i) = GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
g Int
i
toUnwindExpr (CmmReg (CmmGlobal g :: GlobalReg
g))      = GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
g 0
toUnwindExpr (CmmLoad e :: CmmExpr
e _)               = UnwindExpr -> UnwindExpr
UwDeref (CmmExpr -> UnwindExpr
toUnwindExpr CmmExpr
e)
toUnwindExpr e :: CmmExpr
e@(CmmMachOp op :: MachOp
op [e1 :: CmmExpr
e1, e2 :: CmmExpr
e2])   =
  case (MachOp
op, CmmExpr -> UnwindExpr
toUnwindExpr CmmExpr
e1, CmmExpr -> UnwindExpr
toUnwindExpr CmmExpr
e2) of
    (MO_Add{}, UwReg r :: GlobalReg
r x :: Int
x, UwConst y :: Int
y) -> GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
r (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y)
    (MO_Sub{}, UwReg r :: GlobalReg
r x :: Int
x, UwConst y :: Int
y) -> GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
r (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y)
    (MO_Add{}, UwConst x :: Int
x, UwReg r :: GlobalReg
r y :: Int
y) -> GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
r (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y)
    (MO_Add{}, UwConst x :: Int
x, UwConst y :: Int
y) -> Int -> UnwindExpr
UwConst (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y)
    (MO_Sub{}, UwConst x :: Int
x, UwConst y :: Int
y) -> Int -> UnwindExpr
UwConst (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y)
    (MO_Mul{}, UwConst x :: Int
x, UwConst y :: Int
y) -> Int -> UnwindExpr
UwConst (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y)
    (MO_Add{}, u1 :: UnwindExpr
u1,        u2 :: UnwindExpr
u2       ) -> UnwindExpr -> UnwindExpr -> UnwindExpr
UwPlus UnwindExpr
u1 UnwindExpr
u2
    (MO_Sub{}, u1 :: UnwindExpr
u1,        u2 :: UnwindExpr
u2       ) -> UnwindExpr -> UnwindExpr -> UnwindExpr
UwMinus UnwindExpr
u1 UnwindExpr
u2
    (MO_Mul{}, u1 :: UnwindExpr
u1,        u2 :: UnwindExpr
u2       ) -> UnwindExpr -> UnwindExpr -> UnwindExpr
UwTimes UnwindExpr
u1 UnwindExpr
u2
    _otherwise :: (MachOp, UnwindExpr, UnwindExpr)
_otherwise -> String -> SDoc -> UnwindExpr
forall a. HasCallStack => String -> SDoc -> a
pprPanic "Unsupported operator in unwind expression!"
                           (CmmExpr -> SDoc
pprExpr CmmExpr
e)
toUnwindExpr e :: CmmExpr
e
  = String -> SDoc -> UnwindExpr
forall a. HasCallStack => String -> SDoc -> a
pprPanic "Unsupported unwind expression!" (CmmExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CmmExpr
e)