{-# LANGUAGE TypeFamilies, ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE CPP #-}
module CFG
( CFG, CfgEdge(..), EdgeInfo(..), EdgeWeight(..)
, TransitionSource(..)
, addWeightEdge, addEdge, delEdge
, addNodesBetween, shortcutWeightMap
, reverseEdges, filterEdges
, addImmediateSuccessor
, mkWeightInfo, adjustEdgeWeight
, infoEdgeList, edgeList
, getSuccessorEdges, getSuccessors
, getSuccEdgesSorted, weightedEdgeList
, getEdgeInfo
, getCfgNodes, hasNode
, loopMembers
, getCfg, getCfgProc, pprEdgeWeights, sanityCheckCfg
, optimizeCFG )
where
#include "HsVersions.h"
import GhcPrelude
import BlockId
import Cmm ( RawCmmDecl, GenCmmDecl( .. ), CmmBlock, succ, g_entry
, CmmGraph )
import CmmNode
import CmmUtils
import CmmSwitch
import Hoopl.Collections
import Hoopl.Label
import Hoopl.Block
import qualified Hoopl.Graph as G
import Util
import Digraph
import Outputable
import PprCmm ()
import qualified DynFlags as D
import Data.List
type Edge = (BlockId, BlockId)
type Edges = [Edge]
newtype EdgeWeight
= EdgeWeight Int
deriving (EdgeWeight -> EdgeWeight -> Bool
(EdgeWeight -> EdgeWeight -> Bool)
-> (EdgeWeight -> EdgeWeight -> Bool) -> Eq EdgeWeight
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EdgeWeight -> EdgeWeight -> Bool
$c/= :: EdgeWeight -> EdgeWeight -> Bool
== :: EdgeWeight -> EdgeWeight -> Bool
$c== :: EdgeWeight -> EdgeWeight -> Bool
Eq,Eq EdgeWeight
Eq EdgeWeight =>
(EdgeWeight -> EdgeWeight -> Ordering)
-> (EdgeWeight -> EdgeWeight -> Bool)
-> (EdgeWeight -> EdgeWeight -> Bool)
-> (EdgeWeight -> EdgeWeight -> Bool)
-> (EdgeWeight -> EdgeWeight -> Bool)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> Ord EdgeWeight
EdgeWeight -> EdgeWeight -> Bool
EdgeWeight -> EdgeWeight -> Ordering
EdgeWeight -> EdgeWeight -> EdgeWeight
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EdgeWeight -> EdgeWeight -> EdgeWeight
$cmin :: EdgeWeight -> EdgeWeight -> EdgeWeight
max :: EdgeWeight -> EdgeWeight -> EdgeWeight
$cmax :: EdgeWeight -> EdgeWeight -> EdgeWeight
>= :: EdgeWeight -> EdgeWeight -> Bool
$c>= :: EdgeWeight -> EdgeWeight -> Bool
> :: EdgeWeight -> EdgeWeight -> Bool
$c> :: EdgeWeight -> EdgeWeight -> Bool
<= :: EdgeWeight -> EdgeWeight -> Bool
$c<= :: EdgeWeight -> EdgeWeight -> Bool
< :: EdgeWeight -> EdgeWeight -> Bool
$c< :: EdgeWeight -> EdgeWeight -> Bool
compare :: EdgeWeight -> EdgeWeight -> Ordering
$ccompare :: EdgeWeight -> EdgeWeight -> Ordering
$cp1Ord :: Eq EdgeWeight
Ord,Int -> EdgeWeight
EdgeWeight -> Int
EdgeWeight -> [EdgeWeight]
EdgeWeight -> EdgeWeight
EdgeWeight -> EdgeWeight -> [EdgeWeight]
EdgeWeight -> EdgeWeight -> EdgeWeight -> [EdgeWeight]
(EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight)
-> (Int -> EdgeWeight)
-> (EdgeWeight -> Int)
-> (EdgeWeight -> [EdgeWeight])
-> (EdgeWeight -> EdgeWeight -> [EdgeWeight])
-> (EdgeWeight -> EdgeWeight -> [EdgeWeight])
-> (EdgeWeight -> EdgeWeight -> EdgeWeight -> [EdgeWeight])
-> Enum EdgeWeight
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: EdgeWeight -> EdgeWeight -> EdgeWeight -> [EdgeWeight]
$cenumFromThenTo :: EdgeWeight -> EdgeWeight -> EdgeWeight -> [EdgeWeight]
enumFromTo :: EdgeWeight -> EdgeWeight -> [EdgeWeight]
$cenumFromTo :: EdgeWeight -> EdgeWeight -> [EdgeWeight]
enumFromThen :: EdgeWeight -> EdgeWeight -> [EdgeWeight]
$cenumFromThen :: EdgeWeight -> EdgeWeight -> [EdgeWeight]
enumFrom :: EdgeWeight -> [EdgeWeight]
$cenumFrom :: EdgeWeight -> [EdgeWeight]
fromEnum :: EdgeWeight -> Int
$cfromEnum :: EdgeWeight -> Int
toEnum :: Int -> EdgeWeight
$ctoEnum :: Int -> EdgeWeight
pred :: EdgeWeight -> EdgeWeight
$cpred :: EdgeWeight -> EdgeWeight
succ :: EdgeWeight -> EdgeWeight
$csucc :: EdgeWeight -> EdgeWeight
Enum,Integer -> EdgeWeight
EdgeWeight -> EdgeWeight
EdgeWeight -> EdgeWeight -> EdgeWeight
(EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight)
-> (Integer -> EdgeWeight)
-> Num EdgeWeight
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> EdgeWeight
$cfromInteger :: Integer -> EdgeWeight
signum :: EdgeWeight -> EdgeWeight
$csignum :: EdgeWeight -> EdgeWeight
abs :: EdgeWeight -> EdgeWeight
$cabs :: EdgeWeight -> EdgeWeight
negate :: EdgeWeight -> EdgeWeight
$cnegate :: EdgeWeight -> EdgeWeight
* :: EdgeWeight -> EdgeWeight -> EdgeWeight
$c* :: EdgeWeight -> EdgeWeight -> EdgeWeight
- :: EdgeWeight -> EdgeWeight -> EdgeWeight
$c- :: EdgeWeight -> EdgeWeight -> EdgeWeight
+ :: EdgeWeight -> EdgeWeight -> EdgeWeight
$c+ :: EdgeWeight -> EdgeWeight -> EdgeWeight
Num,Num EdgeWeight
Ord EdgeWeight
(Num EdgeWeight, Ord EdgeWeight) =>
(EdgeWeight -> Rational) -> Real EdgeWeight
EdgeWeight -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
toRational :: EdgeWeight -> Rational
$ctoRational :: EdgeWeight -> Rational
$cp2Real :: Ord EdgeWeight
$cp1Real :: Num EdgeWeight
Real,Enum EdgeWeight
Real EdgeWeight
(Real EdgeWeight, Enum EdgeWeight) =>
(EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> EdgeWeight)
-> (EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight))
-> (EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight))
-> (EdgeWeight -> Integer)
-> Integral EdgeWeight
EdgeWeight -> Integer
EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight)
EdgeWeight -> EdgeWeight -> EdgeWeight
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: EdgeWeight -> Integer
$ctoInteger :: EdgeWeight -> Integer
divMod :: EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight)
$cdivMod :: EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight)
quotRem :: EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight)
$cquotRem :: EdgeWeight -> EdgeWeight -> (EdgeWeight, EdgeWeight)
mod :: EdgeWeight -> EdgeWeight -> EdgeWeight
$cmod :: EdgeWeight -> EdgeWeight -> EdgeWeight
div :: EdgeWeight -> EdgeWeight -> EdgeWeight
$cdiv :: EdgeWeight -> EdgeWeight -> EdgeWeight
rem :: EdgeWeight -> EdgeWeight -> EdgeWeight
$crem :: EdgeWeight -> EdgeWeight -> EdgeWeight
quot :: EdgeWeight -> EdgeWeight -> EdgeWeight
$cquot :: EdgeWeight -> EdgeWeight -> EdgeWeight
$cp2Integral :: Enum EdgeWeight
$cp1Integral :: Real EdgeWeight
Integral)
instance Outputable EdgeWeight where
ppr :: EdgeWeight -> SDoc
ppr (EdgeWeight w :: Int
w) = Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
w
type EdgeInfoMap edgeInfo = LabelMap (LabelMap edgeInfo)
type CFG = EdgeInfoMap EdgeInfo
data CfgEdge
= CfgEdge
{ CfgEdge -> BlockId
edgeFrom :: !BlockId
, CfgEdge -> BlockId
edgeTo :: !BlockId
, CfgEdge -> EdgeInfo
edgeInfo :: !EdgeInfo
}
instance Eq CfgEdge where
== :: CfgEdge -> CfgEdge -> Bool
(==) (CfgEdge from1 :: BlockId
from1 to1 :: BlockId
to1 _) (CfgEdge from2 :: BlockId
from2 to2 :: BlockId
to2 _)
= BlockId
from1 BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
from2 Bool -> Bool -> Bool
&& BlockId
to1 BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
to2
instance Ord CfgEdge where
compare :: CfgEdge -> CfgEdge -> Ordering
compare (CfgEdge from1 :: BlockId
from1 to1 :: BlockId
to1 (EdgeInfo {edgeWeight :: EdgeInfo -> EdgeWeight
edgeWeight = EdgeWeight
weight1}))
(CfgEdge from2 :: BlockId
from2 to2 :: BlockId
to2 (EdgeInfo {edgeWeight :: EdgeInfo -> EdgeWeight
edgeWeight = EdgeWeight
weight2}))
| EdgeWeight
weight1 EdgeWeight -> EdgeWeight -> Bool
forall a. Ord a => a -> a -> Bool
< EdgeWeight
weight2 Bool -> Bool -> Bool
|| EdgeWeight
weight1 EdgeWeight -> EdgeWeight -> Bool
forall a. Eq a => a -> a -> Bool
== EdgeWeight
weight2 Bool -> Bool -> Bool
&& BlockId
from1 BlockId -> BlockId -> Bool
forall a. Ord a => a -> a -> Bool
< BlockId
from2 Bool -> Bool -> Bool
||
EdgeWeight
weight1 EdgeWeight -> EdgeWeight -> Bool
forall a. Eq a => a -> a -> Bool
== EdgeWeight
weight2 Bool -> Bool -> Bool
&& BlockId
from1 BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
from2 Bool -> Bool -> Bool
&& BlockId
to1 BlockId -> BlockId -> Bool
forall a. Ord a => a -> a -> Bool
< BlockId
to2
= Ordering
LT
| BlockId
from1 BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
from2 Bool -> Bool -> Bool
&& BlockId
to1 BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
to2 Bool -> Bool -> Bool
&& EdgeWeight
weight1 EdgeWeight -> EdgeWeight -> Bool
forall a. Eq a => a -> a -> Bool
== EdgeWeight
weight2
= Ordering
EQ
| Bool
otherwise
= Ordering
GT
instance Outputable CfgEdge where
ppr :: CfgEdge -> SDoc
ppr (CfgEdge from1 :: BlockId
from1 to1 :: BlockId
to1 edgeInfo :: EdgeInfo
edgeInfo)
= SDoc -> SDoc
parens (BlockId -> SDoc
forall a. Outputable a => a -> SDoc
ppr BlockId
from1 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "-(" SDoc -> SDoc -> SDoc
<> EdgeInfo -> SDoc
forall a. Outputable a => a -> SDoc
ppr EdgeInfo
edgeInfo SDoc -> SDoc -> SDoc
<> String -> SDoc
text ")->" SDoc -> SDoc -> SDoc
<+> BlockId -> SDoc
forall a. Outputable a => a -> SDoc
ppr BlockId
to1)
data TransitionSource
= CmmSource (CmmNode O C)
| AsmCodeGen
deriving (TransitionSource -> TransitionSource -> Bool
(TransitionSource -> TransitionSource -> Bool)
-> (TransitionSource -> TransitionSource -> Bool)
-> Eq TransitionSource
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TransitionSource -> TransitionSource -> Bool
$c/= :: TransitionSource -> TransitionSource -> Bool
== :: TransitionSource -> TransitionSource -> Bool
$c== :: TransitionSource -> TransitionSource -> Bool
Eq)
data EdgeInfo
= EdgeInfo
{ EdgeInfo -> TransitionSource
transitionSource :: !TransitionSource
, EdgeInfo -> EdgeWeight
edgeWeight :: !EdgeWeight
} deriving (EdgeInfo -> EdgeInfo -> Bool
(EdgeInfo -> EdgeInfo -> Bool)
-> (EdgeInfo -> EdgeInfo -> Bool) -> Eq EdgeInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EdgeInfo -> EdgeInfo -> Bool
$c/= :: EdgeInfo -> EdgeInfo -> Bool
== :: EdgeInfo -> EdgeInfo -> Bool
$c== :: EdgeInfo -> EdgeInfo -> Bool
Eq)
instance Outputable EdgeInfo where
ppr :: EdgeInfo -> SDoc
ppr edgeInfo :: EdgeInfo
edgeInfo = String -> SDoc
text "weight:" SDoc -> SDoc -> SDoc
<+> EdgeWeight -> SDoc
forall a. Outputable a => a -> SDoc
ppr (EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
edgeInfo)
{-# INLINEABLE mkWeightInfo #-}
mkWeightInfo :: Integral n => n -> EdgeInfo
mkWeightInfo :: n -> EdgeInfo
mkWeightInfo = TransitionSource -> EdgeWeight -> EdgeInfo
EdgeInfo TransitionSource
AsmCodeGen (EdgeWeight -> EdgeInfo) -> (n -> EdgeWeight) -> n -> EdgeInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> EdgeWeight
forall a b. (Integral a, Num b) => a -> b
fromIntegral
adjustEdgeWeight :: CFG -> (EdgeWeight -> EdgeWeight)
-> BlockId -> BlockId -> CFG
adjustEdgeWeight :: CFG -> (EdgeWeight -> EdgeWeight) -> BlockId -> BlockId -> CFG
adjustEdgeWeight cfg :: CFG
cfg f :: EdgeWeight -> EdgeWeight
f from :: BlockId
from to :: BlockId
to
| Just info :: EdgeInfo
info <- BlockId -> BlockId -> CFG -> Maybe EdgeInfo
getEdgeInfo BlockId
from BlockId
to CFG
cfg
, EdgeWeight
weight <- EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
info
= BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge BlockId
from BlockId
to (EdgeInfo
info { edgeWeight :: EdgeWeight
edgeWeight = EdgeWeight -> EdgeWeight
f EdgeWeight
weight}) CFG
cfg
| Bool
otherwise = CFG
cfg
getCfgNodes :: CFG -> LabelSet
getCfgNodes :: CFG -> LabelSet
getCfgNodes m :: CFG
m = (KeyOf LabelMap -> LabelMap EdgeInfo -> LabelSet)
-> CFG -> LabelSet
forall (map :: * -> *) m a.
(IsMap map, Monoid m) =>
(KeyOf map -> a -> m) -> map a -> m
mapFoldMapWithKey (\k :: KeyOf LabelMap
k v :: LabelMap EdgeInfo
v -> [ElemOf LabelSet] -> LabelSet
forall set. IsSet set => [ElemOf set] -> set
setFromList (KeyOf LabelMap
BlockId
kBlockId -> [BlockId] -> [BlockId]
forall a. a -> [a] -> [a]
:LabelMap EdgeInfo -> [KeyOf LabelMap]
forall (map :: * -> *) a. IsMap map => map a -> [KeyOf map]
mapKeys LabelMap EdgeInfo
v)) CFG
m
hasNode :: CFG -> BlockId -> Bool
hasNode :: CFG -> BlockId -> Bool
hasNode m :: CFG
m node :: BlockId
node =
ASSERT( found || not (any (mapMember node) m))
Bool
found
where
found :: Bool
found = KeyOf LabelMap -> CFG -> Bool
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> Bool
mapMember KeyOf LabelMap
BlockId
node CFG
m
sanityCheckCfg :: CFG -> LabelSet -> SDoc -> Bool
sanityCheckCfg :: CFG -> LabelSet -> SDoc -> Bool
sanityCheckCfg m :: CFG
m blockSet :: LabelSet
blockSet msg :: SDoc
msg
| LabelSet
blockSet LabelSet -> LabelSet -> Bool
forall a. Eq a => a -> a -> Bool
== LabelSet
cfgNodes
= Bool
True
| Bool
otherwise =
String -> SDoc -> Bool -> Bool
forall a. HasCallStack => String -> SDoc -> a
pprPanic "Block list and cfg nodes don't match" (
String -> SDoc
text "difference:" SDoc -> SDoc -> SDoc
<+> LabelSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr LabelSet
diff SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "blocks:" SDoc -> SDoc -> SDoc
<+> LabelSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr LabelSet
blockSet SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "cfg:" SDoc -> SDoc -> SDoc
<+> CFG -> SDoc
pprEdgeWeights CFG
m SDoc -> SDoc -> SDoc
$$
SDoc
msg )
Bool
False
where
cfgNodes :: LabelSet
cfgNodes = CFG -> LabelSet
getCfgNodes CFG
m :: LabelSet
diff :: LabelSet
diff = (LabelSet -> LabelSet -> LabelSet
forall set. IsSet set => set -> set -> set
setUnion LabelSet
cfgNodes LabelSet
blockSet) LabelSet -> LabelSet -> LabelSet
forall set. IsSet set => set -> set -> set
`setDifference` (LabelSet -> LabelSet -> LabelSet
forall set. IsSet set => set -> set -> set
setIntersection LabelSet
cfgNodes LabelSet
blockSet) :: LabelSet
filterEdges :: (BlockId -> BlockId -> EdgeInfo -> Bool) -> CFG -> CFG
filterEdges :: (BlockId -> BlockId -> EdgeInfo -> Bool) -> CFG -> CFG
filterEdges f :: BlockId -> BlockId -> EdgeInfo -> Bool
f cfg :: CFG
cfg =
(KeyOf LabelMap -> LabelMap EdgeInfo -> LabelMap EdgeInfo)
-> CFG -> CFG
forall (map :: * -> *) a b.
IsMap map =>
(KeyOf map -> a -> b) -> map a -> map b
mapMapWithKey KeyOf LabelMap -> LabelMap EdgeInfo -> LabelMap EdgeInfo
BlockId -> LabelMap EdgeInfo -> LabelMap EdgeInfo
filterSources CFG
cfg
where
filterSources :: BlockId -> LabelMap EdgeInfo -> LabelMap EdgeInfo
filterSources from :: BlockId
from m :: LabelMap EdgeInfo
m =
(KeyOf LabelMap -> EdgeInfo -> Bool)
-> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a.
IsMap map =>
(KeyOf map -> a -> Bool) -> map a -> map a
mapFilterWithKey (\to :: KeyOf LabelMap
to w :: EdgeInfo
w -> BlockId -> BlockId -> EdgeInfo -> Bool
f BlockId
from KeyOf LabelMap
BlockId
to EdgeInfo
w) LabelMap EdgeInfo
m
shortcutWeightMap :: LabelMap (Maybe BlockId) -> CFG -> CFG
shortcutWeightMap :: LabelMap (Maybe BlockId) -> CFG -> CFG
shortcutWeightMap cuts :: LabelMap (Maybe BlockId)
cuts cfg :: CFG
cfg =
(CFG -> (BlockId, Maybe BlockId) -> CFG)
-> CFG -> [(BlockId, Maybe BlockId)] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' CFG -> (BlockId, Maybe BlockId) -> CFG
applyMapping CFG
cfg ([(BlockId, Maybe BlockId)] -> CFG)
-> [(BlockId, Maybe BlockId)] -> CFG
forall a b. (a -> b) -> a -> b
$ LabelMap (Maybe BlockId) -> [(KeyOf LabelMap, Maybe BlockId)]
forall (map :: * -> *) a. IsMap map => map a -> [(KeyOf map, a)]
mapToList LabelMap (Maybe BlockId)
cuts
where
applyMapping :: CFG -> (BlockId,Maybe BlockId) -> CFG
applyMapping :: CFG -> (BlockId, Maybe BlockId) -> CFG
applyMapping m :: CFG
m (from :: BlockId
from, Nothing) =
KeyOf LabelMap -> CFG -> CFG
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> map a
mapDelete KeyOf LabelMap
BlockId
from (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(LabelMap EdgeInfo -> LabelMap EdgeInfo) -> CFG -> CFG
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (KeyOf LabelMap -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> map a
mapDelete KeyOf LabelMap
BlockId
from) (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$ CFG
m
applyMapping m :: CFG
m (from :: BlockId
from, Just to :: BlockId
to) =
let updatedMap :: CFG
updatedMap :: CFG
updatedMap
= (LabelMap EdgeInfo -> LabelMap EdgeInfo) -> CFG -> CFG
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((BlockId, BlockId) -> LabelMap EdgeInfo -> LabelMap EdgeInfo
shortcutEdge (BlockId
from,BlockId
to)) (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$
(KeyOf LabelMap -> CFG -> CFG
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> map a
mapDelete KeyOf LabelMap
BlockId
from CFG
m :: CFG )
in case KeyOf LabelMap -> LabelMap (Maybe BlockId) -> Maybe (Maybe BlockId)
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
to LabelMap (Maybe BlockId)
cuts of
Nothing -> CFG
updatedMap
Just dest :: Maybe BlockId
dest -> CFG -> (BlockId, Maybe BlockId) -> CFG
applyMapping CFG
updatedMap (BlockId
to, Maybe BlockId
dest)
shortcutEdge :: (BlockId, BlockId) -> LabelMap EdgeInfo -> LabelMap EdgeInfo
shortcutEdge :: (BlockId, BlockId) -> LabelMap EdgeInfo -> LabelMap EdgeInfo
shortcutEdge (from :: BlockId
from, to :: BlockId
to) m :: LabelMap EdgeInfo
m =
case KeyOf LabelMap -> LabelMap EdgeInfo -> Maybe EdgeInfo
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
from LabelMap EdgeInfo
m of
Just info :: EdgeInfo
info -> KeyOf LabelMap
-> EdgeInfo -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert KeyOf LabelMap
BlockId
to EdgeInfo
info (LabelMap EdgeInfo -> LabelMap EdgeInfo)
-> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> map a
mapDelete KeyOf LabelMap
BlockId
from LabelMap EdgeInfo
m
Nothing -> LabelMap EdgeInfo
m
addImmediateSuccessor :: HasDebugCallStack => BlockId -> BlockId -> CFG -> CFG
addImmediateSuccessor :: BlockId -> BlockId -> CFG -> CFG
addImmediateSuccessor node :: BlockId
node follower :: BlockId
follower cfg :: CFG
cfg
= CFG -> CFG
updateEdges (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockId -> BlockId -> EdgeWeight -> CFG -> CFG
addWeightEdge BlockId
node BlockId
follower EdgeWeight
uncondWeight (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$ CFG
cfg
where
uncondWeight :: EdgeWeight
uncondWeight = Int -> EdgeWeight
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> EdgeWeight) -> (DynFlags -> Int) -> DynFlags -> EdgeWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CfgWeights -> Int
D.uncondWeight (CfgWeights -> Int) -> (DynFlags -> CfgWeights) -> DynFlags -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
DynFlags -> CfgWeights
D.cfgWeightInfo (DynFlags -> EdgeWeight) -> DynFlags -> EdgeWeight
forall a b. (a -> b) -> a -> b
$ DynFlags
D.unsafeGlobalDynFlags
targets :: [(BlockId, EdgeInfo)]
targets = HasDebugCallStack => CFG -> BlockId -> [(BlockId, EdgeInfo)]
CFG -> BlockId -> [(BlockId, EdgeInfo)]
getSuccessorEdges CFG
cfg BlockId
node
successors :: [BlockId]
successors = ((BlockId, EdgeInfo) -> BlockId)
-> [(BlockId, EdgeInfo)] -> [BlockId]
forall a b. (a -> b) -> [a] -> [b]
map (BlockId, EdgeInfo) -> BlockId
forall a b. (a, b) -> a
fst [(BlockId, EdgeInfo)]
targets :: [BlockId]
updateEdges :: CFG -> CFG
updateEdges = CFG -> CFG
addNewSuccs (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CFG -> CFG
remOldSuccs
remOldSuccs :: CFG -> CFG
remOldSuccs m :: CFG
m = (CFG -> BlockId -> CFG) -> CFG -> [BlockId] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((BlockId -> CFG -> CFG) -> CFG -> BlockId -> CFG
forall a b c. (a -> b -> c) -> b -> a -> c
flip (BlockId -> BlockId -> CFG -> CFG
delEdge BlockId
node)) CFG
m [BlockId]
successors
addNewSuccs :: CFG -> CFG
addNewSuccs m :: CFG
m =
(CFG -> (BlockId, EdgeInfo) -> CFG)
-> CFG -> [(BlockId, EdgeInfo)] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\m' :: CFG
m' (t :: BlockId
t,info :: EdgeInfo
info) -> BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge BlockId
follower BlockId
t EdgeInfo
info CFG
m') CFG
m [(BlockId, EdgeInfo)]
targets
addEdge :: BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge :: BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge from :: BlockId
from to :: BlockId
to info :: EdgeInfo
info cfg :: CFG
cfg =
(Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo))
-> KeyOf LabelMap -> CFG -> CFG
forall (map :: * -> *) a.
IsMap map =>
(Maybe a -> Maybe a) -> KeyOf map -> map a -> map a
mapAlter Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
addFromToEdge KeyOf LabelMap
BlockId
from (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$
(Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo))
-> KeyOf LabelMap -> CFG -> CFG
forall (map :: * -> *) a.
IsMap map =>
(Maybe a -> Maybe a) -> KeyOf map -> map a -> map a
mapAlter Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
forall (map :: * -> *) a.
IsMap map =>
Maybe (map a) -> Maybe (map a)
addDestNode KeyOf LabelMap
BlockId
to CFG
cfg
where
addFromToEdge :: Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
addFromToEdge Nothing = LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a. a -> Maybe a
Just (LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo))
-> LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => KeyOf map -> a -> map a
mapSingleton KeyOf LabelMap
BlockId
to EdgeInfo
info
addFromToEdge (Just wm :: LabelMap EdgeInfo
wm) = LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a. a -> Maybe a
Just (LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo))
-> LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap
-> EdgeInfo -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert KeyOf LabelMap
BlockId
to EdgeInfo
info LabelMap EdgeInfo
wm
addDestNode :: Maybe (map a) -> Maybe (map a)
addDestNode Nothing = map a -> Maybe (map a)
forall a. a -> Maybe a
Just (map a -> Maybe (map a)) -> map a -> Maybe (map a)
forall a b. (a -> b) -> a -> b
$ map a
forall (map :: * -> *) a. IsMap map => map a
mapEmpty
addDestNode n :: Maybe (map a)
n@(Just _) = Maybe (map a)
n
addWeightEdge :: BlockId -> BlockId -> EdgeWeight -> CFG -> CFG
addWeightEdge :: BlockId -> BlockId -> EdgeWeight -> CFG -> CFG
addWeightEdge from :: BlockId
from to :: BlockId
to weight :: EdgeWeight
weight cfg :: CFG
cfg =
BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge BlockId
from BlockId
to (EdgeWeight -> EdgeInfo
forall n. Integral n => n -> EdgeInfo
mkWeightInfo EdgeWeight
weight) CFG
cfg
delEdge :: BlockId -> BlockId -> CFG -> CFG
delEdge :: BlockId -> BlockId -> CFG -> CFG
delEdge from :: BlockId
from to :: BlockId
to m :: CFG
m =
(Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo))
-> KeyOf LabelMap -> CFG -> CFG
forall (map :: * -> *) a.
IsMap map =>
(Maybe a -> Maybe a) -> KeyOf map -> map a -> map a
mapAlter Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
remDest KeyOf LabelMap
BlockId
from CFG
m
where
remDest :: Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
remDest Nothing = Maybe (LabelMap EdgeInfo)
forall a. Maybe a
Nothing
remDest (Just wm :: LabelMap EdgeInfo
wm) = LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a. a -> Maybe a
Just (LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo))
-> LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> map a
mapDelete KeyOf LabelMap
BlockId
to LabelMap EdgeInfo
wm
getSuccEdgesSorted :: CFG -> BlockId -> [(BlockId,EdgeInfo)]
getSuccEdgesSorted :: CFG -> BlockId -> [(BlockId, EdgeInfo)]
getSuccEdgesSorted m :: CFG
m bid :: BlockId
bid =
let destMap :: LabelMap EdgeInfo
destMap = LabelMap EdgeInfo -> KeyOf LabelMap -> CFG -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => a -> KeyOf map -> map a -> a
mapFindWithDefault LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => map a
mapEmpty KeyOf LabelMap
BlockId
bid CFG
m
cfgEdges :: [(KeyOf LabelMap, EdgeInfo)]
cfgEdges = LabelMap EdgeInfo -> [(KeyOf LabelMap, EdgeInfo)]
forall (map :: * -> *) a. IsMap map => map a -> [(KeyOf map, a)]
mapToList LabelMap EdgeInfo
destMap
sortedEdges :: [(BlockId, EdgeInfo)]
sortedEdges = ((BlockId, EdgeInfo) -> EdgeWeight)
-> [(BlockId, EdgeInfo)] -> [(BlockId, EdgeInfo)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortWith (EdgeWeight -> EdgeWeight
forall a. Num a => a -> a
negate (EdgeWeight -> EdgeWeight)
-> ((BlockId, EdgeInfo) -> EdgeWeight)
-> (BlockId, EdgeInfo)
-> EdgeWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EdgeInfo -> EdgeWeight
edgeWeight (EdgeInfo -> EdgeWeight)
-> ((BlockId, EdgeInfo) -> EdgeInfo)
-> (BlockId, EdgeInfo)
-> EdgeWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BlockId, EdgeInfo) -> EdgeInfo
forall a b. (a, b) -> b
snd) [(KeyOf LabelMap, EdgeInfo)]
[(BlockId, EdgeInfo)]
cfgEdges
in
[(BlockId, EdgeInfo)]
sortedEdges
getSuccessorEdges :: HasDebugCallStack => CFG -> BlockId -> [(BlockId,EdgeInfo)]
getSuccessorEdges :: CFG -> BlockId -> [(BlockId, EdgeInfo)]
getSuccessorEdges m :: CFG
m bid :: BlockId
bid = [(BlockId, EdgeInfo)]
-> (LabelMap EdgeInfo -> [(BlockId, EdgeInfo)])
-> Maybe (LabelMap EdgeInfo)
-> [(BlockId, EdgeInfo)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [(BlockId, EdgeInfo)]
lookupError LabelMap EdgeInfo -> [(BlockId, EdgeInfo)]
forall (map :: * -> *) a. IsMap map => map a -> [(KeyOf map, a)]
mapToList (KeyOf LabelMap -> CFG -> Maybe (LabelMap EdgeInfo)
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
bid CFG
m)
where
lookupError :: [(BlockId, EdgeInfo)]
lookupError = String -> SDoc -> [(BlockId, EdgeInfo)]
forall a. HasCallStack => String -> SDoc -> a
pprPanic "getSuccessorEdges: Block does not exist" (SDoc -> [(BlockId, EdgeInfo)]) -> SDoc -> [(BlockId, EdgeInfo)]
forall a b. (a -> b) -> a -> b
$
BlockId -> SDoc
forall a. Outputable a => a -> SDoc
ppr BlockId
bid SDoc -> SDoc -> SDoc
$$ String -> SDoc
text "CFG:" SDoc -> SDoc -> SDoc
<+> CFG -> SDoc
pprEdgeWeights CFG
m
getEdgeInfo :: BlockId -> BlockId -> CFG -> Maybe EdgeInfo
getEdgeInfo :: BlockId -> BlockId -> CFG -> Maybe EdgeInfo
getEdgeInfo from :: BlockId
from to :: BlockId
to m :: CFG
m
| Just wm :: LabelMap EdgeInfo
wm <- KeyOf LabelMap -> CFG -> Maybe (LabelMap EdgeInfo)
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
from CFG
m
, Just info :: EdgeInfo
info <- KeyOf LabelMap -> LabelMap EdgeInfo -> Maybe EdgeInfo
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
to LabelMap EdgeInfo
wm
= EdgeInfo -> Maybe EdgeInfo
forall a. a -> Maybe a
Just (EdgeInfo -> Maybe EdgeInfo) -> EdgeInfo -> Maybe EdgeInfo
forall a b. (a -> b) -> a -> b
$! EdgeInfo
info
| Bool
otherwise
= Maybe EdgeInfo
forall a. Maybe a
Nothing
reverseEdges :: CFG -> CFG
reverseEdges :: CFG -> CFG
reverseEdges cfg :: CFG
cfg = (CFG -> KeyOf LabelMap -> LabelMap EdgeInfo -> CFG)
-> CFG -> CFG -> CFG
forall (map :: * -> *) b a.
IsMap map =>
(b -> KeyOf map -> a -> b) -> b -> map a -> b
mapFoldlWithKey (\cfg :: CFG
cfg from :: KeyOf LabelMap
from toMap :: LabelMap EdgeInfo
toMap -> CFG -> BlockId -> LabelMap EdgeInfo -> CFG
go (CFG -> BlockId -> CFG
addNode CFG
cfg KeyOf LabelMap
BlockId
from) KeyOf LabelMap
BlockId
from LabelMap EdgeInfo
toMap) CFG
forall (map :: * -> *) a. IsMap map => map a
mapEmpty CFG
cfg
where
addNode :: CFG -> BlockId -> CFG
addNode :: CFG -> BlockId -> CFG
addNode cfg :: CFG
cfg b :: BlockId
b = (LabelMap EdgeInfo -> LabelMap EdgeInfo -> LabelMap EdgeInfo)
-> KeyOf LabelMap -> LabelMap EdgeInfo -> CFG -> CFG
forall (map :: * -> *) a.
IsMap map =>
(a -> a -> a) -> KeyOf map -> a -> map a -> map a
mapInsertWith LabelMap EdgeInfo -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => map a -> map a -> map a
mapUnion KeyOf LabelMap
BlockId
b LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => map a
mapEmpty CFG
cfg
go :: CFG -> BlockId -> (LabelMap EdgeInfo) -> CFG
go :: CFG -> BlockId -> LabelMap EdgeInfo -> CFG
go cfg :: CFG
cfg from :: BlockId
from toMap :: LabelMap EdgeInfo
toMap = (CFG -> KeyOf LabelMap -> EdgeInfo -> CFG)
-> CFG -> LabelMap EdgeInfo -> CFG
forall (map :: * -> *) b a.
IsMap map =>
(b -> KeyOf map -> a -> b) -> b -> map a -> b
mapFoldlWithKey (\cfg :: CFG
cfg to :: KeyOf LabelMap
to info :: EdgeInfo
info -> BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge KeyOf LabelMap
BlockId
to BlockId
from EdgeInfo
info CFG
cfg) CFG
cfg LabelMap EdgeInfo
toMap :: CFG
infoEdgeList :: CFG -> [CfgEdge]
infoEdgeList :: CFG -> [CfgEdge]
infoEdgeList m :: CFG
m =
(KeyOf LabelMap -> LabelMap EdgeInfo -> [CfgEdge])
-> CFG -> [CfgEdge]
forall (map :: * -> *) m a.
(IsMap map, Monoid m) =>
(KeyOf map -> a -> m) -> map a -> m
mapFoldMapWithKey
(\from :: KeyOf LabelMap
from toMap :: LabelMap EdgeInfo
toMap ->
((BlockId, EdgeInfo) -> CfgEdge)
-> [(BlockId, EdgeInfo)] -> [CfgEdge]
forall a b. (a -> b) -> [a] -> [b]
map (\(to :: BlockId
to,info :: EdgeInfo
info) -> BlockId -> BlockId -> EdgeInfo -> CfgEdge
CfgEdge KeyOf LabelMap
BlockId
from BlockId
to EdgeInfo
info) (LabelMap EdgeInfo -> [(KeyOf LabelMap, EdgeInfo)]
forall (map :: * -> *) a. IsMap map => map a -> [(KeyOf map, a)]
mapToList LabelMap EdgeInfo
toMap))
CFG
m
weightedEdgeList :: CFG -> [(BlockId,BlockId,EdgeWeight)]
weightedEdgeList :: CFG -> [(BlockId, BlockId, EdgeWeight)]
weightedEdgeList m :: CFG
m =
(KeyOf LabelMap
-> LabelMap EdgeInfo -> [(BlockId, BlockId, EdgeWeight)])
-> CFG -> [(BlockId, BlockId, EdgeWeight)]
forall (map :: * -> *) m a.
(IsMap map, Monoid m) =>
(KeyOf map -> a -> m) -> map a -> m
mapFoldMapWithKey
(\from :: KeyOf LabelMap
from toMap :: LabelMap EdgeInfo
toMap ->
((BlockId, EdgeInfo) -> (BlockId, BlockId, EdgeWeight))
-> [(BlockId, EdgeInfo)] -> [(BlockId, BlockId, EdgeWeight)]
forall a b. (a -> b) -> [a] -> [b]
map (\(to :: BlockId
to,info :: EdgeInfo
info) ->
(KeyOf LabelMap
BlockId
from,BlockId
to, EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
info)) (LabelMap EdgeInfo -> [(KeyOf LabelMap, EdgeInfo)]
forall (map :: * -> *) a. IsMap map => map a -> [(KeyOf map, a)]
mapToList LabelMap EdgeInfo
toMap))
CFG
m
edgeList :: CFG -> [Edge]
edgeList :: CFG -> [(BlockId, BlockId)]
edgeList m :: CFG
m =
(KeyOf LabelMap -> LabelMap EdgeInfo -> [(BlockId, BlockId)])
-> CFG -> [(BlockId, BlockId)]
forall (map :: * -> *) m a.
(IsMap map, Monoid m) =>
(KeyOf map -> a -> m) -> map a -> m
mapFoldMapWithKey (\from :: KeyOf LabelMap
from toMap :: LabelMap EdgeInfo
toMap -> (BlockId -> (BlockId, BlockId))
-> [BlockId] -> [(BlockId, BlockId)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (KeyOf LabelMap
BlockId
from,) (LabelMap EdgeInfo -> [KeyOf LabelMap]
forall (map :: * -> *) a. IsMap map => map a -> [KeyOf map]
mapKeys LabelMap EdgeInfo
toMap)) CFG
m
getSuccessors :: HasDebugCallStack => CFG -> BlockId -> [BlockId]
getSuccessors :: CFG -> BlockId -> [BlockId]
getSuccessors m :: CFG
m bid :: BlockId
bid
| Just wm :: LabelMap EdgeInfo
wm <- KeyOf LabelMap -> CFG -> Maybe (LabelMap EdgeInfo)
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
bid CFG
m
= LabelMap EdgeInfo -> [KeyOf LabelMap]
forall (map :: * -> *) a. IsMap map => map a -> [KeyOf map]
mapKeys LabelMap EdgeInfo
wm
| Bool
otherwise = [BlockId]
lookupError
where
lookupError :: [BlockId]
lookupError = String -> SDoc -> [BlockId]
forall a. HasCallStack => String -> SDoc -> a
pprPanic "getSuccessors: Block does not exist" (SDoc -> [BlockId]) -> SDoc -> [BlockId]
forall a b. (a -> b) -> a -> b
$
BlockId -> SDoc
forall a. Outputable a => a -> SDoc
ppr BlockId
bid SDoc -> SDoc -> SDoc
<+> CFG -> SDoc
pprEdgeWeights CFG
m
pprEdgeWeights :: CFG -> SDoc
pprEdgeWeights :: CFG -> SDoc
pprEdgeWeights m :: CFG
m =
let edges :: [(BlockId, BlockId, EdgeWeight)]
edges = [(BlockId, BlockId, EdgeWeight)]
-> [(BlockId, BlockId, EdgeWeight)]
forall a. Ord a => [a] -> [a]
sort ([(BlockId, BlockId, EdgeWeight)]
-> [(BlockId, BlockId, EdgeWeight)])
-> [(BlockId, BlockId, EdgeWeight)]
-> [(BlockId, BlockId, EdgeWeight)]
forall a b. (a -> b) -> a -> b
$ CFG -> [(BlockId, BlockId, EdgeWeight)]
weightedEdgeList CFG
m
printEdge :: (a, a, a) -> SDoc
printEdge (from :: a
from, to :: a
to, weight :: a
weight)
= String -> SDoc
text "\t" SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
from SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "->" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
to SDoc -> SDoc -> SDoc
<>
String -> SDoc
text "[label=\"" SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
weight SDoc -> SDoc -> SDoc
<> String -> SDoc
text "\",weight=\"" SDoc -> SDoc -> SDoc
<>
a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
weight SDoc -> SDoc -> SDoc
<> String -> SDoc
text "\"];\n"
printNode :: a -> SDoc
printNode node :: a
node
= String -> SDoc
text "\t" SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
node SDoc -> SDoc -> SDoc
<> String -> SDoc
text ";\n"
getEdgeNodes :: (a, a, c) -> [a]
getEdgeNodes (from :: a
from, to :: a
to, _weight :: c
_weight) = [a
from,a
to]
edgeNodes :: LabelSet
edgeNodes = [ElemOf LabelSet] -> LabelSet
forall set. IsSet set => [ElemOf set] -> set
setFromList ([ElemOf LabelSet] -> LabelSet) -> [ElemOf LabelSet] -> LabelSet
forall a b. (a -> b) -> a -> b
$ ((BlockId, BlockId, EdgeWeight) -> [BlockId])
-> [(BlockId, BlockId, EdgeWeight)] -> [BlockId]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (BlockId, BlockId, EdgeWeight) -> [BlockId]
forall a c. (a, a, c) -> [a]
getEdgeNodes [(BlockId, BlockId, EdgeWeight)]
edges :: LabelSet
nodes :: [BlockId]
nodes = (BlockId -> Bool) -> [BlockId] -> [BlockId]
forall a. (a -> Bool) -> [a] -> [a]
filter (\n :: BlockId
n -> (Bool -> Bool
not (Bool -> Bool) -> (LabelSet -> Bool) -> LabelSet -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElemOf LabelSet -> LabelSet -> Bool
forall set. IsSet set => ElemOf set -> set -> Bool
setMember ElemOf LabelSet
BlockId
n) LabelSet
edgeNodes) ([BlockId] -> [BlockId]) -> (CFG -> [BlockId]) -> CFG -> [BlockId]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CFG -> [BlockId]
forall (map :: * -> *) a. IsMap map => map a -> [KeyOf map]
mapKeys (CFG -> [BlockId]) -> CFG -> [BlockId]
forall a b. (a -> b) -> a -> b
$ (LabelMap EdgeInfo -> Bool) -> CFG -> CFG
forall (map :: * -> *) a.
IsMap map =>
(a -> Bool) -> map a -> map a
mapFilter LabelMap EdgeInfo -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null CFG
m
in
String -> SDoc
text "digraph {\n" SDoc -> SDoc -> SDoc
<>
((SDoc -> SDoc -> SDoc) -> SDoc -> [SDoc] -> SDoc
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SDoc -> SDoc -> SDoc
(<>) SDoc
empty (((BlockId, BlockId, EdgeWeight) -> SDoc)
-> [(BlockId, BlockId, EdgeWeight)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (BlockId, BlockId, EdgeWeight) -> SDoc
forall a a a.
(Outputable a, Outputable a, Outputable a) =>
(a, a, a) -> SDoc
printEdge [(BlockId, BlockId, EdgeWeight)]
edges)) SDoc -> SDoc -> SDoc
<>
((SDoc -> SDoc -> SDoc) -> SDoc -> [SDoc] -> SDoc
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SDoc -> SDoc -> SDoc
(<>) SDoc
empty ((BlockId -> SDoc) -> [BlockId] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map BlockId -> SDoc
forall a. Outputable a => a -> SDoc
printNode [BlockId]
nodes)) SDoc -> SDoc -> SDoc
<>
String -> SDoc
text "}\n"
{-# INLINE updateEdgeWeight #-}
updateEdgeWeight :: (EdgeWeight -> EdgeWeight) -> Edge -> CFG -> CFG
updateEdgeWeight :: (EdgeWeight -> EdgeWeight) -> (BlockId, BlockId) -> CFG -> CFG
updateEdgeWeight f :: EdgeWeight -> EdgeWeight
f (from :: BlockId
from, to :: BlockId
to) cfg :: CFG
cfg
| Just oldInfo :: EdgeInfo
oldInfo <- BlockId -> BlockId -> CFG -> Maybe EdgeInfo
getEdgeInfo BlockId
from BlockId
to CFG
cfg
= let oldWeight :: EdgeWeight
oldWeight = EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
oldInfo
newWeight :: EdgeWeight
newWeight = EdgeWeight -> EdgeWeight
f EdgeWeight
oldWeight
in BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge BlockId
from BlockId
to (EdgeInfo
oldInfo {edgeWeight :: EdgeWeight
edgeWeight = EdgeWeight
newWeight}) CFG
cfg
| Bool
otherwise
= String -> CFG
forall a. String -> a
panic "Trying to update invalid edge"
mapWeights :: (BlockId -> BlockId -> EdgeWeight -> EdgeWeight) -> CFG -> CFG
mapWeights :: (BlockId -> BlockId -> EdgeWeight -> EdgeWeight) -> CFG -> CFG
mapWeights f :: BlockId -> BlockId -> EdgeWeight -> EdgeWeight
f cfg :: CFG
cfg =
(CFG -> CfgEdge -> CFG) -> CFG -> [CfgEdge] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\cfg :: CFG
cfg (CfgEdge from :: BlockId
from to :: BlockId
to info :: EdgeInfo
info) ->
let oldWeight :: EdgeWeight
oldWeight = EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
info
newWeight :: EdgeWeight
newWeight = BlockId -> BlockId -> EdgeWeight -> EdgeWeight
f BlockId
from BlockId
to EdgeWeight
oldWeight
in BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge BlockId
from BlockId
to (EdgeInfo
info {edgeWeight :: EdgeWeight
edgeWeight = EdgeWeight
newWeight}) CFG
cfg)
CFG
cfg (CFG -> [CfgEdge]
infoEdgeList CFG
cfg)
addNodesBetween :: CFG -> [(BlockId,BlockId,BlockId)] -> CFG
addNodesBetween :: CFG -> [(BlockId, BlockId, BlockId)] -> CFG
addNodesBetween m :: CFG
m updates :: [(BlockId, BlockId, BlockId)]
updates =
(CFG -> (BlockId, BlockId, BlockId, EdgeInfo) -> CFG)
-> CFG -> [(BlockId, BlockId, BlockId, EdgeInfo)] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' CFG -> (BlockId, BlockId, BlockId, EdgeInfo) -> CFG
updateWeight CFG
m ([(BlockId, BlockId, BlockId, EdgeInfo)] -> CFG)
-> ([(BlockId, BlockId, BlockId)]
-> [(BlockId, BlockId, BlockId, EdgeInfo)])
-> [(BlockId, BlockId, BlockId)]
-> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
[(BlockId, BlockId, BlockId)]
-> [(BlockId, BlockId, BlockId, EdgeInfo)]
weightUpdates ([(BlockId, BlockId, BlockId)] -> CFG)
-> [(BlockId, BlockId, BlockId)] -> CFG
forall a b. (a -> b) -> a -> b
$ [(BlockId, BlockId, BlockId)]
updates
where
weight :: EdgeWeight
weight = Int -> EdgeWeight
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> EdgeWeight) -> (DynFlags -> Int) -> DynFlags -> EdgeWeight
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CfgWeights -> Int
D.uncondWeight (CfgWeights -> Int) -> (DynFlags -> CfgWeights) -> DynFlags -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
DynFlags -> CfgWeights
D.cfgWeightInfo (DynFlags -> EdgeWeight) -> DynFlags -> EdgeWeight
forall a b. (a -> b) -> a -> b
$ DynFlags
D.unsafeGlobalDynFlags
weightUpdates :: [(BlockId, BlockId, BlockId)]
-> [(BlockId, BlockId, BlockId, EdgeInfo)]
weightUpdates = ((BlockId, BlockId, BlockId)
-> (BlockId, BlockId, BlockId, EdgeInfo))
-> [(BlockId, BlockId, BlockId)]
-> [(BlockId, BlockId, BlockId, EdgeInfo)]
forall a b. (a -> b) -> [a] -> [b]
map (BlockId, BlockId, BlockId)
-> (BlockId, BlockId, BlockId, EdgeInfo)
getWeight
getWeight :: (BlockId,BlockId,BlockId) -> (BlockId,BlockId,BlockId,EdgeInfo)
getWeight :: (BlockId, BlockId, BlockId)
-> (BlockId, BlockId, BlockId, EdgeInfo)
getWeight (from :: BlockId
from,between :: BlockId
between,old :: BlockId
old)
| Just edgeInfo :: EdgeInfo
edgeInfo <- BlockId -> BlockId -> CFG -> Maybe EdgeInfo
getEdgeInfo BlockId
from BlockId
old CFG
m
= (BlockId
from,BlockId
between,BlockId
old,EdgeInfo
edgeInfo)
| Bool
otherwise
= String -> SDoc -> (BlockId, BlockId, BlockId, EdgeInfo)
forall a. HasCallStack => String -> SDoc -> a
pprPanic "Can't find weight for edge that should have one" (
String -> SDoc
text "triple" SDoc -> SDoc -> SDoc
<+> (BlockId, BlockId, BlockId) -> SDoc
forall a. Outputable a => a -> SDoc
ppr (BlockId
from,BlockId
between,BlockId
old) SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "updates" SDoc -> SDoc -> SDoc
<+> [(BlockId, BlockId, BlockId)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(BlockId, BlockId, BlockId)]
updates SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "cfg:" SDoc -> SDoc -> SDoc
<+> CFG -> SDoc
pprEdgeWeights CFG
m )
updateWeight :: CFG -> (BlockId,BlockId,BlockId,EdgeInfo) -> CFG
updateWeight :: CFG -> (BlockId, BlockId, BlockId, EdgeInfo) -> CFG
updateWeight m :: CFG
m (from :: BlockId
from,between :: BlockId
between,old :: BlockId
old,edgeInfo :: EdgeInfo
edgeInfo)
= BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
addEdge BlockId
from BlockId
between EdgeInfo
edgeInfo (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
BlockId -> BlockId -> EdgeWeight -> CFG -> CFG
addWeightEdge BlockId
between BlockId
old EdgeWeight
weight (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
BlockId -> BlockId -> CFG -> CFG
delEdge BlockId
from BlockId
old (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$ CFG
m
getCfgProc :: D.CfgWeights -> RawCmmDecl -> CFG
getCfgProc :: CfgWeights -> RawCmmDecl -> CFG
getCfgProc _ (CmmData {}) = CFG
forall (map :: * -> *) a. IsMap map => map a
mapEmpty
getCfgProc weights :: CfgWeights
weights (CmmProc _info :: LabelMap CmmStatics
_info _lab :: CLabel
_lab _live :: [GlobalReg]
_live graph :: CmmGraph
graph)
| [CmmBlock] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CmmGraph -> [CmmBlock]
toBlockList CmmGraph
graph) = CFG
forall (map :: * -> *) a. IsMap map => map a
mapEmpty
| Bool
otherwise = CfgWeights -> CmmGraph -> CFG
getCfg CfgWeights
weights CmmGraph
graph
getCfg :: D.CfgWeights -> CmmGraph -> CFG
getCfg :: CfgWeights -> CmmGraph -> CFG
getCfg weights :: CfgWeights
weights graph :: CmmGraph
graph =
(CFG -> ((BlockId, BlockId), EdgeInfo) -> CFG)
-> CFG -> [((BlockId, BlockId), EdgeInfo)] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' CFG -> ((BlockId, BlockId), EdgeInfo) -> CFG
insertEdge CFG
edgelessCfg ([((BlockId, BlockId), EdgeInfo)] -> CFG)
-> [((BlockId, BlockId), EdgeInfo)] -> CFG
forall a b. (a -> b) -> a -> b
$ (CmmBlock -> [((BlockId, BlockId), EdgeInfo)])
-> [CmmBlock] -> [((BlockId, BlockId), EdgeInfo)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CmmBlock -> [((BlockId, BlockId), EdgeInfo)]
getBlockEdges [CmmBlock]
blocks
where
D.CFGWeights
{ uncondWeight :: CfgWeights -> Int
D.uncondWeight = Int
uncondWeight
, condBranchWeight :: CfgWeights -> Int
D.condBranchWeight = Int
condBranchWeight
, switchWeight :: CfgWeights -> Int
D.switchWeight = Int
switchWeight
, callWeight :: CfgWeights -> Int
D.callWeight = Int
callWeight
, likelyCondWeight :: CfgWeights -> Int
D.likelyCondWeight = Int
likelyCondWeight
, unlikelyCondWeight :: CfgWeights -> Int
D.unlikelyCondWeight = Int
unlikelyCondWeight
} = CfgWeights
weights
edgelessCfg :: CFG
edgelessCfg = [(KeyOf LabelMap, LabelMap EdgeInfo)] -> CFG
forall (map :: * -> *) a. IsMap map => [(KeyOf map, a)] -> map a
mapFromList ([(KeyOf LabelMap, LabelMap EdgeInfo)] -> CFG)
-> [(KeyOf LabelMap, LabelMap EdgeInfo)] -> CFG
forall a b. (a -> b) -> a -> b
$ [BlockId] -> [LabelMap EdgeInfo] -> [(BlockId, LabelMap EdgeInfo)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((CmmBlock -> BlockId) -> [CmmBlock] -> [BlockId]
forall a b. (a -> b) -> [a] -> [b]
map CmmBlock -> BlockId
forall (thing :: * -> * -> *) x.
NonLocal thing =>
thing C x -> BlockId
G.entryLabel [CmmBlock]
blocks) (LabelMap EdgeInfo -> [LabelMap EdgeInfo]
forall a. a -> [a]
repeat LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => map a
mapEmpty)
insertEdge :: CFG -> ((BlockId,BlockId),EdgeInfo) -> CFG
insertEdge :: CFG -> ((BlockId, BlockId), EdgeInfo) -> CFG
insertEdge m :: CFG
m ((from :: BlockId
from,to :: BlockId
to),weight :: EdgeInfo
weight) =
(Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo))
-> KeyOf LabelMap -> CFG -> CFG
forall (map :: * -> *) a.
IsMap map =>
(Maybe a -> Maybe a) -> KeyOf map -> map a -> map a
mapAlter Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
f KeyOf LabelMap
BlockId
from CFG
m
where
f :: Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
f :: Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
f Nothing = LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a. a -> Maybe a
Just (LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo))
-> LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a. IsMap map => KeyOf map -> a -> map a
mapSingleton KeyOf LabelMap
BlockId
to EdgeInfo
weight
f (Just destMap :: LabelMap EdgeInfo
destMap) = LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a. a -> Maybe a
Just (LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo))
-> LabelMap EdgeInfo -> Maybe (LabelMap EdgeInfo)
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap
-> EdgeInfo -> LabelMap EdgeInfo -> LabelMap EdgeInfo
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert KeyOf LabelMap
BlockId
to EdgeInfo
weight LabelMap EdgeInfo
destMap
getBlockEdges :: CmmBlock -> [((BlockId,BlockId),EdgeInfo)]
getBlockEdges :: CmmBlock -> [((BlockId, BlockId), EdgeInfo)]
getBlockEdges block :: CmmBlock
block =
case CmmNode O C
branch of
CmmBranch dest :: BlockId
dest -> [BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
dest Int
uncondWeight]
CmmCondBranch _c :: CmmExpr
_c t :: BlockId
t f :: BlockId
f l :: Maybe Bool
l
| Maybe Bool
l Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Bool
forall a. Maybe a
Nothing ->
[BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
f Int
condBranchWeight, BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
t Int
condBranchWeight]
| Maybe Bool
l Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True ->
[BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
f Int
unlikelyCondWeight, BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
t Int
likelyCondWeight]
| Maybe Bool
l Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False ->
[BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
f Int
likelyCondWeight, BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
t Int
unlikelyCondWeight]
(CmmSwitch _e :: CmmExpr
_e ids :: SwitchTargets
ids) ->
let switchTargets :: [BlockId]
switchTargets = SwitchTargets -> [BlockId]
switchTargetsToList SwitchTargets
ids
adjustedWeight :: Int
adjustedWeight =
if ([BlockId] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [BlockId]
switchTargets Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 10) then -1 else Int
switchWeight
in (BlockId -> ((BlockId, BlockId), EdgeInfo))
-> [BlockId] -> [((BlockId, BlockId), EdgeInfo)]
forall a b. (a -> b) -> [a] -> [b]
map (\x :: BlockId
x -> BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
x Int
adjustedWeight) [BlockId]
switchTargets
(CmmCall { cml_cont :: CmmNode O C -> Maybe BlockId
cml_cont = Just cont :: BlockId
cont}) -> [BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
cont Int
callWeight]
(CmmForeignCall {succ :: CmmNode O C -> BlockId
Cmm.succ = BlockId
cont}) -> [BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge BlockId
cont Int
callWeight]
(CmmCall { cml_cont :: CmmNode O C -> Maybe BlockId
cml_cont = Maybe BlockId
Nothing }) -> []
other :: CmmNode O C
other ->
String
-> [((BlockId, BlockId), EdgeInfo)]
-> [((BlockId, BlockId), EdgeInfo)]
forall a. String -> a
panic "Foo" ([((BlockId, BlockId), EdgeInfo)]
-> [((BlockId, BlockId), EdgeInfo)])
-> [((BlockId, BlockId), EdgeInfo)]
-> [((BlockId, BlockId), EdgeInfo)]
forall a b. (a -> b) -> a -> b
$
ASSERT2(False, ppr "Unkown successor cause:" <>
(ppr branch <+> text "=>" <> ppr (G.successors other)))
(BlockId -> ((BlockId, BlockId), EdgeInfo))
-> [BlockId] -> [((BlockId, BlockId), EdgeInfo)]
forall a b. (a -> b) -> [a] -> [b]
map (\x :: BlockId
x -> ((BlockId
bid,BlockId
x),Int -> EdgeInfo
mkEdgeInfo 0)) ([BlockId] -> [((BlockId, BlockId), EdgeInfo)])
-> [BlockId] -> [((BlockId, BlockId), EdgeInfo)]
forall a b. (a -> b) -> a -> b
$ CmmNode O C -> [BlockId]
forall (thing :: * -> * -> *) e.
NonLocal thing =>
thing e C -> [BlockId]
G.successors CmmNode O C
other
where
bid :: BlockId
bid = CmmBlock -> BlockId
forall (thing :: * -> * -> *) x.
NonLocal thing =>
thing C x -> BlockId
G.entryLabel CmmBlock
block
mkEdgeInfo :: Int -> EdgeInfo
mkEdgeInfo = TransitionSource -> EdgeWeight -> EdgeInfo
EdgeInfo (CmmNode O C -> TransitionSource
CmmSource CmmNode O C
branch) (EdgeWeight -> EdgeInfo) -> (Int -> EdgeWeight) -> Int -> EdgeInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> EdgeWeight
forall a b. (Integral a, Num b) => a -> b
fromIntegral
mkEdge :: BlockId -> Int -> ((BlockId, BlockId), EdgeInfo)
mkEdge target :: BlockId
target weight :: Int
weight = ((BlockId
bid,BlockId
target), Int -> EdgeInfo
mkEdgeInfo Int
weight)
branch :: CmmNode O C
branch = CmmBlock -> CmmNode O C
forall (n :: * -> * -> *) x. Block n x C -> n O C
lastNode CmmBlock
block :: CmmNode O C
blocks :: [CmmBlock]
blocks = CmmGraph -> [CmmBlock]
revPostorder CmmGraph
graph :: [CmmBlock]
findBackEdges :: HasDebugCallStack => BlockId -> CFG -> Edges
findBackEdges :: BlockId -> CFG -> [(BlockId, BlockId)]
findBackEdges root :: BlockId
root cfg :: CFG
cfg =
(((BlockId, BlockId), EdgeType) -> (BlockId, BlockId))
-> [((BlockId, BlockId), EdgeType)] -> [(BlockId, BlockId)]
forall a b. (a -> b) -> [a] -> [b]
map ((BlockId, BlockId), EdgeType) -> (BlockId, BlockId)
forall a b. (a, b) -> a
fst ([((BlockId, BlockId), EdgeType)] -> [(BlockId, BlockId)])
-> ([((BlockId, BlockId), EdgeType)]
-> [((BlockId, BlockId), EdgeType)])
-> [((BlockId, BlockId), EdgeType)]
-> [(BlockId, BlockId)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(((BlockId, BlockId), EdgeType) -> Bool)
-> [((BlockId, BlockId), EdgeType)]
-> [((BlockId, BlockId), EdgeType)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\x :: ((BlockId, BlockId), EdgeType)
x -> ((BlockId, BlockId), EdgeType) -> EdgeType
forall a b. (a, b) -> b
snd ((BlockId, BlockId), EdgeType)
x EdgeType -> EdgeType -> Bool
forall a. Eq a => a -> a -> Bool
== EdgeType
Backward) ([((BlockId, BlockId), EdgeType)] -> [(BlockId, BlockId)])
-> [((BlockId, BlockId), EdgeType)] -> [(BlockId, BlockId)]
forall a b. (a -> b) -> a -> b
$ [((BlockId, BlockId), EdgeType)]
typedEdges
where
edges :: [(BlockId, BlockId)]
edges = CFG -> [(BlockId, BlockId)]
edgeList CFG
cfg :: [(BlockId,BlockId)]
getSuccs :: BlockId -> [BlockId]
getSuccs = HasDebugCallStack => CFG -> BlockId -> [BlockId]
CFG -> BlockId -> [BlockId]
getSuccessors CFG
cfg :: BlockId -> [BlockId]
typedEdges :: [((BlockId, BlockId), EdgeType)]
typedEdges =
BlockId
-> (BlockId -> [BlockId])
-> [(BlockId, BlockId)]
-> [((BlockId, BlockId), EdgeType)]
forall key.
Uniquable key =>
key -> (key -> [key]) -> [(key, key)] -> [((key, key), EdgeType)]
classifyEdges BlockId
root BlockId -> [BlockId]
getSuccs [(BlockId, BlockId)]
edges :: [((BlockId,BlockId),EdgeType)]
optimizeCFG :: HasDebugCallStack => D.CfgWeights -> RawCmmDecl -> CFG -> CFG
optimizeCFG :: CfgWeights -> RawCmmDecl -> CFG -> CFG
optimizeCFG _ (CmmData {}) cfg :: CFG
cfg = CFG
cfg
optimizeCFG weights :: CfgWeights
weights (CmmProc info :: LabelMap CmmStatics
info _lab :: CLabel
_lab _live :: [GlobalReg]
_live graph :: CmmGraph
graph) cfg :: CFG
cfg =
CFG -> CFG
favourFewerPreds (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
LabelMap CmmStatics -> CFG -> CFG
forall a. LabelMap a -> CFG -> CFG
penalizeInfoTables LabelMap CmmStatics
info (CFG -> CFG) -> (CFG -> CFG) -> CFG -> CFG
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
BlockId -> CFG -> CFG
increaseBackEdgeWeight (CmmGraph -> BlockId
forall (n :: * -> * -> *). GenCmmGraph n -> BlockId
g_entry CmmGraph
graph) (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$ CFG
cfg
where
increaseBackEdgeWeight :: BlockId -> CFG -> CFG
increaseBackEdgeWeight :: BlockId -> CFG -> CFG
increaseBackEdgeWeight root :: BlockId
root cfg :: CFG
cfg =
let backedges :: [(BlockId, BlockId)]
backedges = HasDebugCallStack => BlockId -> CFG -> [(BlockId, BlockId)]
BlockId -> CFG -> [(BlockId, BlockId)]
findBackEdges BlockId
root CFG
cfg
update :: EdgeWeight -> EdgeWeight
update weight :: EdgeWeight
weight
| EdgeWeight
weight EdgeWeight -> EdgeWeight -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = 0
| Bool
otherwise
= EdgeWeight
weight EdgeWeight -> EdgeWeight -> EdgeWeight
forall a. Num a => a -> a -> a
+ Int -> EdgeWeight
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CfgWeights -> Int
D.backEdgeBonus CfgWeights
weights)
in (CFG -> (BlockId, BlockId) -> CFG)
-> CFG -> [(BlockId, BlockId)] -> CFG
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\cfg :: CFG
cfg edge :: (BlockId, BlockId)
edge -> (EdgeWeight -> EdgeWeight) -> (BlockId, BlockId) -> CFG -> CFG
updateEdgeWeight EdgeWeight -> EdgeWeight
update (BlockId, BlockId)
edge CFG
cfg)
CFG
cfg [(BlockId, BlockId)]
backedges
penalizeInfoTables :: LabelMap a -> CFG -> CFG
penalizeInfoTables :: LabelMap a -> CFG -> CFG
penalizeInfoTables info :: LabelMap a
info cfg :: CFG
cfg =
(BlockId -> BlockId -> EdgeWeight -> EdgeWeight) -> CFG -> CFG
mapWeights BlockId -> BlockId -> EdgeWeight -> EdgeWeight
fupdate CFG
cfg
where
fupdate :: BlockId -> BlockId -> EdgeWeight -> EdgeWeight
fupdate :: BlockId -> BlockId -> EdgeWeight -> EdgeWeight
fupdate _ to :: BlockId
to weight :: EdgeWeight
weight
| KeyOf LabelMap -> LabelMap a -> Bool
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> Bool
mapMember KeyOf LabelMap
BlockId
to LabelMap a
info
= EdgeWeight
weight EdgeWeight -> EdgeWeight -> EdgeWeight
forall a. Num a => a -> a -> a
- (Int -> EdgeWeight
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> EdgeWeight) -> Int -> EdgeWeight
forall a b. (a -> b) -> a -> b
$ CfgWeights -> Int
D.infoTablePenalty CfgWeights
weights)
| Bool
otherwise = EdgeWeight
weight
favourFewerPreds :: CFG -> CFG
favourFewerPreds :: CFG -> CFG
favourFewerPreds cfg :: CFG
cfg =
let
revCfg :: CFG
revCfg =
CFG -> CFG
reverseEdges (CFG -> CFG) -> CFG -> CFG
forall a b. (a -> b) -> a -> b
$ (BlockId -> BlockId -> EdgeInfo -> Bool) -> CFG -> CFG
filterEdges
(\_from :: BlockId
_from -> BlockId -> EdgeInfo -> Bool
fallthroughTarget) CFG
cfg
predCount :: BlockId -> Int
predCount n :: BlockId
n = [(BlockId, EdgeInfo)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([(BlockId, EdgeInfo)] -> Int) -> [(BlockId, EdgeInfo)] -> Int
forall a b. (a -> b) -> a -> b
$ HasDebugCallStack => CFG -> BlockId -> [(BlockId, EdgeInfo)]
CFG -> BlockId -> [(BlockId, EdgeInfo)]
getSuccessorEdges CFG
revCfg BlockId
n
nodes :: LabelSet
nodes = CFG -> LabelSet
getCfgNodes CFG
cfg
modifiers :: Int -> Int -> (EdgeWeight, EdgeWeight)
modifiers :: Int -> Int -> (EdgeWeight, EdgeWeight)
modifiers preds1 :: Int
preds1 preds2 :: Int
preds2
| Int
preds1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
preds2 = ( 1,-1)
| Int
preds1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
preds2 = ( 0, 0)
| Bool
otherwise = (-1, 1)
update :: CFG -> BlockId -> CFG
update cfg :: CFG
cfg node :: BlockId
node
| [(s1 :: BlockId
s1,e1 :: EdgeInfo
e1),(s2 :: BlockId
s2,e2 :: EdgeInfo
e2)] <- HasDebugCallStack => CFG -> BlockId -> [(BlockId, EdgeInfo)]
CFG -> BlockId -> [(BlockId, EdgeInfo)]
getSuccessorEdges CFG
cfg BlockId
node
, EdgeWeight
w1 <- EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
e1
, EdgeWeight
w2 <- EdgeInfo -> EdgeWeight
edgeWeight EdgeInfo
e2
, EdgeWeight
w1 EdgeWeight -> EdgeWeight -> Bool
forall a. Eq a => a -> a -> Bool
== EdgeWeight
w2
, (mod1 :: EdgeWeight
mod1,mod2 :: EdgeWeight
mod2) <- Int -> Int -> (EdgeWeight, EdgeWeight)
modifiers (BlockId -> Int
predCount BlockId
s1) (BlockId -> Int
predCount BlockId
s2)
= (\cfg' :: CFG
cfg' ->
(CFG -> (EdgeWeight -> EdgeWeight) -> BlockId -> BlockId -> CFG
adjustEdgeWeight CFG
cfg' (EdgeWeight -> EdgeWeight -> EdgeWeight
forall a. Num a => a -> a -> a
+EdgeWeight
mod2) BlockId
node BlockId
s2))
(CFG -> (EdgeWeight -> EdgeWeight) -> BlockId -> BlockId -> CFG
adjustEdgeWeight CFG
cfg (EdgeWeight -> EdgeWeight -> EdgeWeight
forall a. Num a => a -> a -> a
+EdgeWeight
mod1) BlockId
node BlockId
s1)
| Bool
otherwise
= CFG
cfg
in (CFG -> ElemOf LabelSet -> CFG) -> CFG -> LabelSet -> CFG
forall set b. IsSet set => (b -> ElemOf set -> b) -> b -> set -> b
setFoldl CFG -> ElemOf LabelSet -> CFG
CFG -> BlockId -> CFG
update CFG
cfg LabelSet
nodes
where
fallthroughTarget :: BlockId -> EdgeInfo -> Bool
fallthroughTarget :: BlockId -> EdgeInfo -> Bool
fallthroughTarget to :: BlockId
to (EdgeInfo source :: TransitionSource
source _weight :: EdgeWeight
_weight)
| KeyOf LabelMap -> LabelMap CmmStatics -> Bool
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> Bool
mapMember KeyOf LabelMap
BlockId
to LabelMap CmmStatics
info = Bool
False
| TransitionSource
AsmCodeGen <- TransitionSource
source = Bool
True
| CmmSource (CmmBranch {}) <- TransitionSource
source = Bool
True
| CmmSource (CmmCondBranch {}) <- TransitionSource
source = Bool
True
| Bool
otherwise = Bool
False
loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool
loopMembers :: CFG -> LabelMap Bool
loopMembers cfg :: CFG
cfg =
(LabelMap Bool -> SCC BlockId -> LabelMap Bool)
-> LabelMap Bool -> [SCC BlockId] -> LabelMap Bool
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((SCC BlockId -> LabelMap Bool -> LabelMap Bool)
-> LabelMap Bool -> SCC BlockId -> LabelMap Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip SCC BlockId -> LabelMap Bool -> LabelMap Bool
setLevel) LabelMap Bool
forall (map :: * -> *) a. IsMap map => map a
mapEmpty [SCC BlockId]
sccs
where
mkNode :: BlockId -> Node BlockId BlockId
mkNode :: BlockId -> Node BlockId BlockId
mkNode bid :: BlockId
bid = BlockId -> BlockId -> [BlockId] -> Node BlockId BlockId
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode BlockId
bid BlockId
bid (HasDebugCallStack => CFG -> BlockId -> [BlockId]
CFG -> BlockId -> [BlockId]
getSuccessors CFG
cfg BlockId
bid)
nodes :: [Node BlockId BlockId]
nodes = (BlockId -> Node BlockId BlockId)
-> [BlockId] -> [Node BlockId BlockId]
forall a b. (a -> b) -> [a] -> [b]
map BlockId -> Node BlockId BlockId
mkNode ([BlockId] -> [Node BlockId BlockId])
-> [BlockId] -> [Node BlockId BlockId]
forall a b. (a -> b) -> a -> b
$ LabelSet -> [ElemOf LabelSet]
forall set. IsSet set => set -> [ElemOf set]
setElems (CFG -> LabelSet
getCfgNodes CFG
cfg)
sccs :: [SCC BlockId]
sccs = [Node BlockId BlockId] -> [SCC BlockId]
forall key payload. Ord key => [Node key payload] -> [SCC payload]
stronglyConnCompFromEdgedVerticesOrd [Node BlockId BlockId]
nodes
setLevel :: SCC BlockId -> LabelMap Bool -> LabelMap Bool
setLevel :: SCC BlockId -> LabelMap Bool -> LabelMap Bool
setLevel (AcyclicSCC bid :: BlockId
bid) m :: LabelMap Bool
m = KeyOf LabelMap -> Bool -> LabelMap Bool -> LabelMap Bool
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert KeyOf LabelMap
BlockId
bid Bool
False LabelMap Bool
m
setLevel (CyclicSCC bids :: [BlockId]
bids) m :: LabelMap Bool
m = (LabelMap Bool -> BlockId -> LabelMap Bool)
-> LabelMap Bool -> [BlockId] -> LabelMap Bool
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\m :: LabelMap Bool
m k :: BlockId
k -> KeyOf LabelMap -> Bool -> LabelMap Bool -> LabelMap Bool
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
mapInsert KeyOf LabelMap
BlockId
k Bool
True LabelMap Bool
m) LabelMap Bool
m [BlockId]
bids