{-# LANGUAGE GADTs #-}
module GHC.Cmm.Sink (
cmmSink
) where
import GHC.Prelude
import GHC.Cmm
import GHC.Cmm.Opt
import GHC.Cmm.Liveness
import GHC.Cmm.Utils
import GHC.Cmm.Dataflow.Block
import GHC.Cmm.Dataflow.Label
import GHC.Cmm.Dataflow.Collections
import GHC.Cmm.Dataflow.Graph
import GHC.Platform.Regs
import GHC.Platform
import GHC.Driver.Session
import GHC.Types.Unique
import GHC.Types.Unique.FM
import qualified Data.IntSet as IntSet
import Data.List (partition)
import qualified Data.Set as Set
import Data.Maybe
type LRegSet = IntSet.IntSet
emptyLRegSet :: LRegSet
emptyLRegSet :: LRegSet
emptyLRegSet = LRegSet
IntSet.empty
nullLRegSet :: LRegSet -> Bool
nullLRegSet :: LRegSet -> Bool
nullLRegSet = LRegSet -> Bool
IntSet.null
insertLRegSet :: LocalReg -> LRegSet -> LRegSet
insertLRegSet :: LocalReg -> LRegSet -> LRegSet
insertLRegSet LocalReg
l = Int -> LRegSet -> LRegSet
IntSet.insert (Unique -> Int
getKey (LocalReg -> Unique
forall a. Uniquable a => a -> Unique
External instance of the constraint type Uniquable LocalReg
getUnique LocalReg
l))
elemLRegSet :: LocalReg -> LRegSet -> Bool
elemLRegSet :: LocalReg -> LRegSet -> Bool
elemLRegSet LocalReg
l = Int -> LRegSet -> Bool
IntSet.member (Unique -> Int
getKey (LocalReg -> Unique
forall a. Uniquable a => a -> Unique
External instance of the constraint type Uniquable LocalReg
getUnique LocalReg
l))
type Assignment = (LocalReg, CmmExpr, AbsMem)
type Assignments = [Assignment]
cmmSink :: DynFlags -> CmmGraph -> CmmGraph
cmmSink :: DynFlags -> CmmGraph -> CmmGraph
cmmSink DynFlags
dflags CmmGraph
graph = BlockId -> [CmmBlock] -> CmmGraph
ofBlockList (CmmGraph -> BlockId
forall (n :: Extensibility -> Extensibility -> *).
GenCmmGraph n -> BlockId
g_entry CmmGraph
graph) ([CmmBlock] -> CmmGraph) -> [CmmBlock] -> CmmGraph
forall a b. (a -> b) -> a -> b
$ LabelMap Assignments -> [CmmBlock] -> [CmmBlock]
sink LabelMap Assignments
forall (map :: * -> *) a. IsMap map => map a
External instance of the constraint type IsMap LabelMap
mapEmpty ([CmmBlock] -> [CmmBlock]) -> [CmmBlock] -> [CmmBlock]
forall a b. (a -> b) -> a -> b
$ [CmmBlock]
blocks
where
liveness :: BlockEntryLiveness LocalReg
liveness = DynFlags -> CmmGraph -> BlockEntryLiveness LocalReg
cmmLocalLiveness DynFlags
dflags CmmGraph
graph
getLive :: BlockId -> Set LocalReg
getLive BlockId
l = Set LocalReg
-> KeyOf LabelMap -> BlockEntryLiveness LocalReg -> Set LocalReg
forall (map :: * -> *) a. IsMap map => a -> KeyOf map -> map a -> a
External instance of the constraint type IsMap LabelMap
mapFindWithDefault Set LocalReg
forall a. Set a
Set.empty KeyOf LabelMap
BlockId
l BlockEntryLiveness LocalReg
liveness
blocks :: [CmmBlock]
blocks = CmmGraph -> [CmmBlock]
revPostorder CmmGraph
graph
join_pts :: LabelMap Int
join_pts = [CmmBlock] -> LabelMap Int
findJoinPoints [CmmBlock]
blocks
sink :: LabelMap Assignments -> [CmmBlock] -> [CmmBlock]
sink :: LabelMap Assignments -> [CmmBlock] -> [CmmBlock]
sink LabelMap Assignments
_ [] = []
sink LabelMap Assignments
sunk (CmmBlock
b:[CmmBlock]
bs) =
CmmNode C O -> Block CmmNode O O -> CmmNode O C -> CmmBlock
forall (n :: Extensibility -> Extensibility -> *).
n C O -> Block n O O -> n O C -> Block n C C
blockJoin CmmNode C O
first Block CmmNode O O
final_middle CmmNode O C
final_last CmmBlock -> [CmmBlock] -> [CmmBlock]
forall a. a -> [a] -> [a]
: LabelMap Assignments -> [CmmBlock] -> [CmmBlock]
sink LabelMap Assignments
sunk' [CmmBlock]
bs
where
platform :: Platform
platform = DynFlags -> Platform
targetPlatform DynFlags
dflags
lbl :: BlockId
lbl = CmmBlock -> BlockId
forall (thing :: Extensibility -> Extensibility -> *)
(x :: Extensibility).
NonLocal thing =>
thing C x -> BlockId
External instance of the constraint type forall (n :: Extensibility -> Extensibility -> *).
NonLocal n =>
NonLocal (Block n)
External instance of the constraint type NonLocal CmmNode
entryLabel CmmBlock
b
(CmmNode C O
first, Block CmmNode O O
middle, CmmNode O C
last) = CmmBlock -> (CmmNode C O, Block CmmNode O O, CmmNode O C)
forall (n :: Extensibility -> Extensibility -> *).
Block n C C -> (n C O, Block n O O, n O C)
blockSplit CmmBlock
b
succs :: [BlockId]
succs = CmmNode O C -> [BlockId]
forall (thing :: Extensibility -> Extensibility -> *)
(e :: Extensibility).
NonLocal thing =>
thing e C -> [BlockId]
External instance of the constraint type NonLocal CmmNode
successors CmmNode O C
last
live :: Set LocalReg
live = [Set LocalReg] -> Set LocalReg
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
External instance of the constraint type Ord LocalReg
External instance of the constraint type Foldable []
Set.unions ((BlockId -> Set LocalReg) -> [BlockId] -> [Set LocalReg]
forall a b. (a -> b) -> [a] -> [b]
map BlockId -> Set LocalReg
getLive [BlockId]
succs)
live_middle :: Set LocalReg
live_middle = DynFlags -> CmmNode O C -> Set LocalReg -> Set LocalReg
forall r n.
(DefinerOfRegs r n, UserOfRegs r n) =>
DynFlags -> n -> CmmLive r -> CmmLive r
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
UserOfRegs LocalReg (CmmNode e x)
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
DefinerOfRegs LocalReg (CmmNode e x)
gen_kill DynFlags
dflags CmmNode O C
last Set LocalReg
live
ann_middles :: [(Set LocalReg, CmmNode O O)]
ann_middles = DynFlags
-> Set LocalReg -> [CmmNode O O] -> [(Set LocalReg, CmmNode O O)]
annotate DynFlags
dflags Set LocalReg
live_middle (Block CmmNode O O -> [CmmNode O O]
forall (n :: Extensibility -> Extensibility -> *).
Block n O O -> [n O O]
blockToList Block CmmNode O O
middle)
(Block CmmNode O O
middle', Assignments
assigs) = DynFlags
-> [(Set LocalReg, CmmNode O O)]
-> Assignments
-> (Block CmmNode O O, Assignments)
walk DynFlags
dflags [(Set LocalReg, CmmNode O O)]
ann_middles (Assignments
-> KeyOf LabelMap -> LabelMap Assignments -> Assignments
forall (map :: * -> *) a. IsMap map => a -> KeyOf map -> map a -> a
External instance of the constraint type IsMap LabelMap
mapFindWithDefault [] KeyOf LabelMap
BlockId
lbl LabelMap Assignments
sunk)
fold_last :: CmmNode O C
fold_last = Platform -> CmmNode O C -> CmmNode O C
forall (e :: Extensibility) (x :: Extensibility).
Platform -> CmmNode e x -> CmmNode e x
constantFoldNode Platform
platform CmmNode O C
last
(CmmNode O C
final_last, Assignments
assigs') = DynFlags
-> Set LocalReg
-> CmmNode O C
-> Assignments
-> (CmmNode O C, Assignments)
forall (x :: Extensibility).
DynFlags
-> Set LocalReg
-> CmmNode O x
-> Assignments
-> (CmmNode O x, Assignments)
tryToInline DynFlags
dflags Set LocalReg
live CmmNode O C
fold_last Assignments
assigs
([BlockId]
joins, [BlockId]
nonjoins) = (BlockId -> Bool) -> [BlockId] -> ([BlockId], [BlockId])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (KeyOf LabelMap -> LabelMap Int -> Bool
forall (map :: * -> *) a. IsMap map => KeyOf map -> map a -> Bool
External instance of the constraint type IsMap LabelMap
`mapMember` LabelMap Int
join_pts) [BlockId]
succs
live_in_joins :: Set LocalReg
live_in_joins = [Set LocalReg] -> Set LocalReg
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
External instance of the constraint type Ord LocalReg
External instance of the constraint type Foldable []
Set.unions ((BlockId -> Set LocalReg) -> [BlockId] -> [Set LocalReg]
forall a b. (a -> b) -> [a] -> [b]
map BlockId -> Set LocalReg
getLive [BlockId]
joins)
init_live_sets :: [Set LocalReg]
init_live_sets = (BlockId -> Set LocalReg) -> [BlockId] -> [Set LocalReg]
forall a b. (a -> b) -> [a] -> [b]
map BlockId -> Set LocalReg
getLive [BlockId]
nonjoins
live_in_multi :: [Set a] -> a -> Bool
live_in_multi [Set a]
live_sets a
r =
case (Set a -> Bool) -> [Set a] -> [Set a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
Evidence bound by a type signature of the constraint type Ord a
Set.member a
r) [Set a]
live_sets of
(Set a
_one:Set a
_two:[Set a]
_) -> Bool
True
[Set a]
_ -> Bool
False
([CmmNode O O]
dropped_last, Assignments
assigs'') = DynFlags
-> (Assignment -> [Set LocalReg] -> (Bool, [Set LocalReg]))
-> [Set LocalReg]
-> Assignments
-> ([CmmNode O O], Assignments)
forall s.
DynFlags
-> (Assignment -> s -> (Bool, s))
-> s
-> Assignments
-> ([CmmNode O O], Assignments)
dropAssignments DynFlags
dflags Assignment -> [Set LocalReg] -> (Bool, [Set LocalReg])
drop_if [Set LocalReg]
init_live_sets Assignments
assigs'
drop_if :: Assignment -> [Set LocalReg] -> (Bool, [Set LocalReg])
drop_if a :: Assignment
a@(LocalReg
r,CmmExpr
rhs,AbsMem
_) [Set LocalReg]
live_sets = (Bool
should_drop, [Set LocalReg]
live_sets')
where
should_drop :: Bool
should_drop = DynFlags -> Assignment -> CmmNode O C -> Bool
forall (x :: Extensibility).
DynFlags -> Assignment -> CmmNode O x -> Bool
conflicts DynFlags
dflags Assignment
a CmmNode O C
final_last
Bool -> Bool -> Bool
|| Bool -> Bool
not (DynFlags -> CmmExpr -> Bool
isTrivial DynFlags
dflags CmmExpr
rhs) Bool -> Bool -> Bool
&& [Set LocalReg] -> LocalReg -> Bool
forall {a}. Ord a => [Set a] -> a -> Bool
External instance of the constraint type Ord LocalReg
live_in_multi [Set LocalReg]
live_sets LocalReg
r
Bool -> Bool -> Bool
|| LocalReg
r LocalReg -> Set LocalReg -> Bool
forall a. Ord a => a -> Set a -> Bool
External instance of the constraint type Ord LocalReg
`Set.member` Set LocalReg
live_in_joins
live_sets' :: [Set LocalReg]
live_sets' | Bool
should_drop = [Set LocalReg]
live_sets
| Bool
otherwise = (Set LocalReg -> Set LocalReg) -> [Set LocalReg] -> [Set LocalReg]
forall a b. (a -> b) -> [a] -> [b]
map Set LocalReg -> Set LocalReg
upd [Set LocalReg]
live_sets
upd :: Set LocalReg -> Set LocalReg
upd Set LocalReg
set | LocalReg
r LocalReg -> Set LocalReg -> Bool
forall a. Ord a => a -> Set a -> Bool
External instance of the constraint type Ord LocalReg
`Set.member` Set LocalReg
set = Set LocalReg
set Set LocalReg -> Set LocalReg -> Set LocalReg
forall a. Ord a => Set a -> Set a -> Set a
External instance of the constraint type Ord LocalReg
`Set.union` Set LocalReg
live_rhs
| Bool
otherwise = Set LocalReg
set
live_rhs :: Set LocalReg
live_rhs = DynFlags
-> (Set LocalReg -> LocalReg -> Set LocalReg)
-> Set LocalReg
-> CmmExpr
-> Set LocalReg
forall r a b.
UserOfRegs r a =>
DynFlags -> (b -> r -> b) -> b -> a -> b
External instance of the constraint type forall r. (Ord r, UserOfRegs r CmmReg) => UserOfRegs r CmmExpr
External instance of the constraint type Ord LocalReg
External instance of the constraint type UserOfRegs LocalReg CmmReg
foldRegsUsed DynFlags
dflags Set LocalReg -> LocalReg -> Set LocalReg
forall r. Ord r => RegSet r -> r -> RegSet r
External instance of the constraint type Ord LocalReg
extendRegSet Set LocalReg
forall a. Set a
emptyRegSet CmmExpr
rhs
final_middle :: Block CmmNode O O
final_middle = (Block CmmNode O O -> CmmNode O O -> Block CmmNode O O)
-> Block CmmNode O O -> [CmmNode O O] -> Block CmmNode O O
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
External instance of the constraint type Foldable []
foldl' Block CmmNode O O -> CmmNode O O -> Block CmmNode O O
forall (n :: Extensibility -> Extensibility -> *)
(e :: Extensibility).
Block n e O -> n O O -> Block n e O
blockSnoc Block CmmNode O O
middle' [CmmNode O O]
dropped_last
sunk' :: LabelMap Assignments
sunk' = LabelMap Assignments
-> LabelMap Assignments -> LabelMap Assignments
forall (map :: * -> *) a. IsMap map => map a -> map a -> map a
External instance of the constraint type IsMap LabelMap
mapUnion LabelMap Assignments
sunk (LabelMap Assignments -> LabelMap Assignments)
-> LabelMap Assignments -> LabelMap Assignments
forall a b. (a -> b) -> a -> b
$
[(KeyOf LabelMap, Assignments)] -> LabelMap Assignments
forall (map :: * -> *) a. IsMap map => [(KeyOf map, a)] -> map a
External instance of the constraint type IsMap LabelMap
mapFromList [ (KeyOf LabelMap
BlockId
l, DynFlags -> Set LocalReg -> Assignments -> Assignments
filterAssignments DynFlags
dflags (BlockId -> Set LocalReg
getLive BlockId
l) Assignments
assigs'')
| BlockId
l <- [BlockId]
succs ]
isTrivial :: DynFlags -> CmmExpr -> Bool
isTrivial :: DynFlags -> CmmExpr -> Bool
isTrivial DynFlags
_ (CmmReg (CmmLocal LocalReg
_)) = Bool
True
isTrivial DynFlags
dflags (CmmReg (CmmGlobal GlobalReg
r)) =
if Arch -> Bool
isARM (Platform -> Arch
platformArch (DynFlags -> Platform
targetPlatform DynFlags
dflags))
then Bool
True
else Maybe RealReg -> Bool
forall a. Maybe a -> Bool
isJust (Platform -> GlobalReg -> Maybe RealReg
globalRegMaybe (DynFlags -> Platform
targetPlatform DynFlags
dflags) GlobalReg
r)
isTrivial DynFlags
_ (CmmLit CmmLit
_) = Bool
True
isTrivial DynFlags
_ CmmExpr
_ = Bool
False
annotate :: DynFlags -> LocalRegSet -> [CmmNode O O] -> [(LocalRegSet, CmmNode O O)]
annotate :: DynFlags
-> Set LocalReg -> [CmmNode O O] -> [(Set LocalReg, CmmNode O O)]
annotate DynFlags
dflags Set LocalReg
live [CmmNode O O]
nodes = (Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> [(Set LocalReg, CmmNode O O)]
forall a b. (a, b) -> b
snd ((Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> [(Set LocalReg, CmmNode O O)])
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> [(Set LocalReg, CmmNode O O)]
forall a b. (a -> b) -> a -> b
$ (CmmNode O O
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)]))
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> [CmmNode O O]
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
External instance of the constraint type Foldable []
foldr CmmNode O O
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
ann (Set LocalReg
live,[]) [CmmNode O O]
nodes
where ann :: CmmNode O O
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
-> (Set LocalReg, [(Set LocalReg, CmmNode O O)])
ann CmmNode O O
n (Set LocalReg
live,[(Set LocalReg, CmmNode O O)]
nodes) = (DynFlags -> CmmNode O O -> Set LocalReg -> Set LocalReg
forall r n.
(DefinerOfRegs r n, UserOfRegs r n) =>
DynFlags -> n -> CmmLive r -> CmmLive r
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
UserOfRegs LocalReg (CmmNode e x)
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
DefinerOfRegs LocalReg (CmmNode e x)
gen_kill DynFlags
dflags CmmNode O O
n Set LocalReg
live, (Set LocalReg
live,CmmNode O O
n) (Set LocalReg, CmmNode O O)
-> [(Set LocalReg, CmmNode O O)] -> [(Set LocalReg, CmmNode O O)]
forall a. a -> [a] -> [a]
: [(Set LocalReg, CmmNode O O)]
nodes)
findJoinPoints :: [CmmBlock] -> LabelMap Int
findJoinPoints :: [CmmBlock] -> LabelMap Int
findJoinPoints [CmmBlock]
blocks = (Int -> Bool) -> LabelMap Int -> LabelMap Int
forall (map :: * -> *) a.
IsMap map =>
(a -> Bool) -> map a -> map a
External instance of the constraint type IsMap LabelMap
mapFilter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
External instance of the constraint type Ord Int
>Int
1) LabelMap Int
succ_counts
where
all_succs :: [BlockId]
all_succs = (CmmBlock -> [BlockId]) -> [CmmBlock] -> [BlockId]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
External instance of the constraint type Foldable []
concatMap CmmBlock -> [BlockId]
forall (thing :: Extensibility -> Extensibility -> *)
(e :: Extensibility).
NonLocal thing =>
thing e C -> [BlockId]
External instance of the constraint type forall (n :: Extensibility -> Extensibility -> *).
NonLocal n =>
NonLocal (Block n)
External instance of the constraint type NonLocal CmmNode
successors [CmmBlock]
blocks
succ_counts :: LabelMap Int
succ_counts :: LabelMap Int
succ_counts = (BlockId -> LabelMap Int -> LabelMap Int)
-> LabelMap Int -> [BlockId] -> LabelMap Int
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
External instance of the constraint type Foldable []
foldr (\BlockId
l -> (Int -> Int -> Int)
-> KeyOf LabelMap -> Int -> LabelMap Int -> LabelMap Int
forall (map :: * -> *) a.
IsMap map =>
(a -> a -> a) -> KeyOf map -> a -> map a -> map a
External instance of the constraint type IsMap LabelMap
mapInsertWith Int -> Int -> Int
forall a. Num a => a -> a -> a
External instance of the constraint type Num Int
(+) KeyOf LabelMap
BlockId
l Int
1) LabelMap Int
forall (map :: * -> *) a. IsMap map => map a
External instance of the constraint type IsMap LabelMap
mapEmpty [BlockId]
all_succs
filterAssignments :: DynFlags -> LocalRegSet -> Assignments -> Assignments
filterAssignments :: DynFlags -> Set LocalReg -> Assignments -> Assignments
filterAssignments DynFlags
dflags Set LocalReg
live Assignments
assigs = Assignments -> Assignments
forall a. [a] -> [a]
reverse (Assignments -> Assignments -> Assignments
go Assignments
assigs [])
where go :: Assignments -> Assignments -> Assignments
go [] Assignments
kept = Assignments
kept
go (a :: Assignment
a@(LocalReg
r,CmmExpr
_,AbsMem
_):Assignments
as) Assignments
kept | Bool
needed = Assignments -> Assignments -> Assignments
go Assignments
as (Assignment
aAssignment -> Assignments -> Assignments
forall a. a -> [a] -> [a]
:Assignments
kept)
| Bool
otherwise = Assignments -> Assignments -> Assignments
go Assignments
as Assignments
kept
where
needed :: Bool
needed = LocalReg
r LocalReg -> Set LocalReg -> Bool
forall a. Ord a => a -> Set a -> Bool
External instance of the constraint type Ord LocalReg
`Set.member` Set LocalReg
live
Bool -> Bool -> Bool
|| (CmmNode O O -> Bool) -> [CmmNode O O] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
External instance of the constraint type Foldable []
any (DynFlags -> Assignment -> CmmNode O O -> Bool
forall (x :: Extensibility).
DynFlags -> Assignment -> CmmNode O x -> Bool
conflicts DynFlags
dflags Assignment
a) ((Assignment -> CmmNode O O) -> Assignments -> [CmmNode O O]
forall a b. (a -> b) -> [a] -> [b]
map Assignment -> CmmNode O O
toNode Assignments
kept)
walk :: DynFlags
-> [(LocalRegSet, CmmNode O O)]
-> Assignments
-> ( Block CmmNode O O
, Assignments
)
walk :: DynFlags
-> [(Set LocalReg, CmmNode O O)]
-> Assignments
-> (Block CmmNode O O, Assignments)
walk DynFlags
dflags [(Set LocalReg, CmmNode O O)]
nodes Assignments
assigs = [(Set LocalReg, CmmNode O O)]
-> Block CmmNode O O
-> Assignments
-> (Block CmmNode O O, Assignments)
go [(Set LocalReg, CmmNode O O)]
nodes Block CmmNode O O
forall (n :: Extensibility -> Extensibility -> *). Block n O O
emptyBlock Assignments
assigs
where
go :: [(Set LocalReg, CmmNode O O)]
-> Block CmmNode O O
-> Assignments
-> (Block CmmNode O O, Assignments)
go [] Block CmmNode O O
block Assignments
as = (Block CmmNode O O
block, Assignments
as)
go ((Set LocalReg
live,CmmNode O O
node):[(Set LocalReg, CmmNode O O)]
ns) Block CmmNode O O
block Assignments
as
| CmmNode O O -> Set LocalReg -> Bool
forall (e :: Extensibility) (x :: Extensibility).
CmmNode e x -> Set LocalReg -> Bool
shouldDiscard CmmNode O O
node Set LocalReg
live = [(Set LocalReg, CmmNode O O)]
-> Block CmmNode O O
-> Assignments
-> (Block CmmNode O O, Assignments)
go [(Set LocalReg, CmmNode O O)]
ns Block CmmNode O O
block Assignments
as
| Just Assignment
a <- Platform -> CmmNode O O -> Maybe Assignment
forall (e :: Extensibility) (x :: Extensibility).
Platform -> CmmNode e x -> Maybe Assignment
shouldSink Platform
platform CmmNode O O
node2 = [(Set LocalReg, CmmNode O O)]
-> Block CmmNode O O
-> Assignments
-> (Block CmmNode O O, Assignments)
go [(Set LocalReg, CmmNode O O)]
ns Block CmmNode O O
block (Assignment
a Assignment -> Assignments -> Assignments
forall a. a -> [a] -> [a]
: Assignments
as1)
| Bool
otherwise = [(Set LocalReg, CmmNode O O)]
-> Block CmmNode O O
-> Assignments
-> (Block CmmNode O O, Assignments)
go [(Set LocalReg, CmmNode O O)]
ns Block CmmNode O O
block' Assignments
as'
where
platform :: Platform
platform = DynFlags -> Platform
targetPlatform DynFlags
dflags
node1 :: CmmNode O O
node1 = Platform -> CmmNode O O -> CmmNode O O
forall (e :: Extensibility) (x :: Extensibility).
Platform -> CmmNode e x -> CmmNode e x
constantFoldNode Platform
platform CmmNode O O
node
(CmmNode O O
node2, Assignments
as1) = DynFlags
-> Set LocalReg
-> CmmNode O O
-> Assignments
-> (CmmNode O O, Assignments)
forall (x :: Extensibility).
DynFlags
-> Set LocalReg
-> CmmNode O x
-> Assignments
-> (CmmNode O x, Assignments)
tryToInline DynFlags
dflags Set LocalReg
live CmmNode O O
node1 Assignments
as
([CmmNode O O]
dropped, Assignments
as') = DynFlags
-> (Assignment -> Bool)
-> Assignments
-> ([CmmNode O O], Assignments)
dropAssignmentsSimple DynFlags
dflags
(\Assignment
a -> DynFlags -> Assignment -> CmmNode O O -> Bool
forall (x :: Extensibility).
DynFlags -> Assignment -> CmmNode O x -> Bool
conflicts DynFlags
dflags Assignment
a CmmNode O O
node2) Assignments
as1
block' :: Block CmmNode O O
block' = (Block CmmNode O O -> CmmNode O O -> Block CmmNode O O)
-> Block CmmNode O O -> [CmmNode O O] -> Block CmmNode O O
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
External instance of the constraint type Foldable []
foldl' Block CmmNode O O -> CmmNode O O -> Block CmmNode O O
forall (n :: Extensibility -> Extensibility -> *)
(e :: Extensibility).
Block n e O -> n O O -> Block n e O
blockSnoc Block CmmNode O O
block [CmmNode O O]
dropped Block CmmNode O O -> CmmNode O O -> Block CmmNode O O
forall (n :: Extensibility -> Extensibility -> *)
(e :: Extensibility).
Block n e O -> n O O -> Block n e O
`blockSnoc` CmmNode O O
node2
shouldSink :: Platform -> CmmNode e x -> Maybe Assignment
shouldSink :: Platform -> CmmNode e x -> Maybe Assignment
shouldSink Platform
platform (CmmAssign (CmmLocal LocalReg
r) CmmExpr
e) | Bool
no_local_regs = Assignment -> Maybe Assignment
forall a. a -> Maybe a
Just (LocalReg
r, CmmExpr
e, Platform -> CmmExpr -> AbsMem
exprMem Platform
platform CmmExpr
e)
where no_local_regs :: Bool
no_local_regs = Bool
True
shouldSink Platform
_ CmmNode e x
_other = Maybe Assignment
forall a. Maybe a
Nothing
shouldDiscard :: CmmNode e x -> LocalRegSet -> Bool
shouldDiscard :: CmmNode e x -> Set LocalReg -> Bool
shouldDiscard CmmNode e x
node Set LocalReg
live
= case CmmNode e x
node of
CmmAssign CmmReg
r (CmmReg CmmReg
r') | CmmReg
r CmmReg -> CmmReg -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq CmmReg
== CmmReg
r' -> Bool
True
CmmAssign (CmmLocal LocalReg
r) CmmExpr
_ -> Bool -> Bool
not (LocalReg
r LocalReg -> Set LocalReg -> Bool
forall a. Ord a => a -> Set a -> Bool
External instance of the constraint type Ord LocalReg
`Set.member` Set LocalReg
live)
CmmNode e x
_otherwise -> Bool
False
toNode :: Assignment -> CmmNode O O
toNode :: Assignment -> CmmNode O O
toNode (LocalReg
r,CmmExpr
rhs,AbsMem
_) = CmmReg -> CmmExpr -> CmmNode O O
CmmAssign (LocalReg -> CmmReg
CmmLocal LocalReg
r) CmmExpr
rhs
dropAssignmentsSimple :: DynFlags -> (Assignment -> Bool) -> Assignments
-> ([CmmNode O O], Assignments)
dropAssignmentsSimple :: DynFlags
-> (Assignment -> Bool)
-> Assignments
-> ([CmmNode O O], Assignments)
dropAssignmentsSimple DynFlags
dflags Assignment -> Bool
f = DynFlags
-> (Assignment -> () -> (Bool, ()))
-> ()
-> Assignments
-> ([CmmNode O O], Assignments)
forall s.
DynFlags
-> (Assignment -> s -> (Bool, s))
-> s
-> Assignments
-> ([CmmNode O O], Assignments)
dropAssignments DynFlags
dflags (\Assignment
a ()
_ -> (Assignment -> Bool
f Assignment
a, ())) ()
dropAssignments :: DynFlags -> (Assignment -> s -> (Bool, s)) -> s -> Assignments
-> ([CmmNode O O], Assignments)
dropAssignments :: DynFlags
-> (Assignment -> s -> (Bool, s))
-> s
-> Assignments
-> ([CmmNode O O], Assignments)
dropAssignments DynFlags
dflags Assignment -> s -> (Bool, s)
should_drop s
state Assignments
assigs
= ([CmmNode O O]
dropped, Assignments -> Assignments
forall a. [a] -> [a]
reverse Assignments
kept)
where
([CmmNode O O]
dropped,Assignments
kept) = s
-> Assignments
-> [CmmNode O O]
-> Assignments
-> ([CmmNode O O], Assignments)
go s
state Assignments
assigs [] []
go :: s
-> Assignments
-> [CmmNode O O]
-> Assignments
-> ([CmmNode O O], Assignments)
go s
_ [] [CmmNode O O]
dropped Assignments
kept = ([CmmNode O O]
dropped, Assignments
kept)
go s
state (Assignment
assig : Assignments
rest) [CmmNode O O]
dropped Assignments
kept
| Bool
conflict = s
-> Assignments
-> [CmmNode O O]
-> Assignments
-> ([CmmNode O O], Assignments)
go s
state' Assignments
rest (Assignment -> CmmNode O O
toNode Assignment
assig CmmNode O O -> [CmmNode O O] -> [CmmNode O O]
forall a. a -> [a] -> [a]
: [CmmNode O O]
dropped) Assignments
kept
| Bool
otherwise = s
-> Assignments
-> [CmmNode O O]
-> Assignments
-> ([CmmNode O O], Assignments)
go s
state' Assignments
rest [CmmNode O O]
dropped (Assignment
assigAssignment -> Assignments -> Assignments
forall a. a -> [a] -> [a]
:Assignments
kept)
where
(Bool
dropit, s
state') = Assignment -> s -> (Bool, s)
should_drop Assignment
assig s
state
conflict :: Bool
conflict = Bool
dropit Bool -> Bool -> Bool
|| (CmmNode O O -> Bool) -> [CmmNode O O] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
External instance of the constraint type Foldable []
any (DynFlags -> Assignment -> CmmNode O O -> Bool
forall (x :: Extensibility).
DynFlags -> Assignment -> CmmNode O x -> Bool
conflicts DynFlags
dflags Assignment
assig) [CmmNode O O]
dropped
tryToInline
:: DynFlags
-> LocalRegSet
-> CmmNode O x
-> Assignments
-> (
CmmNode O x
, Assignments
)
tryToInline :: DynFlags
-> Set LocalReg
-> CmmNode O x
-> Assignments
-> (CmmNode O x, Assignments)
tryToInline DynFlags
dflags Set LocalReg
live CmmNode O x
node Assignments
assigs = UniqFM Int
-> CmmNode O x
-> LRegSet
-> Assignments
-> (CmmNode O x, Assignments)
go UniqFM Int
usages CmmNode O x
node LRegSet
emptyLRegSet Assignments
assigs
where
usages :: UniqFM Int
usages :: UniqFM Int
usages = DynFlags
-> (UniqFM Int -> LocalReg -> UniqFM Int)
-> UniqFM Int
-> CmmNode O x
-> UniqFM Int
forall a b.
UserOfRegs LocalReg a =>
DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
UserOfRegs LocalReg (CmmNode e x)
foldLocalRegsUsed DynFlags
dflags UniqFM Int -> LocalReg -> UniqFM Int
addUsage UniqFM Int
forall elt. UniqFM elt
emptyUFM CmmNode O x
node
go :: UniqFM Int
-> CmmNode O x
-> LRegSet
-> Assignments
-> (CmmNode O x, Assignments)
go UniqFM Int
_usages CmmNode O x
node LRegSet
_skipped [] = (CmmNode O x
node, [])
go UniqFM Int
usages CmmNode O x
node LRegSet
skipped (a :: Assignment
a@(LocalReg
l,CmmExpr
rhs,AbsMem
_) : Assignments
rest)
| Bool
cannot_inline = (CmmNode O x, Assignments)
dont_inline
| Bool
occurs_none = (CmmNode O x, Assignments)
discard
| Bool
occurs_once = (CmmNode O x, Assignments)
inline_and_discard
| DynFlags -> CmmExpr -> Bool
isTrivial DynFlags
dflags CmmExpr
rhs = (CmmNode O x, Assignments)
inline_and_keep
| Bool
otherwise = (CmmNode O x, Assignments)
dont_inline
where
platform :: Platform
platform = DynFlags -> Platform
targetPlatform DynFlags
dflags
inline_and_discard :: (CmmNode O x, Assignments)
inline_and_discard = UniqFM Int
-> CmmNode O x
-> LRegSet
-> Assignments
-> (CmmNode O x, Assignments)
go UniqFM Int
usages' CmmNode O x
inl_node LRegSet
skipped Assignments
rest
where usages' :: UniqFM Int
usages' = DynFlags
-> (UniqFM Int -> LocalReg -> UniqFM Int)
-> UniqFM Int
-> CmmExpr
-> UniqFM Int
forall a b.
UserOfRegs LocalReg a =>
DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
External instance of the constraint type forall r. (Ord r, UserOfRegs r CmmReg) => UserOfRegs r CmmExpr
External instance of the constraint type Ord LocalReg
External instance of the constraint type UserOfRegs LocalReg CmmReg
foldLocalRegsUsed DynFlags
dflags UniqFM Int -> LocalReg -> UniqFM Int
addUsage UniqFM Int
usages CmmExpr
rhs
discard :: (CmmNode O x, Assignments)
discard = UniqFM Int
-> CmmNode O x
-> LRegSet
-> Assignments
-> (CmmNode O x, Assignments)
go UniqFM Int
usages CmmNode O x
node LRegSet
skipped Assignments
rest
dont_inline :: (CmmNode O x, Assignments)
dont_inline = CmmNode O x -> (CmmNode O x, Assignments)
keep CmmNode O x
node
inline_and_keep :: (CmmNode O x, Assignments)
inline_and_keep = CmmNode O x -> (CmmNode O x, Assignments)
keep CmmNode O x
inl_node
keep :: CmmNode O x -> (CmmNode O x, Assignments)
keep CmmNode O x
node' = (CmmNode O x
final_node, Assignment
a Assignment -> Assignments -> Assignments
forall a. a -> [a] -> [a]
: Assignments
rest')
where (CmmNode O x
final_node, Assignments
rest') = UniqFM Int
-> CmmNode O x
-> LRegSet
-> Assignments
-> (CmmNode O x, Assignments)
go UniqFM Int
usages' CmmNode O x
node' (LocalReg -> LRegSet -> LRegSet
insertLRegSet LocalReg
l LRegSet
skipped) Assignments
rest
usages' :: UniqFM Int
usages' = DynFlags
-> (UniqFM Int -> LocalReg -> UniqFM Int)
-> UniqFM Int
-> CmmExpr
-> UniqFM Int
forall a b.
UserOfRegs LocalReg a =>
DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
External instance of the constraint type forall r. (Ord r, UserOfRegs r CmmReg) => UserOfRegs r CmmExpr
External instance of the constraint type Ord LocalReg
External instance of the constraint type UserOfRegs LocalReg CmmReg
foldLocalRegsUsed DynFlags
dflags (\UniqFM Int
m LocalReg
r -> UniqFM Int -> LocalReg -> Int -> UniqFM Int
forall key elt.
Uniquable key =>
UniqFM elt -> key -> elt -> UniqFM elt
External instance of the constraint type Uniquable LocalReg
addToUFM UniqFM Int
m LocalReg
r Int
2)
UniqFM Int
usages CmmExpr
rhs
cannot_inline :: Bool
cannot_inline = LRegSet
skipped LRegSet -> CmmExpr -> Bool
`regsUsedIn` CmmExpr
rhs
Bool -> Bool -> Bool
|| LocalReg
l LocalReg -> LRegSet -> Bool
`elemLRegSet` LRegSet
skipped
Bool -> Bool -> Bool
|| Bool -> Bool
not (DynFlags -> CmmExpr -> CmmNode O x -> Bool
forall (e :: Extensibility) (x :: Extensibility).
DynFlags -> CmmExpr -> CmmNode e x -> Bool
okToInline DynFlags
dflags CmmExpr
rhs CmmNode O x
node)
l_usages :: Maybe Int
l_usages = UniqFM Int -> LocalReg -> Maybe Int
forall key elt. Uniquable key => UniqFM elt -> key -> Maybe elt
External instance of the constraint type Uniquable LocalReg
lookupUFM UniqFM Int
usages LocalReg
l
l_live :: Bool
l_live = LocalReg
l LocalReg -> Set LocalReg -> Bool
forall a. Ord a => a -> Set a -> Bool
External instance of the constraint type Ord LocalReg
`elemRegSet` Set LocalReg
live
occurs_once :: Bool
occurs_once = Bool -> Bool
not Bool
l_live Bool -> Bool -> Bool
&& Maybe Int
l_usages Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type forall a. Eq a => Eq (Maybe a)
External instance of the constraint type Eq Int
== Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
occurs_none :: Bool
occurs_none = Bool -> Bool
not Bool
l_live Bool -> Bool -> Bool
&& Maybe Int
l_usages Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type forall a. Eq a => Eq (Maybe a)
External instance of the constraint type Eq Int
== Maybe Int
forall a. Maybe a
Nothing
inl_node :: CmmNode O x
inl_node = CmmNode O x -> CmmNode O x
forall (x :: Extensibility). CmmNode O x -> CmmNode O x
improveConditional ((CmmExpr -> CmmExpr) -> CmmNode O x -> CmmNode O x
forall (e :: Extensibility) (x :: Extensibility).
(CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x
mapExpDeep CmmExpr -> CmmExpr
inl_exp CmmNode O x
node)
inl_exp :: CmmExpr -> CmmExpr
inl_exp :: CmmExpr -> CmmExpr
inl_exp (CmmReg (CmmLocal LocalReg
l')) | LocalReg
l LocalReg -> LocalReg -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq LocalReg
== LocalReg
l' = CmmExpr
rhs
inl_exp (CmmRegOff (CmmLocal LocalReg
l') Int
off) | LocalReg
l LocalReg -> LocalReg -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq LocalReg
== LocalReg
l'
= Platform -> CmmExpr -> Int -> CmmExpr
cmmOffset Platform
platform CmmExpr
rhs Int
off
inl_exp (CmmMachOp MachOp
op [CmmExpr]
args) = Platform -> MachOp -> [CmmExpr] -> CmmExpr
cmmMachOpFold Platform
platform MachOp
op [CmmExpr]
args
inl_exp CmmExpr
other = CmmExpr
other
improveConditional :: CmmNode O x -> CmmNode O x
improveConditional :: CmmNode O x -> CmmNode O x
improveConditional
(CmmCondBranch (CmmMachOp MachOp
mop [CmmExpr
x, CmmLit (CmmInt Integer
1 Width
_)]) BlockId
t BlockId
f Maybe Bool
l)
| MachOp -> Bool
neLike MachOp
mop, CmmExpr -> Bool
isComparisonExpr CmmExpr
x
= CmmExpr -> BlockId -> BlockId -> Maybe Bool -> CmmNode O C
CmmCondBranch CmmExpr
x BlockId
f BlockId
t ((Bool -> Bool) -> Maybe Bool -> Maybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
External instance of the constraint type Functor Maybe
fmap Bool -> Bool
not Maybe Bool
l)
where
neLike :: MachOp -> Bool
neLike (MO_Ne Width
_) = Bool
True
neLike (MO_U_Lt Width
_) = Bool
True
neLike (MO_S_Lt Width
_) = Bool
True
neLike MachOp
_ = Bool
False
improveConditional CmmNode O x
other = CmmNode O x
other
addUsage :: UniqFM Int -> LocalReg -> UniqFM Int
addUsage :: UniqFM Int -> LocalReg -> UniqFM Int
addUsage UniqFM Int
m LocalReg
r = (Int -> Int -> Int) -> UniqFM Int -> LocalReg -> Int -> UniqFM Int
forall key elt.
Uniquable key =>
(elt -> elt -> elt) -> UniqFM elt -> key -> elt -> UniqFM elt
External instance of the constraint type Uniquable LocalReg
addToUFM_C Int -> Int -> Int
forall a. Num a => a -> a -> a
External instance of the constraint type Num Int
(+) UniqFM Int
m LocalReg
r Int
1
regsUsedIn :: LRegSet -> CmmExpr -> Bool
regsUsedIn :: LRegSet -> CmmExpr -> Bool
regsUsedIn LRegSet
ls CmmExpr
_ | LRegSet -> Bool
nullLRegSet LRegSet
ls = Bool
False
regsUsedIn LRegSet
ls CmmExpr
e = (CmmExpr -> Bool -> Bool) -> CmmExpr -> Bool -> Bool
forall z. (CmmExpr -> z -> z) -> CmmExpr -> z -> z
wrapRecExpf CmmExpr -> Bool -> Bool
f CmmExpr
e Bool
False
where f :: CmmExpr -> Bool -> Bool
f (CmmReg (CmmLocal LocalReg
l)) Bool
_ | LocalReg
l LocalReg -> LRegSet -> Bool
`elemLRegSet` LRegSet
ls = Bool
True
f (CmmRegOff (CmmLocal LocalReg
l) Int
_) Bool
_ | LocalReg
l LocalReg -> LRegSet -> Bool
`elemLRegSet` LRegSet
ls = Bool
True
f CmmExpr
_ Bool
z = Bool
z
okToInline :: DynFlags -> CmmExpr -> CmmNode e x -> Bool
okToInline :: DynFlags -> CmmExpr -> CmmNode e x -> Bool
okToInline DynFlags
dflags CmmExpr
expr node :: CmmNode e x
node@(CmmUnsafeForeignCall{}) =
Bool -> Bool
not (DynFlags -> CmmExpr -> CmmNode e x -> Bool
forall (e :: Extensibility) (x :: Extensibility).
DynFlags -> CmmExpr -> CmmNode e x -> Bool
globalRegistersConflict DynFlags
dflags CmmExpr
expr CmmNode e x
node)
okToInline DynFlags
_ CmmExpr
_ CmmNode e x
_ = Bool
True
conflicts :: DynFlags -> Assignment -> CmmNode O x -> Bool
conflicts :: DynFlags -> Assignment -> CmmNode O x -> Bool
conflicts DynFlags
dflags (LocalReg
r, CmmExpr
rhs, AbsMem
addr) CmmNode O x
node
| DynFlags -> CmmExpr -> CmmNode O x -> Bool
forall (e :: Extensibility) (x :: Extensibility).
DynFlags -> CmmExpr -> CmmNode e x -> Bool
globalRegistersConflict DynFlags
dflags CmmExpr
rhs CmmNode O x
node = Bool
True
| DynFlags -> CmmExpr -> CmmNode O x -> Bool
forall (e :: Extensibility) (x :: Extensibility).
DynFlags -> CmmExpr -> CmmNode e x -> Bool
localRegistersConflict DynFlags
dflags CmmExpr
rhs CmmNode O x
node = Bool
True
| DynFlags
-> (Bool -> LocalReg -> Bool) -> Bool -> CmmNode O x -> Bool
forall r a b.
UserOfRegs r a =>
DynFlags -> (b -> r -> b) -> b -> a -> b
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
UserOfRegs LocalReg (CmmNode e x)
foldRegsUsed DynFlags
dflags (\Bool
b LocalReg
r' -> LocalReg
r LocalReg -> LocalReg -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq LocalReg
== LocalReg
r' Bool -> Bool -> Bool
|| Bool
b) Bool
False CmmNode O x
node = Bool
True
| CmmStore CmmExpr
addr' CmmExpr
e <- CmmNode O x
node
, AbsMem -> AbsMem -> Bool
memConflicts AbsMem
addr (Platform -> CmmExpr -> Width -> AbsMem
loadAddr Platform
platform CmmExpr
addr' (Platform -> CmmExpr -> Width
cmmExprWidth Platform
platform CmmExpr
e)) = Bool
True
| AbsMem
HeapMem <- AbsMem
addr, CmmAssign (CmmGlobal GlobalReg
Hp) CmmExpr
_ <- CmmNode O x
node = Bool
True
| AbsMem
StackMem <- AbsMem
addr, CmmAssign (CmmGlobal GlobalReg
Sp) CmmExpr
_ <- CmmNode O x
node = Bool
True
| SpMem{} <- AbsMem
addr, CmmAssign (CmmGlobal GlobalReg
Sp) CmmExpr
_ <- CmmNode O x
node = Bool
True
| CmmUnsafeForeignCall{} <- CmmNode O x
node, AbsMem -> AbsMem -> Bool
memConflicts AbsMem
addr AbsMem
AnyMem = Bool
True
| CmmCall{} <- CmmNode O x
node, AbsMem -> AbsMem -> Bool
memConflicts AbsMem
addr AbsMem
AnyMem = Bool
True
| Bool
otherwise = Bool
False
where
platform :: Platform
platform = DynFlags -> Platform
targetPlatform DynFlags
dflags
globalRegistersConflict :: DynFlags -> CmmExpr -> CmmNode e x -> Bool
globalRegistersConflict :: DynFlags -> CmmExpr -> CmmNode e x -> Bool
globalRegistersConflict DynFlags
dflags CmmExpr
expr CmmNode e x
node =
DynFlags
-> (Bool -> GlobalReg -> Bool) -> Bool -> CmmNode e x -> Bool
forall r a b.
DefinerOfRegs r a =>
DynFlags -> (b -> r -> b) -> b -> a -> b
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
DefinerOfRegs GlobalReg (CmmNode e x)
foldRegsDefd DynFlags
dflags (\Bool
b GlobalReg
r -> Bool
b Bool -> Bool -> Bool
|| Platform -> CmmReg -> CmmExpr -> Bool
regUsedIn (DynFlags -> Platform
targetPlatform DynFlags
dflags) (GlobalReg -> CmmReg
CmmGlobal GlobalReg
r) CmmExpr
expr)
Bool
False CmmNode e x
node
localRegistersConflict :: DynFlags -> CmmExpr -> CmmNode e x -> Bool
localRegistersConflict :: DynFlags -> CmmExpr -> CmmNode e x -> Bool
localRegistersConflict DynFlags
dflags CmmExpr
expr CmmNode e x
node =
DynFlags
-> (Bool -> LocalReg -> Bool) -> Bool -> CmmNode e x -> Bool
forall r a b.
DefinerOfRegs r a =>
DynFlags -> (b -> r -> b) -> b -> a -> b
External instance of the constraint type forall (e :: Extensibility) (x :: Extensibility).
DefinerOfRegs LocalReg (CmmNode e x)
foldRegsDefd DynFlags
dflags (\Bool
b LocalReg
r -> Bool
b Bool -> Bool -> Bool
|| Platform -> CmmReg -> CmmExpr -> Bool
regUsedIn (DynFlags -> Platform
targetPlatform DynFlags
dflags) (LocalReg -> CmmReg
CmmLocal LocalReg
r) CmmExpr
expr)
Bool
False CmmNode e x
node
data AbsMem
= NoMem
| AnyMem
| HeapMem
| StackMem
| SpMem
{-# UNPACK #-} !Int
{-# UNPACK #-} !Int
bothMems :: AbsMem -> AbsMem -> AbsMem
bothMems :: AbsMem -> AbsMem -> AbsMem
bothMems AbsMem
NoMem AbsMem
x = AbsMem
x
bothMems AbsMem
x AbsMem
NoMem = AbsMem
x
bothMems AbsMem
HeapMem AbsMem
HeapMem = AbsMem
HeapMem
bothMems AbsMem
StackMem AbsMem
StackMem = AbsMem
StackMem
bothMems (SpMem Int
o1 Int
w1) (SpMem Int
o2 Int
w2)
| Int
o1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq Int
== Int
o2 = Int -> Int -> AbsMem
SpMem Int
o1 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
External instance of the constraint type Ord Int
max Int
w1 Int
w2)
| Bool
otherwise = AbsMem
StackMem
bothMems SpMem{} AbsMem
StackMem = AbsMem
StackMem
bothMems AbsMem
StackMem SpMem{} = AbsMem
StackMem
bothMems AbsMem
_ AbsMem
_ = AbsMem
AnyMem
memConflicts :: AbsMem -> AbsMem -> Bool
memConflicts :: AbsMem -> AbsMem -> Bool
memConflicts AbsMem
NoMem AbsMem
_ = Bool
False
memConflicts AbsMem
_ AbsMem
NoMem = Bool
False
memConflicts AbsMem
HeapMem AbsMem
StackMem = Bool
False
memConflicts AbsMem
StackMem AbsMem
HeapMem = Bool
False
memConflicts SpMem{} AbsMem
HeapMem = Bool
False
memConflicts AbsMem
HeapMem SpMem{} = Bool
False
memConflicts (SpMem Int
o1 Int
w1) (SpMem Int
o2 Int
w2)
| Int
o1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
External instance of the constraint type Ord Int
< Int
o2 = Int
o1 Int -> Int -> Int
forall a. Num a => a -> a -> a
External instance of the constraint type Num Int
+ Int
w1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
External instance of the constraint type Ord Int
> Int
o2
| Bool
otherwise = Int
o2 Int -> Int -> Int
forall a. Num a => a -> a -> a
External instance of the constraint type Num Int
+ Int
w2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
External instance of the constraint type Ord Int
> Int
o1
memConflicts AbsMem
_ AbsMem
_ = Bool
True
exprMem :: Platform -> CmmExpr -> AbsMem
exprMem :: Platform -> CmmExpr -> AbsMem
exprMem Platform
platform (CmmLoad CmmExpr
addr CmmType
w) = AbsMem -> AbsMem -> AbsMem
bothMems (Platform -> CmmExpr -> Width -> AbsMem
loadAddr Platform
platform CmmExpr
addr (CmmType -> Width
typeWidth CmmType
w)) (Platform -> CmmExpr -> AbsMem
exprMem Platform
platform CmmExpr
addr)
exprMem Platform
platform (CmmMachOp MachOp
_ [CmmExpr]
es) = (AbsMem -> AbsMem -> AbsMem) -> AbsMem -> [AbsMem] -> AbsMem
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
External instance of the constraint type Foldable []
foldr AbsMem -> AbsMem -> AbsMem
bothMems AbsMem
NoMem ((CmmExpr -> AbsMem) -> [CmmExpr] -> [AbsMem]
forall a b. (a -> b) -> [a] -> [b]
map (Platform -> CmmExpr -> AbsMem
exprMem Platform
platform) [CmmExpr]
es)
exprMem Platform
_ CmmExpr
_ = AbsMem
NoMem
loadAddr :: Platform -> CmmExpr -> Width -> AbsMem
loadAddr :: Platform -> CmmExpr -> Width -> AbsMem
loadAddr Platform
platform CmmExpr
e Width
w =
case CmmExpr
e of
CmmReg CmmReg
r -> Platform -> CmmReg -> Int -> Width -> AbsMem
regAddr Platform
platform CmmReg
r Int
0 Width
w
CmmRegOff CmmReg
r Int
i -> Platform -> CmmReg -> Int -> Width -> AbsMem
regAddr Platform
platform CmmReg
r Int
i Width
w
CmmExpr
_other | Platform -> CmmReg -> CmmExpr -> Bool
regUsedIn Platform
platform CmmReg
spReg CmmExpr
e -> AbsMem
StackMem
| Bool
otherwise -> AbsMem
AnyMem
regAddr :: Platform -> CmmReg -> Int -> Width -> AbsMem
regAddr :: Platform -> CmmReg -> Int -> Width -> AbsMem
regAddr Platform
_ (CmmGlobal GlobalReg
Sp) Int
i Width
w = Int -> Int -> AbsMem
SpMem Int
i (Width -> Int
widthInBytes Width
w)
regAddr Platform
_ (CmmGlobal GlobalReg
Hp) Int
_ Width
_ = AbsMem
HeapMem
regAddr Platform
_ (CmmGlobal GlobalReg
CurrentTSO) Int
_ Width
_ = AbsMem
HeapMem
regAddr Platform
platform CmmReg
r Int
_ Width
_ | CmmType -> Bool
isGcPtrType (Platform -> CmmReg -> CmmType
cmmRegType Platform
platform CmmReg
r) = AbsMem
HeapMem
regAddr Platform
_ CmmReg
_ Int
_ Width
_ = AbsMem
AnyMem