{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Macaw.Analysis.FunctionArgs
( functionDemands
, ArchDemandInfo(..)
, ArchTermStmtRegEffects(..)
, ComputeArchTermStmtEffects
, ResolveCallArgsFn
, AddrDemandMap
, DemandSet(..)
, FunctionSummaryFailureMap
, FunctionArgAnalysisFailure(..)
, RegSegmentOff
, RegisterSet
) where
import Control.Lens
import Control.Monad (when)
import Control.Monad.Except (Except, MonadError(..), runExcept)
import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks)
import Control.Monad.State.Strict (State, StateT, evalStateT, gets, modify', runState)
import Data.Foldable
import qualified Data.Kind as Kind
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe
import Data.Parameterized.Classes
import Data.Parameterized.Some
import Data.Parameterized.TraversableF
import Data.Parameterized.TraversableFC
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Macaw.CFG
import Data.Macaw.CFG.DemandSet
( DemandContext
, demandConstraints
, hasSideEffects
)
import Data.Macaw.Discovery.State
import Data.Macaw.Types
type PredBlockMap arch = Map (ArchSegmentOff arch) [ArchSegmentOff arch]
predBlockMap :: DiscoveryFunInfo arch ids -> PredBlockMap arch
predBlockMap :: forall arch ids. DiscoveryFunInfo arch ids -> PredBlockMap arch
predBlockMap DiscoveryFunInfo arch ids
finfo =
([MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))])
-> [(MemSegmentOff (RegAddrWidth (ArchReg arch)),
[MemSegmentOff (RegAddrWidth (ArchReg arch))])]
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
[MemSegmentOff (RegAddrWidth (ArchReg arch))]
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith [MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
forall a. [a] -> [a] -> [a]
(++)
[ (MemSegmentOff (RegAddrWidth (ArchReg arch))
dest, [ParsedBlock arch ids -> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall arch ids. ParsedBlock arch ids -> ArchSegmentOff arch
pblockAddr ParsedBlock arch ids
b])
| ParsedBlock arch ids
b <- Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(ParsedBlock arch ids)
-> [ParsedBlock arch ids]
forall k a. Map k a -> [a]
Map.elems (DiscoveryFunInfo arch ids
finfoDiscoveryFunInfo arch ids
-> Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(ParsedBlock arch ids))
(DiscoveryFunInfo arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(ParsedBlock arch ids))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(ParsedBlock arch ids)
forall s a. s -> Getting a s a -> a
^.Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(ParsedBlock arch ids))
(DiscoveryFunInfo arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(ParsedBlock arch ids))
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (ParsedBlock arch ids)
-> f (Map (ArchSegmentOff arch) (ParsedBlock arch ids)))
-> DiscoveryFunInfo arch ids -> f (DiscoveryFunInfo arch ids)
parsedBlocks)
, MemSegmentOff (RegAddrWidth (ArchReg arch))
dest <- ParsedTermStmt arch ids
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
forall arch ids. ParsedTermStmt arch ids -> [ArchSegmentOff arch]
parsedTermSucc (ParsedBlock arch ids -> ParsedTermStmt arch ids
forall arch ids. ParsedBlock arch ids -> ParsedTermStmt arch ids
pblockTermStmt ParsedBlock arch ids
b)
]
type RegisterSet (r :: Type -> Kind.Type) = Set (Some r)
type RegSegmentOff r = MemSegmentOff (RegAddrWidth r)
data DemandSet (r :: Type -> Kind.Type) =
DemandSet { forall (r :: Type -> Type). DemandSet r -> RegisterSet r
registerDemands :: !(RegisterSet r)
, forall (r :: Type -> Type).
DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands :: !(Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r))
}
isEmptyDemandSet :: DemandSet r -> Bool
isEmptyDemandSet :: forall (r :: Type -> Type). DemandSet r -> Bool
isEmptyDemandSet DemandSet r
ds =
Set (Some r) -> Bool
forall a. Set a -> Bool
Set.null (DemandSet r -> Set (Some r)
forall (r :: Type -> Type). DemandSet r -> RegisterSet r
registerDemands DemandSet r
ds) Bool -> Bool -> Bool
&& Map (MemSegmentOff (RegAddrWidth r)) (Set (Some r)) -> Bool
forall k a. Map k a -> Bool
Map.null (DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (Set (Some r))
forall (r :: Type -> Type).
DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands DemandSet r
ds)
registerDemandSet :: RegisterSet r -> DemandSet r
registerDemandSet :: forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet RegisterSet r
s = DemandSet { registerDemands :: RegisterSet r
registerDemands = RegisterSet r
s
, functionResultDemands :: Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands = Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall k a. Map k a
Map.empty
}
demandFunctionReturn :: MemSegmentOff (RegAddrWidth r) -> Some r -> DemandSet r
demandFunctionReturn :: forall (r :: Type -> Type).
MemSegmentOff (RegAddrWidth r) -> Some r -> DemandSet r
demandFunctionReturn MemSegmentOff (RegAddrWidth r)
faddr Some r
sr =
DemandSet { registerDemands :: RegisterSet r
registerDemands = RegisterSet r
forall a. Set a
Set.empty
, functionResultDemands :: Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands = MemSegmentOff (RegAddrWidth r)
-> RegisterSet r
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall k a. k -> a -> Map k a
Map.singleton MemSegmentOff (RegAddrWidth r)
faddr (Some r -> RegisterSet r
forall a. a -> Set a
Set.singleton Some r
sr)
}
deriving instance (ShowF r, MemWidth (RegAddrWidth r)) => Show (DemandSet r)
deriving instance TestEquality r => Eq (DemandSet r)
deriving instance OrdF r => Ord (DemandSet r)
instance OrdF r => Semigroup (DemandSet r) where
DemandSet r
ds1 <> :: DemandSet r -> DemandSet r -> DemandSet r
<> DemandSet r
ds2 =
DemandSet { registerDemands :: RegisterSet r
registerDemands = DemandSet r -> RegisterSet r
forall (r :: Type -> Type). DemandSet r -> RegisterSet r
registerDemands DemandSet r
ds1 RegisterSet r -> RegisterSet r -> RegisterSet r
forall a. Semigroup a => a -> a -> a
<> DemandSet r -> RegisterSet r
forall (r :: Type -> Type). DemandSet r -> RegisterSet r
registerDemands DemandSet r
ds2
, functionResultDemands :: Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands =
(RegisterSet r -> RegisterSet r -> RegisterSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith RegisterSet r -> RegisterSet r -> RegisterSet r
forall a. Ord a => Set a -> Set a -> Set a
Set.union (DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall (r :: Type -> Type).
DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands DemandSet r
ds1)
(DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall (r :: Type -> Type).
DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands DemandSet r
ds2)
}
instance OrdF r => Monoid (DemandSet r) where
mempty :: DemandSet r
mempty = DemandSet { registerDemands :: RegisterSet r
registerDemands = RegisterSet r
forall a. Set a
Set.empty
, functionResultDemands :: Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands = Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall k a. Map k a
Map.empty
}
demandSetDifference :: OrdF r => DemandSet r -> DemandSet r -> DemandSet r
demandSetDifference :: forall (r :: Type -> Type).
OrdF r =>
DemandSet r -> DemandSet r -> DemandSet r
demandSetDifference DemandSet r
ds1 DemandSet r
ds2 =
DemandSet { registerDemands :: RegisterSet r
registerDemands = DemandSet r -> RegisterSet r
forall (r :: Type -> Type). DemandSet r -> RegisterSet r
registerDemands DemandSet r
ds1 RegisterSet r -> RegisterSet r -> RegisterSet r
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` DemandSet r -> RegisterSet r
forall (r :: Type -> Type). DemandSet r -> RegisterSet r
registerDemands DemandSet r
ds2
, functionResultDemands :: Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands =
(RegisterSet r -> RegisterSet r -> Maybe (RegisterSet r))
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall k a b.
Ord k =>
(a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a
Map.differenceWith RegisterSet r -> RegisterSet r -> Maybe (RegisterSet r)
forall {a}. Ord a => Set a -> Set a -> Maybe (Set a)
setDiff
(DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall (r :: Type -> Type).
DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands DemandSet r
ds1)
(DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
forall (r :: Type -> Type).
DemandSet r -> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
functionResultDemands DemandSet r
ds2)
}
where
setDiff :: Set a -> Set a -> Maybe (Set a)
setDiff Set a
s1 Set a
s2 =
let s' :: Set a
s' = Set a
s1 Set a -> Set a -> Set a
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` Set a
s2
in if Set a -> Bool
forall a. Set a -> Bool
Set.null Set a
s' then Maybe (Set a)
forall a. Maybe a
Nothing else Set a -> Maybe (Set a)
forall a. a -> Maybe a
Just Set a
s'
data DemandType r
= DemandAlways
| forall tp. DemandFunctionArg (RegSegmentOff r) (r tp)
| forall tp. DemandFunctionResult (r tp)
instance (MemWidth (RegAddrWidth r), ShowF r) => Show (DemandType r) where
showsPrec :: Int -> DemandType r -> ShowS
showsPrec Int
_ DemandType r
DemandAlways = String -> ShowS
showString String
"DemandAlways"
showsPrec Int
p (DemandFunctionArg MemSegmentOff (RegAddrWidth r)
a r tp
r) = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"DemandFunctionArg " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MemSegmentOff (RegAddrWidth r) -> ShowS
forall a. Show a => a -> ShowS
shows MemSegmentOff (RegAddrWidth r)
a ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r tp -> ShowS
forall {k} (f :: k -> Type) (tp :: k). ShowF f => f tp -> ShowS
showsF r tp
r
showsPrec Int
p (DemandFunctionResult r tp
r) = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"DemandFunctionResult " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r tp -> ShowS
forall {k} (f :: k -> Type) (tp :: k). ShowF f => f tp -> ShowS
showsF r tp
r
instance TestEquality r => Eq (DemandType r) where
DemandType r
DemandAlways == :: DemandType r -> DemandType r -> Bool
== DemandType r
DemandAlways = Bool
True
(DemandFunctionArg RegSegmentOff r
faddr1 r tp
r1) == (DemandFunctionArg RegSegmentOff r
faddr2 r tp
r2) =
RegSegmentOff r
faddr1 RegSegmentOff r -> RegSegmentOff r -> Bool
forall a. Eq a => a -> a -> Bool
== RegSegmentOff r
faddr2 Bool -> Bool -> Bool
&& Maybe (tp :~: tp) -> Bool
forall a. Maybe a -> Bool
isJust (r tp -> r tp -> Maybe (tp :~: tp)
forall {k} (f :: k -> Type) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
forall (a :: Type) (b :: Type). r a -> r b -> Maybe (a :~: b)
testEquality r tp
r1 r tp
r2)
(DemandFunctionResult r tp
r1) == (DemandFunctionResult r tp
r2) =
Maybe (tp :~: tp) -> Bool
forall a. Maybe a -> Bool
isJust (r tp -> r tp -> Maybe (tp :~: tp)
forall {k} (f :: k -> Type) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
forall (a :: Type) (b :: Type). r a -> r b -> Maybe (a :~: b)
testEquality r tp
r1 r tp
r2)
DemandType r
_ == DemandType r
_ = Bool
False
instance OrdF r => Ord (DemandType r) where
DemandType r
DemandAlways compare :: DemandType r -> DemandType r -> Ordering
`compare` DemandType r
DemandAlways = Ordering
EQ
DemandType r
DemandAlways `compare` DemandType r
_ = Ordering
LT
DemandType r
_ `compare` DemandType r
DemandAlways = Ordering
GT
(DemandFunctionArg RegSegmentOff r
faddr1 r tp
r1) `compare` (DemandFunctionArg RegSegmentOff r
faddr2 r tp
r2)
| RegSegmentOff r
faddr1 RegSegmentOff r -> RegSegmentOff r -> Bool
forall a. Eq a => a -> a -> Bool
== RegSegmentOff r
faddr2 = OrderingF tp tp -> Ordering
forall {k} (x :: k) (y :: k). OrderingF x y -> Ordering
toOrdering (r tp -> r tp -> OrderingF tp tp
forall k (ktp :: k -> Type) (x :: k) (y :: k).
OrdF ktp =>
ktp x -> ktp y -> OrderingF x y
forall (x :: Type) (y :: Type). r x -> r y -> OrderingF x y
compareF r tp
r1 r tp
r2)
| Bool
otherwise = RegSegmentOff r
faddr1 RegSegmentOff r -> RegSegmentOff r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` RegSegmentOff r
faddr2
(DemandFunctionArg {}) `compare` DemandType r
_ = Ordering
LT
DemandType r
_ `compare` (DemandFunctionArg {}) = Ordering
GT
(DemandFunctionResult r tp
r1) `compare` (DemandFunctionResult r tp
r2) =
OrderingF tp tp -> Ordering
forall {k} (x :: k) (y :: k). OrderingF x y -> Ordering
toOrdering (r tp -> r tp -> OrderingF tp tp
forall k (ktp :: k -> Type) (x :: k) (y :: k).
OrdF ktp =>
ktp x -> ktp y -> OrderingF x y
forall (x :: Type) (y :: Type). r x -> r y -> OrderingF x y
compareF r tp
r1 r tp
r2)
newtype BlockDemands r = BD (Map (DemandType r) (DemandSet r))
demandAlways :: DemandSet r -> BlockDemands r
demandAlways :: forall (r :: Type -> Type). DemandSet r -> BlockDemands r
demandAlways DemandSet r
s = Map (DemandType r) (DemandSet r) -> BlockDemands r
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD (DemandType r -> DemandSet r -> Map (DemandType r) (DemandSet r)
forall k a. k -> a -> Map k a
Map.singleton DemandType r
forall (r :: Type -> Type). DemandType r
DemandAlways DemandSet r
s)
addDemandFunctionArg :: OrdF r
=> RegSegmentOff r
-> r tp
-> DemandSet r
-> BlockDemands r
-> BlockDemands r
addDemandFunctionArg :: forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
RegSegmentOff r
-> r tp -> DemandSet r -> BlockDemands r -> BlockDemands r
addDemandFunctionArg RegSegmentOff r
a r tp
r DemandSet r
s (BD Map (DemandType r) (DemandSet r)
m) = Map (DemandType r) (DemandSet r) -> BlockDemands r
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD ((DemandSet r -> DemandSet r -> DemandSet r)
-> DemandType r
-> DemandSet r
-> Map (DemandType r) (DemandSet r)
-> Map (DemandType r) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend (RegSegmentOff r -> r tp -> DemandType r
forall (r :: Type -> Type) (tp :: Type).
RegSegmentOff r -> r tp -> DemandType r
DemandFunctionArg RegSegmentOff r
a r tp
r) DemandSet r
s Map (DemandType r) (DemandSet r)
m)
addDemandFunctionResult :: OrdF r => r tp -> DemandSet r -> BlockDemands r -> BlockDemands r
addDemandFunctionResult :: forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
r tp -> DemandSet r -> BlockDemands r -> BlockDemands r
addDemandFunctionResult r tp
r DemandSet r
s (BD Map (DemandType r) (DemandSet r)
m) = Map (DemandType r) (DemandSet r) -> BlockDemands r
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD ((DemandSet r -> DemandSet r -> DemandSet r)
-> DemandType r
-> DemandSet r
-> Map (DemandType r) (DemandSet r)
-> Map (DemandType r) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend (r tp -> DemandType r
forall (r :: Type -> Type) (tp :: Type). r tp -> DemandType r
DemandFunctionResult r tp
r) DemandSet r
s Map (DemandType r) (DemandSet r)
m)
unionBlockDemands :: OrdF r => BlockDemands r -> BlockDemands r -> BlockDemands r
unionBlockDemands :: forall (r :: Type -> Type).
OrdF r =>
BlockDemands r -> BlockDemands r -> BlockDemands r
unionBlockDemands (BD Map (DemandType r) (DemandSet r)
x) (BD Map (DemandType r) (DemandSet r)
y) = Map (DemandType r) (DemandSet r) -> BlockDemands r
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD ((DemandSet r -> DemandSet r -> DemandSet r)
-> Map (DemandType r) (DemandSet r)
-> Map (DemandType r) (DemandSet r)
-> Map (DemandType r) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend Map (DemandType r) (DemandSet r)
x Map (DemandType r) (DemandSet r)
y)
instance OrdF r => Semigroup (BlockDemands r) where
<> :: BlockDemands r -> BlockDemands r -> BlockDemands r
(<>) = BlockDemands r -> BlockDemands r -> BlockDemands r
forall (r :: Type -> Type).
OrdF r =>
BlockDemands r -> BlockDemands r -> BlockDemands r
unionBlockDemands
instance OrdF r => Monoid (BlockDemands r) where
mempty :: BlockDemands r
mempty = Map (DemandType r) (DemandSet r) -> BlockDemands r
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD Map (DemandType r) (DemandSet r)
forall k a. Map k a
Map.empty
type AssignmentCache r ids = Map (Some (AssignId ids)) (RegisterSet r)
newtype FinalRegisterDemands r = FRD (Map (Some r) (DemandSet r))
insertRegDemand :: OrdF r
=> r tp
-> DemandSet r
-> FinalRegisterDemands r
-> FinalRegisterDemands r
insertRegDemand :: forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
r tp
-> DemandSet r -> FinalRegisterDemands r -> FinalRegisterDemands r
insertRegDemand r tp
r DemandSet r
s (FRD Map (Some r) (DemandSet r)
m)
| DemandSet r -> Bool
forall (r :: Type -> Type). DemandSet r -> Bool
isEmptyDemandSet DemandSet r
s = Map (Some r) (DemandSet r) -> FinalRegisterDemands r
forall (r :: Type -> Type).
Map (Some r) (DemandSet r) -> FinalRegisterDemands r
FRD Map (Some r) (DemandSet r)
m
| Bool
otherwise = Map (Some r) (DemandSet r) -> FinalRegisterDemands r
forall (r :: Type -> Type).
Map (Some r) (DemandSet r) -> FinalRegisterDemands r
FRD ((DemandSet r -> DemandSet r -> DemandSet r)
-> Some r
-> DemandSet r
-> Map (Some r) (DemandSet r)
-> Map (Some r) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend (r tp -> Some r
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some r tp
r) DemandSet r
s Map (Some r) (DemandSet r)
m)
postRegisterDemands :: OrdF r => FinalRegisterDemands r -> r tp -> DemandSet r
postRegisterDemands :: forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
FinalRegisterDemands r -> r tp -> DemandSet r
postRegisterDemands (FRD Map (Some r) (DemandSet r)
m) r tp
r = Map (Some r) (DemandSet r)
mMap (Some r) (DemandSet r)
-> Getting (DemandSet r) (Map (Some r) (DemandSet r)) (DemandSet r)
-> DemandSet r
forall s a. s -> Getting a s a -> a
^.Index (Map (Some r) (DemandSet r))
-> Traversal'
(Map (Some r) (DemandSet r)) (IxValue (Map (Some r) (DemandSet r)))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix (r tp -> Some r
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some r tp
r)
instance OrdF r => Semigroup (FinalRegisterDemands r) where
FRD Map (Some r) (DemandSet r)
x <> :: FinalRegisterDemands r
-> FinalRegisterDemands r -> FinalRegisterDemands r
<> FRD Map (Some r) (DemandSet r)
y = Map (Some r) (DemandSet r) -> FinalRegisterDemands r
forall (r :: Type -> Type).
Map (Some r) (DemandSet r) -> FinalRegisterDemands r
FRD ((DemandSet r -> DemandSet r -> DemandSet r)
-> Map (Some r) (DemandSet r)
-> Map (Some r) (DemandSet r)
-> Map (Some r) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend Map (Some r) (DemandSet r)
x Map (Some r) (DemandSet r)
y)
instance OrdF r => Monoid (FinalRegisterDemands r) where
mempty :: FinalRegisterDemands r
mempty = Map (Some r) (DemandSet r) -> FinalRegisterDemands r
forall (r :: Type -> Type).
Map (Some r) (DemandSet r) -> FinalRegisterDemands r
FRD Map (Some r) (DemandSet r)
forall k a. Map k a
Map.empty
data ArchTermStmtRegEffects arch
= ArchTermStmtRegEffects { forall arch. ArchTermStmtRegEffects arch -> [Some (ArchReg arch)]
termRegDemands :: ![Some (ArchReg arch)]
, forall arch. ArchTermStmtRegEffects arch -> [Some (ArchReg arch)]
termRegTransfers :: ![Some (ArchReg arch)]
}
type ComputeArchTermStmtEffects arch ids
= ArchTermStmt arch (Value arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> ArchTermStmtRegEffects arch
data ArchDemandInfo arch = ArchDemandInfo
{
forall arch. ArchDemandInfo arch -> [Some (ArchReg arch)]
functionArgRegs :: ![Some (ArchReg arch)]
, forall arch. ArchDemandInfo arch -> [Some (ArchReg arch)]
functionRetRegs :: ![Some (ArchReg arch)]
, forall arch. ArchDemandInfo arch -> Set (Some (ArchReg arch))
calleeSavedRegs :: !(Set (Some (ArchReg arch)))
, forall arch.
ArchDemandInfo arch
-> forall ids. ComputeArchTermStmtEffects arch ids
computeArchTermStmtEffects :: !(forall ids . ComputeArchTermStmtEffects arch ids)
, forall arch. ArchDemandInfo arch -> DemandContext arch
demandInfoCtx :: !(DemandContext arch)
}
type ResolveCallArgsFn arch
= forall ids
. ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> Either String [Some (Value arch ids)]
data FunArgContext arch = FAC
{ forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo :: !(ArchDemandInfo arch)
, forall arch. FunArgContext arch -> Memory (ArchAddrWidth arch)
ctxMemory :: !(Memory (ArchAddrWidth arch))
, forall arch. FunArgContext arch -> Set (ArchSegmentOff arch)
computedAddrSet :: !(Set (ArchSegmentOff arch))
, forall arch. FunArgContext arch -> ResolveCallArgsFn arch
resolveCallArgs :: !(ResolveCallArgsFn arch)
}
data FunctionArgsState arch ids = FAS
{
forall arch ids.
FunctionArgsState arch ids
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
_blockDemandMap :: !(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
, forall arch ids.
FunctionArgsState arch ids -> AssignmentCache (ArchReg arch) ids
_assignmentCache :: !(AssignmentCache (ArchReg arch) ids)
}
blockDemandMap :: Simple Lens (FunctionArgsState arch ids)
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
blockDemandMap :: forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap = (FunctionArgsState arch ids
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> (FunctionArgsState arch ids
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> FunctionArgsState arch ids)
-> Lens
(FunctionArgsState arch ids)
(FunctionArgsState arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens FunctionArgsState arch ids
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
forall arch ids.
FunctionArgsState arch ids
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
_blockDemandMap (\FunctionArgsState arch ids
s Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
v -> FunctionArgsState arch ids
s { _blockDemandMap = v })
assignmentCache :: Simple Lens (FunctionArgsState arch ids) (AssignmentCache (ArchReg arch) ids)
assignmentCache :: forall arch ids (f :: Type -> Type).
Functor f =>
(AssignmentCache (ArchReg arch) ids
-> f (AssignmentCache (ArchReg arch) ids))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
assignmentCache = (FunctionArgsState arch ids -> AssignmentCache (ArchReg arch) ids)
-> (FunctionArgsState arch ids
-> AssignmentCache (ArchReg arch) ids
-> FunctionArgsState arch ids)
-> Lens
(FunctionArgsState arch ids)
(FunctionArgsState arch ids)
(AssignmentCache (ArchReg arch) ids)
(AssignmentCache (ArchReg arch) ids)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens FunctionArgsState arch ids -> AssignmentCache (ArchReg arch) ids
forall arch ids.
FunctionArgsState arch ids -> AssignmentCache (ArchReg arch) ids
_assignmentCache (\FunctionArgsState arch ids
s AssignmentCache (ArchReg arch) ids
v -> FunctionArgsState arch ids
s { _assignmentCache = v })
initFunctionArgsState :: FunctionArgsState arch ids
initFunctionArgsState :: forall arch ids. FunctionArgsState arch ids
initFunctionArgsState =
FAS { _blockDemandMap :: Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
_blockDemandMap = Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
forall k a. Map k a
Map.empty
, _assignmentCache :: AssignmentCache (ArchReg arch) ids
_assignmentCache = AssignmentCache (ArchReg arch) ids
forall k a. Map k a
Map.empty
}
data FunctionArgAnalysisFailure w
= CallAnalysisError !(MemSegmentOff w) !String
| PLTStubNotSupported
deriving (Int -> FunctionArgAnalysisFailure w -> ShowS
[FunctionArgAnalysisFailure w] -> ShowS
FunctionArgAnalysisFailure w -> String
(Int -> FunctionArgAnalysisFailure w -> ShowS)
-> (FunctionArgAnalysisFailure w -> String)
-> ([FunctionArgAnalysisFailure w] -> ShowS)
-> Show (FunctionArgAnalysisFailure w)
forall (w :: Nat).
MemWidth w =>
Int -> FunctionArgAnalysisFailure w -> ShowS
forall (w :: Nat).
MemWidth w =>
[FunctionArgAnalysisFailure w] -> ShowS
forall (w :: Nat).
MemWidth w =>
FunctionArgAnalysisFailure w -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (w :: Nat).
MemWidth w =>
Int -> FunctionArgAnalysisFailure w -> ShowS
showsPrec :: Int -> FunctionArgAnalysisFailure w -> ShowS
$cshow :: forall (w :: Nat).
MemWidth w =>
FunctionArgAnalysisFailure w -> String
show :: FunctionArgAnalysisFailure w -> String
$cshowList :: forall (w :: Nat).
MemWidth w =>
[FunctionArgAnalysisFailure w] -> ShowS
showList :: [FunctionArgAnalysisFailure w] -> ShowS
Show)
type FunctionArgsM arch ids =
StateT (FunctionArgsState arch ids)
(ReaderT (FunArgContext arch) (Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
evalFunctionArgsM :: FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> ArchSegmentOff arch
-> FunctionArgsM arch ids (FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
evalFunctionArgsM :: forall arch ids.
FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> ArchSegmentOff arch
-> FunctionArgsM arch ids (FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
evalFunctionArgsM FunArgContext arch
ctx FunctionSummaries (ArchReg arch)
s MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr FunctionArgsM arch ids (FunctionSummaries (ArchReg arch))
m =
case Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))
(FunctionSummaries (ArchReg arch))
-> Either
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))
(FunctionSummaries (ArchReg arch))
forall e a. Except e a -> Either e a
runExcept (ReaderT
(FunArgContext arch)
(ExceptT
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))
Identity)
(FunctionSummaries (ArchReg arch))
-> FunArgContext arch
-> Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))
(FunctionSummaries (ArchReg arch))
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (FunctionArgsM arch ids (FunctionSummaries (ArchReg arch))
-> FunctionArgsState arch ids
-> ReaderT
(FunArgContext arch)
(ExceptT
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))
Identity)
(FunctionSummaries (ArchReg arch))
forall (m :: Type -> Type) s a. Monad m => StateT s m a -> s -> m a
evalStateT FunctionArgsM arch ids (FunctionSummaries (ArchReg arch))
m FunctionArgsState arch ids
forall arch ids. FunctionArgsState arch ids
initFunctionArgsState) FunArgContext arch
ctx) of
Left FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
e -> FunctionSummaries (ArchReg arch)
s { inferenceFails = Map.insert faddr e (inferenceFails s) }
Right FunctionSummaries (ArchReg arch)
r' -> FunctionSummaries (ArchReg arch)
r'
withAssignmentCache :: State (AssignmentCache (ArchReg arch) ids) a -> FunctionArgsM arch ids a
withAssignmentCache :: forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache State (AssignmentCache (ArchReg arch) ids) a
m = do
AssignmentCache (ArchReg arch) ids
c <- Getting
(AssignmentCache (ArchReg arch) ids)
(FunctionArgsState arch ids)
(AssignmentCache (ArchReg arch) ids)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(AssignmentCache (ArchReg arch) ids)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use Getting
(AssignmentCache (ArchReg arch) ids)
(FunctionArgsState arch ids)
(AssignmentCache (ArchReg arch) ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(AssignmentCache (ArchReg arch) ids
-> f (AssignmentCache (ArchReg arch) ids))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
assignmentCache
let (a
r, AssignmentCache (ArchReg arch) ids
c') = State (AssignmentCache (ArchReg arch) ids) a
-> AssignmentCache (ArchReg arch) ids
-> (a, AssignmentCache (ArchReg arch) ids)
forall s a. State s a -> s -> (a, s)
runState State (AssignmentCache (ArchReg arch) ids) a
m AssignmentCache (ArchReg arch) ids
c
AssignmentCache (ArchReg arch) ids
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall a b. a -> b -> b
seq AssignmentCache (ArchReg arch) ids
c' (StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall a b. (a -> b) -> a -> b
$ (AssignmentCache (ArchReg arch) ids
-> Identity (AssignmentCache (ArchReg arch) ids))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(AssignmentCache (ArchReg arch) ids
-> f (AssignmentCache (ArchReg arch) ids))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
assignmentCache ((AssignmentCache (ArchReg arch) ids
-> Identity (AssignmentCache (ArchReg arch) ids))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids))
-> AssignmentCache (ArchReg arch) ids
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= AssignmentCache (ArchReg arch) ids
c'
a -> FunctionArgsM arch ids a
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
r
valueUses :: (OrdF (ArchReg arch), FoldableFC (ArchFn arch))
=> Value arch ids tp
-> State (AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses :: forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses (AssignedValue (Assignment AssignId ids tp
a AssignRhs arch (Value arch ids) tp
rhs)) = do
Maybe (RegisterSet (ArchReg arch))
mr <- (AssignmentCache (ArchReg arch) ids
-> Maybe (RegisterSet (ArchReg arch)))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(Maybe (RegisterSet (ArchReg arch)))
forall s (m :: Type -> Type) a. MonadState s m => (s -> a) -> m a
gets ((AssignmentCache (ArchReg arch) ids
-> Maybe (RegisterSet (ArchReg arch)))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(Maybe (RegisterSet (ArchReg arch))))
-> (AssignmentCache (ArchReg arch) ids
-> Maybe (RegisterSet (ArchReg arch)))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(Maybe (RegisterSet (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ Some (AssignId ids)
-> AssignmentCache (ArchReg arch) ids
-> Maybe (RegisterSet (ArchReg arch))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (AssignId ids tp -> Some (AssignId ids)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some AssignId ids tp
a)
case Maybe (RegisterSet (ArchReg arch))
mr of
Just RegisterSet (ArchReg arch)
s -> RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure RegisterSet (ArchReg arch)
s
Maybe (RegisterSet (ArchReg arch))
Nothing -> do
RegisterSet (ArchReg arch)
rhs' <- (forall (x :: Type).
RegisterSet (ArchReg arch)
-> Value arch ids x
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch)))
-> RegisterSet (ArchReg arch)
-> AssignRhs arch (Value arch ids) tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall {k} {l} (t :: (k -> Type) -> l -> Type) (m :: Type -> Type)
b (f :: k -> Type) (c :: l).
(FoldableFC t, Monad m) =>
(forall (x :: k). b -> f x -> m b) -> b -> t f c -> m b
foldlMFC (\RegisterSet (ArchReg arch)
s Value arch ids x
v -> RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a b. a -> b -> b
seq RegisterSet (ArchReg arch)
s (State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch)))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ RegisterSet (ArchReg arch)
-> RegisterSet (ArchReg arch) -> RegisterSet (ArchReg arch)
forall a. Ord a => Set a -> Set a -> Set a
Set.union RegisterSet (ArchReg arch)
s (RegisterSet (ArchReg arch) -> RegisterSet (ArchReg arch))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Value arch ids x
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses Value arch ids x
v) RegisterSet (ArchReg arch)
forall a. Set a
Set.empty AssignRhs arch (Value arch ids) tp
rhs
RegisterSet (ArchReg arch)
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ()
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ()
forall a b. a -> b -> b
seq RegisterSet (ArchReg arch)
rhs' (StateT (AssignmentCache (ArchReg arch) ids) Identity ()
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ())
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ()
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ()
forall a b. (a -> b) -> a -> b
$ (AssignmentCache (ArchReg arch) ids
-> AssignmentCache (ArchReg arch) ids)
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ()
forall s (m :: Type -> Type). MonadState s m => (s -> s) -> m ()
modify' ((AssignmentCache (ArchReg arch) ids
-> AssignmentCache (ArchReg arch) ids)
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ())
-> (AssignmentCache (ArchReg arch) ids
-> AssignmentCache (ArchReg arch) ids)
-> StateT (AssignmentCache (ArchReg arch) ids) Identity ()
forall a b. (a -> b) -> a -> b
$ Some (AssignId ids)
-> RegisterSet (ArchReg arch)
-> AssignmentCache (ArchReg arch) ids
-> AssignmentCache (ArchReg arch) ids
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (AssignId ids tp -> Some (AssignId ids)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some AssignId ids tp
a) RegisterSet (ArchReg arch)
rhs'
RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure RegisterSet (ArchReg arch)
rhs'
valueUses (Initial ArchReg arch tp
r) =
RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch)))
-> RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a b. (a -> b) -> a -> b
$! Some (ArchReg arch) -> RegisterSet (ArchReg arch)
forall a. a -> Set a
Set.singleton (ArchReg arch tp -> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch tp
r)
valueUses Value arch ids tp
_ =
RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch)))
-> RegisterSet (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall a b. (a -> b) -> a -> b
$! RegisterSet (ArchReg arch)
forall a. Set a
Set.empty
addValueUses :: (OrdF (ArchReg arch), FoldableFC (ArchFn arch))
=> RegisterSet (ArchReg arch)
-> Value arch ids tp
-> State (AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
addValueUses :: forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
RegisterSet (ArchReg arch)
-> Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
addValueUses RegisterSet (ArchReg arch)
s Value arch ids tp
v = RegisterSet (ArchReg arch)
-> RegisterSet (ArchReg arch) -> RegisterSet (ArchReg arch)
forall a. Ord a => Set a -> Set a -> Set a
Set.union RegisterSet (ArchReg arch)
s (RegisterSet (ArchReg arch) -> RegisterSet (ArchReg arch))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Value arch ids tp
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses Value arch ids tp
v
addBlockDemands :: OrdF (ArchReg arch)
=> ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> FunctionArgsM arch ids ()
addBlockDemands :: forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands MemSegmentOff (RegAddrWidth (ArchReg arch))
a BlockDemands (ArchReg arch)
m =
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap ((Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids))
-> (Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= (BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch) -> BlockDemands (ArchReg arch))
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type).
OrdF r =>
BlockDemands r -> BlockDemands r -> BlockDemands r
unionBlockDemands MemSegmentOff (RegAddrWidth (ArchReg arch))
a BlockDemands (ArchReg arch)
m
recordBlockTransfer :: forall arch ids t
. ( RegisterInfo (ArchReg arch)
, FoldableFC (ArchFn arch)
, Foldable t
)
=> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer :: forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer ArchSegmentOff arch
_addr RegState (ArchReg arch) (Value arch ids)
regs t (Some (ArchReg arch))
regSet = do
let doReg :: FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch)
-> State (AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
doReg :: FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
doReg FinalRegisterDemands (ArchReg arch)
m (Some ArchReg arch x
r) =
case ArchReg arch x
-> ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Maybe (x :~: BVType (RegAddrWidth (ArchReg arch)))
forall {k} (f :: k -> Type) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
forall (a :: Type) (b :: Type).
ArchReg arch a -> ArchReg arch b -> Maybe (a :~: b)
testEquality ArchReg arch x
r ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg of
Just x :~: BVType (RegAddrWidth (ArchReg arch))
_ -> FinalRegisterDemands (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
m
Maybe (x :~: BVType (RegAddrWidth (ArchReg arch)))
Nothing -> do
RegisterSet (ArchReg arch)
rs' <- Value arch ids x
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses (RegState (ArchReg arch) (Value arch ids)
regsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids x)
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids x)
-> Value arch ids x
forall s a. s -> Getting a s a -> a
^.ArchReg arch x
-> Lens'
(RegState (ArchReg arch) (Value arch ids)) (Value arch ids x)
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch x
r)
FinalRegisterDemands (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (FinalRegisterDemands (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch)))
-> FinalRegisterDemands (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$! ArchReg arch x
-> DemandSet (ArchReg arch)
-> FinalRegisterDemands (ArchReg arch)
-> FinalRegisterDemands (ArchReg arch)
forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
r tp
-> DemandSet r -> FinalRegisterDemands r -> FinalRegisterDemands r
insertRegDemand ArchReg arch x
r (RegisterSet (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet RegisterSet (ArchReg arch)
rs') FinalRegisterDemands (ArchReg arch)
m
State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch)))
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ (FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch)))
-> FinalRegisterDemands (ArchReg arch)
-> t (Some (ArchReg arch))
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch)
-> State
(AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch))
doReg FinalRegisterDemands (ArchReg arch)
forall a. Monoid a => a
mempty t (Some (ArchReg arch))
regSet
demandValue :: (OrdF (ArchReg arch), FoldableFC (ArchFn arch))
=> ArchSegmentOff arch
-> Value arch ids tp
-> FunctionArgsM arch ids ()
demandValue :: forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
addr Value arch ids tp
v = do
RegisterSet (ArchReg arch)
regs <- State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(RegisterSet (ArchReg arch))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(RegisterSet (ArchReg arch)))
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(RegisterSet (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses Value arch ids tp
v
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands ArchSegmentOff arch
addr (BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ())
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
forall a b. (a -> b) -> a -> b
$ DemandSet (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type). DemandSet r -> BlockDemands r
demandAlways (RegisterSet (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet RegisterSet (ArchReg arch)
regs)
type AddrDemandMap r = Map (RegSegmentOff r) (DemandSet r)
type ArgDemandsMap r = Map (RegSegmentOff r, Some r) (AddrDemandMap r)
linkKnownCallArguments :: ( FoldableFC (ArchFn arch)
, RegisterInfo (ArchReg arch)
)
=> BlockDemands (ArchReg arch)
-> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> FunctionArgsM arch ids (BlockDemands (ArchReg arch))
linkKnownCallArguments :: forall arch ids.
(FoldableFC (ArchFn arch), RegisterInfo (ArchReg arch)) =>
BlockDemands (ArchReg arch)
-> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> FunctionArgsM arch ids (BlockDemands (ArchReg arch))
linkKnownCallArguments BlockDemands (ArchReg arch)
curBlockDemands ArchSegmentOff arch
faddr RegState (ArchReg arch) (Value arch ids)
regs = do
[Some (ArchReg arch)]
argRegs <- (FunArgContext arch -> [Some (ArchReg arch)])
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
[Some (ArchReg arch)]
forall r (m :: Type -> Type) a. MonadReader r m => (r -> a) -> m a
asks ((FunArgContext arch -> [Some (ArchReg arch)])
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
[Some (ArchReg arch)])
-> (FunArgContext arch -> [Some (ArchReg arch)])
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
[Some (ArchReg arch)]
forall a b. (a -> b) -> a -> b
$ ArchDemandInfo arch -> [Some (ArchReg arch)]
forall arch. ArchDemandInfo arch -> [Some (ArchReg arch)]
functionArgRegs (ArchDemandInfo arch -> [Some (ArchReg arch)])
-> (FunArgContext arch -> ArchDemandInfo arch)
-> FunArgContext arch
-> [Some (ArchReg arch)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FunArgContext arch -> ArchDemandInfo arch
forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo
let insertArgRegDemands :: BlockDemands (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
insertArgRegDemands BlockDemands (ArchReg arch)
m (Some ArchReg arch x
r) = do
RegisterSet (ArchReg arch)
vals <- Value arch ids x
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses (RegState (ArchReg arch) (Value arch ids)
regsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids x)
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids x)
-> Value arch ids x
forall s a. s -> Getting a s a -> a
^. ArchReg arch x
-> Lens'
(RegState (ArchReg arch) (Value arch ids)) (Value arch ids x)
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch x
r)
BlockDemands (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (BlockDemands (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch)))
-> BlockDemands (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$! ArchSegmentOff arch
-> ArchReg arch x
-> DemandSet (ArchReg arch)
-> BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch)
forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
RegSegmentOff r
-> r tp -> DemandSet r -> BlockDemands r -> BlockDemands r
addDemandFunctionArg ArchSegmentOff arch
faddr ArchReg arch x
r (RegisterSet (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet RegisterSet (ArchReg arch)
vals) BlockDemands (ArchReg arch)
m
StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids (BlockDemands (ArchReg arch))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids (BlockDemands (ArchReg arch)))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids (BlockDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ (BlockDemands (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch)))
-> BlockDemands (ArchReg arch)
-> [Some (ArchReg arch)]
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM BlockDemands (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
insertArgRegDemands BlockDemands (ArchReg arch)
curBlockDemands [Some (ArchReg arch)]
argRegs
linkKnownCallReturnValues :: forall arch ids
. ( RegisterInfo (ArchReg arch)
, FoldableFC (ArchFn arch)
)
=> ArchSegmentOff arch
-> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
linkKnownCallReturnValues :: forall arch ids.
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
linkKnownCallReturnValues MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr RegState (ArchReg arch) (Value arch ids)
regs Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
mReturnAddr = do
ArchDemandInfo arch
ainfo <- (FunArgContext arch -> ArchDemandInfo arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(ArchDemandInfo arch)
forall r (m :: Type -> Type) a. MonadReader r m => (r -> a) -> m a
asks FunArgContext arch -> ArchDemandInfo arch
forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo
let retRegs :: [Some (ArchReg arch)]
retRegs = ArchDemandInfo arch -> [Some (ArchReg arch)]
forall arch. ArchDemandInfo arch -> [Some (ArchReg arch)]
functionRetRegs ArchDemandInfo arch
ainfo
case Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
mReturnAddr of
Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
Nothing -> do
BlockDemands (ArchReg arch)
curDemandMap <- BlockDemands (ArchReg arch)
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault BlockDemands (ArchReg arch)
forall a. Monoid a => a
mempty MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr (Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(FunctionArgsState arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(FunctionArgsState arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap
let addRetRegDemands :: BlockDemands (ArchReg arch)
-> Some (ArchReg arch) -> BlockDemands (ArchReg arch)
addRetRegDemands BlockDemands (ArchReg arch)
m (Some ArchReg arch x
r) =
ArchReg arch x
-> DemandSet (ArchReg arch)
-> BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch)
forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
r tp -> DemandSet r -> BlockDemands r -> BlockDemands r
addDemandFunctionResult ArchReg arch x
r (MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Some (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type).
MemSegmentOff (RegAddrWidth r) -> Some r -> DemandSet r
demandFunctionReturn MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr (ArchReg arch x -> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch x
r)) BlockDemands (ArchReg arch)
m
let nextDemandMap :: BlockDemands (ArchReg arch)
nextDemandMap = (BlockDemands (ArchReg arch)
-> Some (ArchReg arch) -> BlockDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> [Some (ArchReg arch)]
-> BlockDemands (ArchReg arch)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' BlockDemands (ArchReg arch)
-> Some (ArchReg arch) -> BlockDemands (ArchReg arch)
addRetRegDemands BlockDemands (ArchReg arch)
curDemandMap [Some (ArchReg arch)]
retRegs
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap ((Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids))
-> (Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr BlockDemands (ArchReg arch)
nextDemandMap
FinalRegisterDemands (ArchReg arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
forall a. Monoid a => a
mempty
Just MemSegmentOff (RegAddrWidth (ArchReg arch))
_ -> do
FinalRegisterDemands (ArchReg arch)
newDemands <-
MemSegmentOff (RegAddrWidth (ArchReg arch))
-> RegState (ArchReg arch) (Value arch ids)
-> [Some (ArchReg arch)]
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr RegState (ArchReg arch) (Value arch ids)
regs (ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
sp_reg Some (ArchReg arch)
-> [Some (ArchReg arch)] -> [Some (ArchReg arch)]
forall a. a -> [a] -> [a]
: Set (Some (ArchReg arch)) -> [Some (ArchReg arch)]
forall a. Set a -> [a]
Set.toList (ArchDemandInfo arch -> Set (Some (ArchReg arch))
forall arch. ArchDemandInfo arch -> Set (Some (ArchReg arch))
calleeSavedRegs ArchDemandInfo arch
ainfo))
let linkRetReg :: FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch) -> FinalRegisterDemands (ArchReg arch)
linkRetReg FinalRegisterDemands (ArchReg arch)
m (Some ArchReg arch x
r) = ArchReg arch x
-> DemandSet (ArchReg arch)
-> FinalRegisterDemands (ArchReg arch)
-> FinalRegisterDemands (ArchReg arch)
forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
r tp
-> DemandSet r -> FinalRegisterDemands r -> FinalRegisterDemands r
insertRegDemand ArchReg arch x
r (MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Some (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type).
MemSegmentOff (RegAddrWidth r) -> Some r -> DemandSet r
demandFunctionReturn MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr (ArchReg arch x -> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch x
r)) FinalRegisterDemands (ArchReg arch)
m
let srDemandSet :: FinalRegisterDemands (ArchReg arch)
srDemandSet :: FinalRegisterDemands (ArchReg arch)
srDemandSet = (FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch) -> FinalRegisterDemands (ArchReg arch))
-> FinalRegisterDemands (ArchReg arch)
-> [Some (ArchReg arch)]
-> FinalRegisterDemands (ArchReg arch)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch) -> FinalRegisterDemands (ArchReg arch)
linkRetReg FinalRegisterDemands (ArchReg arch)
newDemands [Some (ArchReg arch)]
retRegs
FinalRegisterDemands (ArchReg arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
srDemandSet
summarizeCall :: forall arch ids
. ( FoldableFC (ArchFn arch)
, RegisterInfo (ArchReg arch)
)
=> ArchSegmentOff arch
-> ArchAddrWord arch
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
summarizeCall :: forall arch ids.
(FoldableFC (ArchFn arch), RegisterInfo (ArchReg arch)) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
summarizeCall MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr MemWord (RegAddrWidth (ArchReg arch))
callOff RegState (ArchReg arch) (Value arch ids)
finalRegs Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
mReturnAddr = do
FunArgContext arch
ctx <- StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(FunArgContext arch)
forall r (m :: Type -> Type). MonadReader r m => m r
ask
let ipVal :: Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal = RegState (ArchReg arch) (Value arch ids)
finalRegsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^.ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg
let spVal :: Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
spVal = RegState (ArchReg arch) (Value arch ids)
finalRegsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^.ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
sp_reg
do Set (Some (ArchReg arch))
demands <- State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Set (Some (ArchReg arch)))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Set (Some (ArchReg arch))))
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Set (Some (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ (Set (Some (ArchReg arch))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch))))
-> Set (Some (ArchReg arch))
-> [Value arch ids (BVType (RegAddrWidth (ArchReg arch)))]
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM Set (Some (ArchReg arch))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
RegisterSet (ArchReg arch)
-> Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
addValueUses Set (Some (ArchReg arch))
forall a. Set a
Set.empty [Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal, Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
spVal]
MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr (BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall a b. (a -> b) -> a -> b
$ DemandSet (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type). DemandSet r -> BlockDemands r
demandAlways (Set (Some (ArchReg arch)) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet Set (Some (ArchReg arch))
demands)
case () of
()
_ | Just MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr <- Memory (RegAddrWidth (ArchReg arch))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall arch ids.
Memory (ArchAddrWidth arch)
-> BVValue arch ids (ArchAddrWidth arch)
-> Maybe (ArchSegmentOff arch)
valueAsSegmentOff (FunArgContext arch -> Memory (RegAddrWidth (ArchReg arch))
forall arch. FunArgContext arch -> Memory (ArchAddrWidth arch)
ctxMemory FunArgContext arch
ctx) Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal
, MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Set (MemSegmentOff (RegAddrWidth (ArchReg arch))) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr (FunArgContext arch
-> Set (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall arch. FunArgContext arch -> Set (ArchSegmentOff arch)
computedAddrSet FunArgContext arch
ctx) -> do
BlockDemands (ArchReg arch)
curBlockDemands <- BlockDemands (ArchReg arch)
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault BlockDemands (ArchReg arch)
forall a. Monoid a => a
mempty MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr (Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(FunctionArgsState arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(FunctionArgsState arch ids)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap
BlockDemands (ArchReg arch)
newBlockDemands <- BlockDemands (ArchReg arch)
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> RegState (ArchReg arch) (Value arch ids)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall arch ids.
(FoldableFC (ArchFn arch), RegisterInfo (ArchReg arch)) =>
BlockDemands (ArchReg arch)
-> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> FunctionArgsM arch ids (BlockDemands (ArchReg arch))
linkKnownCallArguments BlockDemands (ArchReg arch)
curBlockDemands MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr RegState (ArchReg arch) (Value arch ids)
finalRegs
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap ((Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids))
-> (Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr BlockDemands (ArchReg arch)
newBlockDemands
MemSegmentOff (RegAddrWidth (ArchReg arch))
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids.
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
linkKnownCallReturnValues MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr MemSegmentOff (RegAddrWidth (ArchReg arch))
faddr RegState (ArchReg arch) (Value arch ids)
finalRegs Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
mReturnAddr
()
_ -> do
let ainfo :: ArchDemandInfo arch
ainfo = FunArgContext arch -> ArchDemandInfo arch
forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo FunArgContext arch
ctx
let callAddr :: MemSegmentOff (RegAddrWidth (ArchReg arch))
callAddr =
case MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Integer -> Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall (w :: Nat).
MemWidth w =>
MemSegmentOff w -> Integer -> Maybe (MemSegmentOff w)
incSegmentOff MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr (MemWord (RegAddrWidth (ArchReg arch)) -> Integer
forall a. Integral a => a -> Integer
toInteger MemWord (RegAddrWidth (ArchReg arch))
callOff) of
Just MemSegmentOff (RegAddrWidth (ArchReg arch))
a -> MemSegmentOff (RegAddrWidth (ArchReg arch))
a
Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
Nothing -> String -> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall a. HasCallStack => String -> a
error String
"Call site is not a valid address."
[Some (Value arch ids)]
argValues <-
case FunArgContext arch -> ResolveCallArgsFn arch
forall arch. FunArgContext arch -> ResolveCallArgsFn arch
resolveCallArgs FunArgContext arch
ctx MemSegmentOff (RegAddrWidth (ArchReg arch))
callAddr RegState (ArchReg arch) (Value arch ids)
finalRegs of
Left String
e -> FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
[Some (Value arch ids)]
forall a.
FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall e (m :: Type -> Type) a. MonadError e m => e -> m a
throwError (MemSegmentOff (RegAddrWidth (ArchReg arch))
-> String
-> FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
forall (w :: Nat).
MemSegmentOff w -> String -> FunctionArgAnalysisFailure w
CallAnalysisError MemSegmentOff (RegAddrWidth (ArchReg arch))
callAddr String
e)
Right [Some (Value arch ids)]
r -> [Some (Value arch ids)]
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
[Some (Value arch ids)]
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure [Some (Value arch ids)]
r
let regUses :: RegisterSet (ArchReg arch)
-> Some (Value arch ids)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
regUses RegisterSet (ArchReg arch)
s (Some Value arch ids x
v) = RegisterSet (ArchReg arch)
-> Value arch ids x
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
RegisterSet (ArchReg arch)
-> Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
addValueUses RegisterSet (ArchReg arch)
s Value arch ids x
v
Set (Some (ArchReg arch))
demands <- State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Set (Some (ArchReg arch)))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Set (Some (ArchReg arch))))
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Set (Some (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ (Set (Some (ArchReg arch))
-> Some (Value arch ids)
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch))))
-> Set (Some (ArchReg arch))
-> [Some (Value arch ids)]
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM Set (Some (ArchReg arch))
-> Some (Value arch ids)
-> State
(AssignmentCache (ArchReg arch) ids) (Set (Some (ArchReg arch)))
forall {arch} {ids}.
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
RegisterSet (ArchReg arch)
-> Some (Value arch ids)
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
regUses Set (Some (ArchReg arch))
forall a. Set a
Set.empty [Some (Value arch ids)]
argValues
MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr (BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall a b. (a -> b) -> a -> b
$ DemandSet (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type). DemandSet r -> BlockDemands r
demandAlways (Set (Some (ArchReg arch)) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet Set (Some (ArchReg arch))
demands)
if Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch))) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
mReturnAddr then do
let savedRegs :: [Some (ArchReg arch)]
savedRegs = ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
sp_reg Some (ArchReg arch)
-> [Some (ArchReg arch)] -> [Some (ArchReg arch)]
forall a. a -> [a] -> [a]
: Set (Some (ArchReg arch)) -> [Some (ArchReg arch)]
forall a. Set a -> [a]
Set.toList (ArchDemandInfo arch -> Set (Some (ArchReg arch))
forall arch. ArchDemandInfo arch -> Set (Some (ArchReg arch))
calleeSavedRegs ArchDemandInfo arch
ainfo)
MemSegmentOff (RegAddrWidth (ArchReg arch))
-> RegState (ArchReg arch) (Value arch ids)
-> [Some (ArchReg arch)]
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer MemSegmentOff (RegAddrWidth (ArchReg arch))
blockAddr RegState (ArchReg arch) (Value arch ids)
finalRegs [Some (ArchReg arch)]
savedRegs
else
FinalRegisterDemands (ArchReg arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
forall a. Monoid a => a
mempty
recordStmtsDemands :: OrdF (ArchReg arch)
=> ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands :: forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
_blockAddr ArchAddrWord arch
off [] = do
ArchAddrWord arch -> FunctionArgsM arch ids (ArchAddrWord arch)
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ArchAddrWord arch
off
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off (Stmt arch ids
stmt:[Stmt arch ids]
stmts) = do
DemandContext arch
ctx <- (FunArgContext arch -> DemandContext arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(DemandContext arch)
forall r (m :: Type -> Type) a. MonadReader r m => (r -> a) -> m a
asks ((FunArgContext arch -> DemandContext arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(DemandContext arch))
-> (FunArgContext arch -> DemandContext arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(DemandContext arch)
forall a b. (a -> b) -> a -> b
$ ArchDemandInfo arch -> DemandContext arch
forall arch. ArchDemandInfo arch -> DemandContext arch
demandInfoCtx (ArchDemandInfo arch -> DemandContext arch)
-> (FunArgContext arch -> ArchDemandInfo arch)
-> FunArgContext arch
-> DemandContext arch
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FunArgContext arch -> ArchDemandInfo arch
forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo
DemandContext arch
-> forall a.
((FoldableFC (ArchFn arch), FoldableF (ArchStmt arch)) => a) -> a
forall arch.
DemandContext arch
-> forall a.
((FoldableFC (ArchFn arch), FoldableF (ArchStmt arch)) => a) -> a
demandConstraints DemandContext arch
ctx (((FoldableFC (ArchFn arch), FoldableF (ArchStmt arch)) =>
FunctionArgsM arch ids (ArchAddrWord arch))
-> FunctionArgsM arch ids (ArchAddrWord arch))
-> ((FoldableFC (ArchFn arch), FoldableF (ArchStmt arch)) =>
FunctionArgsM arch ids (ArchAddrWord arch))
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall a b. (a -> b) -> a -> b
$ do
case Stmt arch ids
stmt of
AssignStmt Assignment arch ids tp
a -> do
Bool
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (DemandContext arch -> AssignRhs arch (Value arch ids) tp -> Bool
forall arch (f :: Type -> Type) (tp :: Type).
DemandContext arch -> AssignRhs arch f tp -> Bool
hasSideEffects DemandContext arch
ctx (Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
forall arch ids (tp :: Type).
Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
assignRhs Assignment arch ids tp
a)) (StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall a b. (a -> b) -> a -> b
$ do
(forall (x :: Type).
Value arch ids x
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> forall (x :: Type).
AssignRhs arch (Value arch ids) x
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall {k} {l} (t :: (k -> Type) -> l -> Type) (m :: Type -> Type)
(f :: k -> Type) a.
(FoldableFC t, Applicative m) =>
(forall (x :: k). f x -> m a) -> forall (x :: l). t f x -> m ()
traverseFC_ (ArchSegmentOff arch
-> Value arch ids x
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr) (Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
forall arch ids (tp :: Type).
Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
assignRhs Assignment arch ids tp
a)
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off [Stmt arch ids]
stmts
WriteMem ArchAddrValue arch ids
addr MemRepr tp
_ Value arch ids tp
v -> do
ArchSegmentOff arch
-> ArchAddrValue arch ids
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr ArchAddrValue arch ids
addr
ArchSegmentOff arch
-> Value arch ids tp
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr Value arch ids tp
v
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off [Stmt arch ids]
stmts
CondWriteMem Value arch ids BoolType
cond ArchAddrValue arch ids
addr MemRepr tp
_ Value arch ids tp
v -> do
ArchSegmentOff arch
-> Value arch ids BoolType
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr Value arch ids BoolType
cond
ArchSegmentOff arch
-> ArchAddrValue arch ids
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr ArchAddrValue arch ids
addr
ArchSegmentOff arch
-> Value arch ids tp
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr Value arch ids tp
v
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off [Stmt arch ids]
stmts
InstructionStart ArchAddrWord arch
off' Text
_ -> do
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off' [Stmt arch ids]
stmts
Comment Text
_ -> do
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off [Stmt arch ids]
stmts
ExecArchStmt ArchStmt arch (Value arch ids)
astmt -> do
(forall (x :: Type).
Value arch ids x
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> ArchStmt arch (Value arch ids)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall {k} (t :: (k -> Type) -> Type) (f :: Type -> Type)
(e :: k -> Type) a.
(FoldableF t, Applicative f) =>
(forall (s :: k). e s -> f a) -> t e -> f ()
traverseF_ (ArchSegmentOff arch
-> Value arch ids s
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr) ArchStmt arch (Value arch ids)
astmt
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off [Stmt arch ids]
stmts
ArchState ArchMemAddr arch
_addr MapF (ArchReg arch) (Value arch ids)
_assn -> do
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr ArchAddrWord arch
off [Stmt arch ids]
stmts
summarizeBlock :: forall arch ids
. ArchConstraints arch
=> ParsedBlock arch ids
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
summarizeBlock :: forall arch ids.
ArchConstraints arch =>
ParsedBlock arch ids
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
summarizeBlock ParsedBlock arch ids
b = do
let blockAddr :: ArchSegmentOff arch
blockAddr = ParsedBlock arch ids -> ArchSegmentOff arch
forall arch ids. ParsedBlock arch ids -> ArchSegmentOff arch
pblockAddr ParsedBlock arch ids
b
ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands ArchSegmentOff arch
blockAddr BlockDemands (ArchReg arch)
forall a. Monoid a => a
mempty
FunArgContext arch
ctx <- StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(FunArgContext arch)
forall r (m :: Type -> Type). MonadReader r m => m r
ask
let ainfo :: ArchDemandInfo arch
ainfo = FunArgContext arch -> ArchDemandInfo arch
forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo FunArgContext arch
ctx
MemWord (RegAddrWidth (ArchReg arch))
finalOff <- ArchSegmentOff arch
-> MemWord (RegAddrWidth (ArchReg arch))
-> [Stmt arch ids]
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(MemWord (RegAddrWidth (ArchReg arch)))
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> [Stmt arch ids]
-> FunctionArgsM arch ids (ArchAddrWord arch)
recordStmtsDemands ArchSegmentOff arch
blockAddr MemWord (RegAddrWidth (ArchReg arch))
0 (ParsedBlock arch ids -> [Stmt arch ids]
forall arch ids. ParsedBlock arch ids -> [Stmt arch ids]
pblockStmts ParsedBlock arch ids
b)
case ParsedBlock arch ids -> ParsedTermStmt arch ids
forall arch ids. ParsedBlock arch ids -> ParsedTermStmt arch ids
pblockTermStmt ParsedBlock arch ids
b of
ParsedCall RegState (ArchReg arch) (Value arch ids)
regs Maybe (ArchSegmentOff arch)
mRetAddr -> do
ArchSegmentOff arch
-> MemWord (RegAddrWidth (ArchReg arch))
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids.
(FoldableFC (ArchFn arch), RegisterInfo (ArchReg arch)) =>
ArchSegmentOff arch
-> ArchAddrWord arch
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
summarizeCall ArchSegmentOff arch
blockAddr MemWord (RegAddrWidth (ArchReg arch))
finalOff RegState (ArchReg arch) (Value arch ids)
regs Maybe (ArchSegmentOff arch)
mRetAddr
PLTStub{} -> do
FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall e (m :: Type -> Type) a. MonadError e m => e -> m a
throwError FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch))
forall (w :: Nat). FunctionArgAnalysisFailure w
PLTStubNotSupported
ParsedJump RegState (ArchReg arch) (Value arch ids)
regs ArchSegmentOff arch
_tgtAddr -> do
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> [Some (ArchReg arch)]
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer ArchSegmentOff arch
blockAddr RegState (ArchReg arch) (Value arch ids)
regs [Some (ArchReg arch)]
forall (r :: Type -> Type). RegisterInfo r => [Some r]
archRegs
ParsedBranch RegState (ArchReg arch) (Value arch ids)
regs Value arch ids BoolType
cond ArchSegmentOff arch
_trueAddr ArchSegmentOff arch
_falseAddr -> do
ArchSegmentOff arch
-> Value arch ids BoolType
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr Value arch ids BoolType
cond
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> [Some (ArchReg arch)]
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer ArchSegmentOff arch
blockAddr RegState (ArchReg arch) (Value arch ids)
regs [Some (ArchReg arch)]
forall (r :: Type -> Type). RegisterInfo r => [Some r]
archRegs
ParsedLookupTable JumpTableLayout arch
_layout RegState (ArchReg arch) (Value arch ids)
regs ArchAddrValue arch ids
lookupIdx Vector (ArchSegmentOff arch)
_vec -> do
ArchSegmentOff arch
-> ArchAddrValue arch ids
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
ArchSegmentOff arch
-> Value arch ids tp -> FunctionArgsM arch ids ()
demandValue ArchSegmentOff arch
blockAddr ArchAddrValue arch ids
lookupIdx
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> [Some (ArchReg arch)]
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer ArchSegmentOff arch
blockAddr RegState (ArchReg arch) (Value arch ids)
regs [Some (ArchReg arch)]
forall (r :: Type -> Type). RegisterInfo r => [Some r]
archRegs
ParsedReturn RegState (ArchReg arch) (Value arch ids)
regs -> do
let retRegs :: [Some (ArchReg arch)]
retRegs = ArchDemandInfo arch -> [Some (ArchReg arch)]
forall arch. ArchDemandInfo arch -> [Some (ArchReg arch)]
functionRetRegs ArchDemandInfo arch
ainfo
let regDemandSet :: BlockDemands (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
regDemandSet BlockDemands (ArchReg arch)
m (Some ArchReg arch x
r) = do
RegisterSet (ArchReg arch)
rUses <- Value arch ids x
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
valueUses (RegState (ArchReg arch) (Value arch ids)
regsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids x)
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids x)
-> Value arch ids x
forall s a. s -> Getting a s a -> a
^.ArchReg arch x
-> Lens'
(RegState (ArchReg arch) (Value arch ids)) (Value arch ids x)
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch x
r)
BlockDemands (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
forall a.
a -> StateT (AssignmentCache (ArchReg arch) ids) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (BlockDemands (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch)))
-> BlockDemands (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$! ArchReg arch x
-> DemandSet (ArchReg arch)
-> BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch)
forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
r tp -> DemandSet r -> BlockDemands r -> BlockDemands r
addDemandFunctionResult ArchReg arch x
r (RegisterSet (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet RegisterSet (ArchReg arch)
rUses) BlockDemands (ArchReg arch)
m
BlockDemands (ArchReg arch)
demands <- StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch)))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ (BlockDemands (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch)))
-> BlockDemands (ArchReg arch)
-> [Some (ArchReg arch)]
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM BlockDemands (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(BlockDemands (ArchReg arch))
regDemandSet BlockDemands (ArchReg arch)
forall a. Monoid a => a
mempty [Some (ArchReg arch)]
retRegs
ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands ArchSegmentOff arch
blockAddr BlockDemands (ArchReg arch)
demands
FinalRegisterDemands (ArchReg arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
forall a. Monoid a => a
mempty
ParsedArchTermStmt ArchTermStmt arch (Value arch ids)
tstmt RegState (ArchReg arch) (Value arch ids)
regs Maybe (ArchSegmentOff arch)
_nextAddr -> do
let e :: ArchTermStmtRegEffects arch
e = ArchDemandInfo arch
-> forall ids. ComputeArchTermStmtEffects arch ids
forall arch.
ArchDemandInfo arch
-> forall ids. ComputeArchTermStmtEffects arch ids
computeArchTermStmtEffects ArchDemandInfo arch
ainfo ArchTermStmt arch (Value arch ids)
tstmt RegState (ArchReg arch) (Value arch ids)
regs
do let regUses :: RegisterSet (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
regUses RegisterSet (ArchReg arch)
s (Some ArchReg arch x
r) = RegisterSet (ArchReg arch)
-> Value arch ids x
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall arch ids (tp :: Type).
(OrdF (ArchReg arch), FoldableFC (ArchFn arch)) =>
RegisterSet (ArchReg arch)
-> Value arch ids tp
-> State
(AssignmentCache (ArchReg arch) ids) (RegisterSet (ArchReg arch))
addValueUses RegisterSet (ArchReg arch)
s (RegState (ArchReg arch) (Value arch ids)
regsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids x)
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids x)
-> Value arch ids x
forall s a. s -> Getting a s a -> a
^.ArchReg arch x
-> Lens'
(RegState (ArchReg arch) (Value arch ids)) (Value arch ids x)
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch x
r)
RegisterSet (ArchReg arch)
demands <- StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(RegisterSet (ArchReg arch))
forall arch ids a.
State (AssignmentCache (ArchReg arch) ids) a
-> FunctionArgsM arch ids a
withAssignmentCache (StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(RegisterSet (ArchReg arch)))
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(RegisterSet (ArchReg arch))
forall a b. (a -> b) -> a -> b
$
(RegisterSet (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch)))
-> RegisterSet (ArchReg arch)
-> [Some (ArchReg arch)]
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM RegisterSet (ArchReg arch)
-> Some (ArchReg arch)
-> StateT
(AssignmentCache (ArchReg arch) ids)
Identity
(RegisterSet (ArchReg arch))
regUses RegisterSet (ArchReg arch)
forall a. Set a
Set.empty (ArchTermStmtRegEffects arch -> [Some (ArchReg arch)]
forall arch. ArchTermStmtRegEffects arch -> [Some (ArchReg arch)]
termRegDemands ArchTermStmtRegEffects arch
e)
ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids.
OrdF (ArchReg arch) =>
ArchSegmentOff arch
-> BlockDemands (ArchReg arch) -> FunctionArgsM arch ids ()
addBlockDemands ArchSegmentOff arch
blockAddr (BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
())
-> BlockDemands (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall a b. (a -> b) -> a -> b
$ DemandSet (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type). DemandSet r -> BlockDemands r
demandAlways (RegisterSet (ArchReg arch) -> DemandSet (ArchReg arch)
forall (r :: Type -> Type). RegisterSet r -> DemandSet r
registerDemandSet RegisterSet (ArchReg arch)
demands)
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> [Some (ArchReg arch)]
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall arch ids (t :: Type -> Type).
(RegisterInfo (ArchReg arch), FoldableFC (ArchFn arch),
Foldable t) =>
ArchSegmentOff arch
-> RegState (ArchReg arch) (Value arch ids)
-> t (Some (ArchReg arch))
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
recordBlockTransfer ArchSegmentOff arch
blockAddr RegState (ArchReg arch) (Value arch ids)
regs (ArchTermStmtRegEffects arch -> [Some (ArchReg arch)]
forall arch. ArchTermStmtRegEffects arch -> [Some (ArchReg arch)]
termRegTransfers ArchTermStmtRegEffects arch
e)
ParsedTranslateError Text
_ -> do
FinalRegisterDemands (ArchReg arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
forall a. Monoid a => a
mempty
ClassifyFailure RegState (ArchReg arch) (Value arch ids)
_ [String]
_ ->
FinalRegisterDemands (ArchReg arch)
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure FinalRegisterDemands (ArchReg arch)
forall a. Monoid a => a
mempty
transferRegDemand :: ( MemWidth (ArchAddrWidth arch)
, OrdF (ArchReg arch)
, ShowF (ArchReg arch)
)
=> FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> Some (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
transferRegDemand :: forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> Some (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
transferRegDemand (FRD Map (Some (ArchReg arch)) (DemandSet (ArchReg arch))
xfer) DemandSet (ArchReg arch)
s (Some ArchReg arch x
r) =
case Some (ArchReg arch)
-> Map (Some (ArchReg arch)) (DemandSet (ArchReg arch))
-> Maybe (DemandSet (ArchReg arch))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (ArchReg arch x -> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch x
r) Map (Some (ArchReg arch)) (DemandSet (ArchReg arch))
xfer of
Just DemandSet (ArchReg arch)
t -> DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch)))
-> DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ DemandSet (ArchReg arch)
-> DemandSet (ArchReg arch) -> DemandSet (ArchReg arch)
forall a. Monoid a => a -> a -> a
mappend DemandSet (ArchReg arch)
s DemandSet (ArchReg arch)
t
Maybe (DemandSet (ArchReg arch))
Nothing -> DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure DemandSet (ArchReg arch)
s
transferDemands :: ( MemWidth (ArchAddrWidth arch)
, OrdF (ArchReg arch)
, ShowF (ArchReg arch)
)
=> FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
transferDemands :: forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
transferDemands FinalRegisterDemands (ArchReg arch)
xfer (DemandSet RegisterSet (ArchReg arch)
regs Map
(MemSegmentOff (ArchAddrWidth arch)) (RegisterSet (ArchReg arch))
funs) = do
(DemandSet (ArchReg arch)
-> Some (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch)))
-> DemandSet (ArchReg arch)
-> RegisterSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM (FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> Some (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> Some (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
transferRegDemand FinalRegisterDemands (ArchReg arch)
xfer) (RegisterSet (ArchReg arch)
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (RegisterSet (ArchReg arch))
-> DemandSet (ArchReg arch)
forall (r :: Type -> Type).
RegisterSet r
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
-> DemandSet r
DemandSet RegisterSet (ArchReg arch)
forall a. Set a
Set.empty Map
(MemSegmentOff (ArchAddrWidth arch)) (RegisterSet (ArchReg arch))
funs) RegisterSet (ArchReg arch)
regs
calculateOnePred :: ( MemWidth (ArchAddrWidth arch)
, OrdF (ArchReg arch)
, ShowF (ArchReg arch)
)
=> Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> ArchSegmentOff arch
-> FunctionArgsM arch ids (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
calculateOnePred :: forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> ArchSegmentOff arch
-> FunctionArgsM
arch ids (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
calculateOnePred Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
xferMap (BD Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
newDemands) Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
pendingMap MemSegmentOff (ArchAddrWidth arch)
predAddr = do
let xfer :: FinalRegisterDemands (ArchReg arch)
xfer = Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
xferMapMap
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
-> Getting
(FinalRegisterDemands (ArchReg arch))
(Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch))
-> FinalRegisterDemands (ArchReg arch)
forall s a. s -> Getting a s a -> a
^.Index
(Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch)))
-> Traversal'
(Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch)))
(IxValue
(Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index
(Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch)))
MemSegmentOff (ArchAddrWidth arch)
predAddr
BD Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
seenDemands <- Getting
(BlockDemands (ArchReg arch))
(FunctionArgsState arch ids)
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(BlockDemands (ArchReg arch))
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use ((Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Const
(BlockDemands (ArchReg arch))
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Const (BlockDemands (ArchReg arch)) (FunctionArgsState arch ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap ((Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Const
(BlockDemands (ArchReg arch))
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Const
(BlockDemands (ArchReg arch)) (FunctionArgsState arch ids))
-> ((BlockDemands (ArchReg arch)
-> Const
(BlockDemands (ArchReg arch)) (BlockDemands (ArchReg arch)))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Const
(BlockDemands (ArchReg arch))
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> Getting
(BlockDemands (ArchReg arch))
(FunctionArgsState arch ids)
(BlockDemands (ArchReg arch))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
-> Traversal'
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
(IxValue
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
MemSegmentOff (ArchAddrWidth arch)
predAddr)
Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
demands' <- (DemandSet (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(DemandSet (ArchReg arch)))
-> Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch)))
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b)
-> Map (DemandType (ArchReg arch)) a
-> f (Map (DemandType (ArchReg arch)) b)
traverse (FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(DemandSet (ArchReg arch))
forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
FinalRegisterDemands (ArchReg arch)
-> DemandSet (ArchReg arch)
-> FunctionArgsM arch ids (DemandSet (ArchReg arch))
transferDemands FinalRegisterDemands (ArchReg arch)
xfer) Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
newDemands
let diff :: OrdF r => DemandSet r -> DemandSet r -> Maybe (DemandSet r)
diff :: forall (r :: Type -> Type).
OrdF r =>
DemandSet r -> DemandSet r -> Maybe (DemandSet r)
diff DemandSet r
ds1 DemandSet r
ds2 | DemandSet r
ds' DemandSet r -> DemandSet r -> Bool
forall a. Eq a => a -> a -> Bool
== DemandSet r
forall a. Monoid a => a
mempty = Maybe (DemandSet r)
forall a. Maybe a
Nothing
| Bool
otherwise = DemandSet r -> Maybe (DemandSet r)
forall a. a -> Maybe a
Just DemandSet r
ds'
where ds' :: DemandSet r
ds' = DemandSet r
ds1 DemandSet r -> DemandSet r -> DemandSet r
forall (r :: Type -> Type).
OrdF r =>
DemandSet r -> DemandSet r -> DemandSet r
`demandSetDifference` DemandSet r
ds2
let d :: Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
d = (DemandSet (ArchReg arch)
-> DemandSet (ArchReg arch) -> Maybe (DemandSet (ArchReg arch)))
-> Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
forall k a b.
Ord k =>
(a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a
Map.differenceWith DemandSet (ArchReg arch)
-> DemandSet (ArchReg arch) -> Maybe (DemandSet (ArchReg arch))
forall (r :: Type -> Type).
OrdF r =>
DemandSet r -> DemandSet r -> Maybe (DemandSet r)
diff Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
demands' Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
seenDemands
if Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch)) -> Bool
forall k a. Map k a -> Bool
Map.null Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
d then
Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM
arch
ids
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM
arch
ids
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM
arch
ids
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$! Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
pendingMap
else do
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids)
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap ((Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Identity
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids
-> Identity (FunctionArgsState arch ids))
-> (Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= MemSegmentOff (ArchAddrWidth arch)
-> BlockDemands (ArchReg arch)
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert MemSegmentOff (ArchAddrWidth arch)
predAddr (BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type).
OrdF r =>
BlockDemands r -> BlockDemands r -> BlockDemands r
unionBlockDemands (Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> BlockDemands (ArchReg arch)
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
seenDemands) (Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> BlockDemands (ArchReg arch)
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
demands'))
Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM
arch
ids
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM
arch
ids
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM
arch
ids
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$! (BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch) -> BlockDemands (ArchReg arch))
-> MemSegmentOff (ArchAddrWidth arch)
-> BlockDemands (ArchReg arch)
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith BlockDemands (ArchReg arch)
-> BlockDemands (ArchReg arch) -> BlockDemands (ArchReg arch)
forall (r :: Type -> Type).
OrdF r =>
BlockDemands r -> BlockDemands r -> BlockDemands r
unionBlockDemands MemSegmentOff (ArchAddrWidth arch)
predAddr (Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> BlockDemands (ArchReg arch)
forall (r :: Type -> Type).
Map (DemandType r) (DemandSet r) -> BlockDemands r
BD Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
d) Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
pendingMap
calculateLocalFixpoint :: forall arch ids
. ( MemWidth (ArchAddrWidth arch)
, OrdF (ArchReg arch)
, ShowF (ArchReg arch)
)
=> PredBlockMap arch
-> Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids ()
calculateLocalFixpoint :: forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
PredBlockMap arch
-> Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids ()
calculateLocalFixpoint Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)]
predMap Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
xferMap Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
new =
case Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> Maybe
((MemSegmentOff (ArchAddrWidth arch), BlockDemands (ArchReg arch)),
Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall k a. Map k a -> Maybe ((k, a), Map k a)
Map.maxViewWithKey Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
new of
Maybe
((MemSegmentOff (ArchAddrWidth arch), BlockDemands (ArchReg arch)),
Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
Nothing -> () -> FunctionArgsM arch ids ()
forall a.
a
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
Just ((MemSegmentOff (ArchAddrWidth arch)
currAddr, BlockDemands (ArchReg arch)
newDemands), Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
rest) -> do
Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
next <- (Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> MemSegmentOff (ArchAddrWidth arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(Map
(MemSegmentOff (ArchAddrWidth arch))
(BlockDemands (ArchReg arch))))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> [MemSegmentOff (ArchAddrWidth arch)]
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM (Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> MemSegmentOff (ArchAddrWidth arch)
-> StateT
(FunctionArgsState arch ids)
(ReaderT
(FunArgContext arch)
(Except (FunctionArgAnalysisFailure (ArchAddrWidth arch))))
(Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch)))
forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> ArchSegmentOff arch
-> FunctionArgsM
arch ids (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
calculateOnePred Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
xferMap BlockDemands (ArchReg arch)
newDemands) Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
rest (Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)]
predMapMap
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)]
-> Getting
[MemSegmentOff (ArchAddrWidth arch)]
(Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)])
[MemSegmentOff (ArchAddrWidth arch)]
-> [MemSegmentOff (ArchAddrWidth arch)]
forall s a. s -> Getting a s a -> a
^.Index
(Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)])
-> Traversal'
(Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)])
(IxValue
(Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)]))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index
(Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)])
MemSegmentOff (ArchAddrWidth arch)
currAddr)
Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)]
-> Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
-> Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids ()
forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
PredBlockMap arch
-> Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids ()
calculateLocalFixpoint Map
(MemSegmentOff (ArchAddrWidth arch))
[MemSegmentOff (ArchAddrWidth arch)]
predMap Map
(MemSegmentOff (ArchAddrWidth arch))
(FinalRegisterDemands (ArchReg arch))
xferMap Map
(MemSegmentOff (ArchAddrWidth arch)) (BlockDemands (ArchReg arch))
next
type FunctionSummaryFailureMap r = Map (RegSegmentOff r) (FunctionArgAnalysisFailure (RegAddrWidth r))
data FunctionSummaries r = FunctionSummaries {
forall (r :: Type -> Type). FunctionSummaries r -> ArgDemandsMap r
_funArgMap :: !(ArgDemandsMap r)
, forall (r :: Type -> Type).
FunctionSummaries r
-> Map (RegSegmentOff r) (FinalRegisterDemands r)
_funResMap :: !(Map (RegSegmentOff r) (FinalRegisterDemands r))
, forall (r :: Type -> Type).
FunctionSummaries r -> Map (RegSegmentOff r) (DemandSet r)
_alwaysDemandMap :: !(Map (RegSegmentOff r) (DemandSet r))
, forall (r :: Type -> Type).
FunctionSummaries r -> FunctionSummaryFailureMap r
inferenceFails :: !(FunctionSummaryFailureMap r)
}
funArgMap :: Simple Lens (FunctionSummaries r) (ArgDemandsMap r)
funArgMap :: forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(ArgDemandsMap r -> f (ArgDemandsMap r))
-> FunctionSummaries r -> f (FunctionSummaries r)
funArgMap = (FunctionSummaries r
-> Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
-> (FunctionSummaries r
-> Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> FunctionSummaries r)
-> Lens
(FunctionSummaries r)
(FunctionSummaries r)
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens FunctionSummaries r
-> Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
forall (r :: Type -> Type). FunctionSummaries r -> ArgDemandsMap r
_funArgMap (\FunctionSummaries r
s Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
v -> FunctionSummaries r
s { _funArgMap = v })
funResMap :: Simple Lens (FunctionSummaries r) (Map (RegSegmentOff r) (FinalRegisterDemands r))
funResMap :: forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (FinalRegisterDemands r)
-> f (Map (RegSegmentOff r) (FinalRegisterDemands r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
funResMap = (FunctionSummaries r
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
-> (FunctionSummaries r
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
-> FunctionSummaries r)
-> Lens
(FunctionSummaries r)
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens FunctionSummaries r
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
forall (r :: Type -> Type).
FunctionSummaries r
-> Map (RegSegmentOff r) (FinalRegisterDemands r)
_funResMap (\FunctionSummaries r
s Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
v -> FunctionSummaries r
s { _funResMap = v })
alwaysDemandMap :: Simple Lens (FunctionSummaries r) (Map (RegSegmentOff r) (DemandSet r))
alwaysDemandMap :: forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (DemandSet r)
-> f (Map (RegSegmentOff r) (DemandSet r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
alwaysDemandMap = (FunctionSummaries r
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> (FunctionSummaries r
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> FunctionSummaries r)
-> Lens
(FunctionSummaries r)
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens FunctionSummaries r
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall (r :: Type -> Type).
FunctionSummaries r -> Map (RegSegmentOff r) (DemandSet r)
_alwaysDemandMap (\FunctionSummaries r
s Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
v -> FunctionSummaries r
s { _alwaysDemandMap = v })
decomposeMap :: OrdF r
=> RegisterSet r
-> RegSegmentOff r
-> FunctionSummaries r
-> DemandType r
-> DemandSet r
-> FunctionSummaries r
decomposeMap :: forall (r :: Type -> Type).
OrdF r =>
RegisterSet r
-> RegSegmentOff r
-> FunctionSummaries r
-> DemandType r
-> DemandSet r
-> FunctionSummaries r
decomposeMap RegisterSet r
_ MemSegmentOff (RegAddrWidth r)
addr FunctionSummaries r
acc (DemandFunctionArg MemSegmentOff (RegAddrWidth r)
f r tp
r) DemandSet r
v =
FunctionSummaries r
acc FunctionSummaries r
-> (FunctionSummaries r -> FunctionSummaries r)
-> FunctionSummaries r
forall a b. a -> (a -> b) -> b
& (ArgDemandsMap r -> Identity (ArgDemandsMap r))
-> FunctionSummaries r -> Identity (FunctionSummaries r)
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(ArgDemandsMap r -> f (ArgDemandsMap r))
-> FunctionSummaries r -> f (FunctionSummaries r)
funArgMap ((ArgDemandsMap r -> Identity (ArgDemandsMap r))
-> FunctionSummaries r -> Identity (FunctionSummaries r))
-> (ArgDemandsMap r -> ArgDemandsMap r)
-> FunctionSummaries r
-> FunctionSummaries r
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> (MemSegmentOff (RegAddrWidth r), Some r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> ArgDemandsMap r
-> ArgDemandsMap r
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith ((DemandSet r -> DemandSet r -> DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend) (MemSegmentOff (RegAddrWidth r)
f, r tp -> Some r
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some r tp
r) (MemSegmentOff (RegAddrWidth r)
-> DemandSet r
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a. k -> a -> Map k a
Map.singleton MemSegmentOff (RegAddrWidth r)
addr DemandSet r
v)
decomposeMap RegisterSet r
_ MemSegmentOff (RegAddrWidth r)
addr FunctionSummaries r
acc (DemandFunctionResult r tp
r) DemandSet r
v =
FunctionSummaries r
acc FunctionSummaries r
-> (FunctionSummaries r -> FunctionSummaries r)
-> FunctionSummaries r
forall a b. a -> (a -> b) -> b
& (Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
-> Identity
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)))
-> FunctionSummaries r -> Identity (FunctionSummaries r)
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (FinalRegisterDemands r)
-> f (Map (RegSegmentOff r) (FinalRegisterDemands r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
funResMap ((Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
-> Identity
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)))
-> FunctionSummaries r -> Identity (FunctionSummaries r))
-> (Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
-> FunctionSummaries r
-> FunctionSummaries r
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (FinalRegisterDemands r
-> FinalRegisterDemands r -> FinalRegisterDemands r)
-> MemSegmentOff (RegAddrWidth r)
-> FinalRegisterDemands r
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith FinalRegisterDemands r
-> FinalRegisterDemands r -> FinalRegisterDemands r
forall a. Monoid a => a -> a -> a
mappend MemSegmentOff (RegAddrWidth r)
addr (Map (Some r) (DemandSet r) -> FinalRegisterDemands r
forall (r :: Type -> Type).
Map (Some r) (DemandSet r) -> FinalRegisterDemands r
FRD (Some r -> DemandSet r -> Map (Some r) (DemandSet r)
forall k a. k -> a -> Map k a
Map.singleton (r tp -> Some r
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some r tp
r) DemandSet r
v))
decomposeMap RegisterSet r
ds MemSegmentOff (RegAddrWidth r)
addr FunctionSummaries r
acc DemandType r
DemandAlways DemandSet r
v =
let v' :: DemandSet r
v' = DemandSet r
v { registerDemands = registerDemands v `Set.difference` ds }
in FunctionSummaries r
acc FunctionSummaries r
-> (FunctionSummaries r -> FunctionSummaries r)
-> FunctionSummaries r
forall a b. a -> (a -> b) -> b
& (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Identity (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
-> FunctionSummaries r -> Identity (FunctionSummaries r)
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (DemandSet r)
-> f (Map (RegSegmentOff r) (DemandSet r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
alwaysDemandMap ((Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Identity (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
-> FunctionSummaries r -> Identity (FunctionSummaries r))
-> (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> FunctionSummaries r
-> FunctionSummaries r
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (DemandSet r -> DemandSet r -> DemandSet r)
-> MemSegmentOff (RegAddrWidth r)
-> DemandSet r
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend MemSegmentOff (RegAddrWidth r)
addr DemandSet r
v'
recordInferredFunctionDemands :: ArchConstraints arch
=> ArchDemandInfo arch
-> ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
recordInferredFunctionDemands :: forall arch.
ArchConstraints arch =>
ArchDemandInfo arch
-> ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
recordInferredFunctionDemands ArchDemandInfo arch
ainfo ArchSegmentOff arch
fnAddr (BD Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
fnDemands) FunctionSummaries (ArchReg arch)
globalState =
let spuriousDemands :: Set (Some (ArchReg arch))
spuriousDemands = Some (ArchReg arch)
-> Set (Some (ArchReg arch)) -> Set (Some (ArchReg arch))
forall a. Ord a => a -> Set a -> Set a
Set.insert (ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Some (ArchReg arch)
forall k (f :: k -> Type) (x :: k). f x -> Some f
Some ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
sp_reg) (ArchDemandInfo arch -> Set (Some (ArchReg arch))
forall arch. ArchDemandInfo arch -> Set (Some (ArchReg arch))
calleeSavedRegs ArchDemandInfo arch
ainfo)
in (FunctionSummaries (ArchReg arch)
-> DemandType (ArchReg arch)
-> DemandSet (ArchReg arch)
-> FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
-> Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
forall a k b. (a -> k -> b -> a) -> a -> Map k b -> a
Map.foldlWithKey' (Set (Some (ArchReg arch))
-> ArchSegmentOff arch
-> FunctionSummaries (ArchReg arch)
-> DemandType (ArchReg arch)
-> DemandSet (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
forall (r :: Type -> Type).
OrdF r =>
RegisterSet r
-> RegSegmentOff r
-> FunctionSummaries r
-> DemandType r
-> DemandSet r
-> FunctionSummaries r
decomposeMap Set (Some (ArchReg arch))
spuriousDemands ArchSegmentOff arch
fnAddr) FunctionSummaries (ArchReg arch)
globalState Map (DemandType (ArchReg arch)) (DemandSet (ArchReg arch))
fnDemands
summarizeFunction :: forall arch
. ArchConstraints arch
=> FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> Some (DiscoveryFunInfo arch)
-> FunctionSummaries (ArchReg arch)
summarizeFunction :: forall arch.
ArchConstraints arch =>
FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> Some (DiscoveryFunInfo arch)
-> FunctionSummaries (ArchReg arch)
summarizeFunction FunArgContext arch
ctx FunctionSummaries (ArchReg arch)
acc (Some DiscoveryFunInfo arch x
finfo) = do
let addr :: MemSegmentOff (RegAddrWidth (ArchReg arch))
addr = DiscoveryFunInfo arch x
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall arch ids. DiscoveryFunInfo arch ids -> ArchSegmentOff arch
discoveredFunAddr DiscoveryFunInfo arch x
finfo
FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> FunctionArgsM arch x (FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
forall arch ids.
FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> ArchSegmentOff arch
-> FunctionArgsM arch ids (FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
evalFunctionArgsM FunArgContext arch
ctx FunctionSummaries (ArchReg arch)
acc MemSegmentOff (RegAddrWidth (ArchReg arch))
addr (FunctionArgsM arch x (FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch))
-> FunctionArgsM arch x (FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
forall a b. (a -> b) -> a -> b
$ do
Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch))
xferMap <- (ParsedBlock arch x
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(FinalRegisterDemands (ArchReg arch)))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) (ParsedBlock arch x)
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch)))
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b)
-> Map (MemSegmentOff (RegAddrWidth (ArchReg arch))) a
-> f (Map (MemSegmentOff (RegAddrWidth (ArchReg arch))) b)
traverse ParsedBlock arch x
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(FinalRegisterDemands (ArchReg arch))
forall arch ids.
ArchConstraints arch =>
ParsedBlock arch ids
-> FunctionArgsM arch ids (FinalRegisterDemands (ArchReg arch))
summarizeBlock (DiscoveryFunInfo arch x
finfoDiscoveryFunInfo arch x
-> Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) (ParsedBlock arch x))
(DiscoveryFunInfo arch x)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) (ParsedBlock arch x))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) (ParsedBlock arch x)
forall s a. s -> Getting a s a -> a
^.Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) (ParsedBlock arch x))
(DiscoveryFunInfo arch x)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) (ParsedBlock arch x))
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (ParsedBlock arch ids)
-> f (Map (ArchSegmentOff arch) (ParsedBlock arch ids)))
-> DiscoveryFunInfo arch ids -> f (DiscoveryFunInfo arch ids)
parsedBlocks)
Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
new <- Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(FunctionArgsState arch x)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use Getting
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(FunctionArgsState arch x)
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap
PredBlockMap arch
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
()
forall arch ids.
(MemWidth (ArchAddrWidth arch), OrdF (ArchReg arch),
ShowF (ArchReg arch)) =>
PredBlockMap arch
-> Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> FunctionArgsM arch ids ()
calculateLocalFixpoint (DiscoveryFunInfo arch x -> PredBlockMap arch
forall arch ids. DiscoveryFunInfo arch ids -> PredBlockMap arch
predBlockMap DiscoveryFunInfo arch x
finfo) Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch))
xferMap Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
new
BlockDemands (ArchReg arch)
entryDemands <- Getting
(BlockDemands (ArchReg arch))
(FunctionArgsState arch x)
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use (Getting
(BlockDemands (ArchReg arch))
(FunctionArgsState arch x)
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch)))
-> Getting
(BlockDemands (ArchReg arch))
(FunctionArgsState arch x)
(BlockDemands (ArchReg arch))
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
(BlockDemands (ArchReg arch))
forall a b. (a -> b) -> a -> b
$ (Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Const
(BlockDemands (ArchReg arch))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch x
-> Const (BlockDemands (ArchReg arch)) (FunctionArgsState arch x)
forall arch ids (f :: Type -> Type).
Functor f =>
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-> f (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))))
-> FunctionArgsState arch ids -> f (FunctionArgsState arch ids)
blockDemandMap ((Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Const
(BlockDemands (ArchReg arch))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> FunctionArgsState arch x
-> Const (BlockDemands (ArchReg arch)) (FunctionArgsState arch x))
-> ((BlockDemands (ArchReg arch)
-> Const
(BlockDemands (ArchReg arch)) (BlockDemands (ArchReg arch)))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))
-> Const
(BlockDemands (ArchReg arch))
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
-> Getting
(BlockDemands (ArchReg arch))
(FunctionArgsState arch x)
(BlockDemands (ArchReg arch))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
-> Traversal'
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
(IxValue
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch))))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index
(Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(BlockDemands (ArchReg arch)))
MemSegmentOff (RegAddrWidth (ArchReg arch))
addr
FunctionSummaries (ArchReg arch)
-> FunctionArgsM arch x (FunctionSummaries (ArchReg arch))
forall a.
a
-> StateT
(FunctionArgsState arch x)
(ReaderT
(FunArgContext arch)
(Except
(FunctionArgAnalysisFailure (RegAddrWidth (ArchReg arch)))))
a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (FunctionSummaries (ArchReg arch)
-> FunctionArgsM arch x (FunctionSummaries (ArchReg arch)))
-> FunctionSummaries (ArchReg arch)
-> FunctionArgsM arch x (FunctionSummaries (ArchReg arch))
forall a b. (a -> b) -> a -> b
$! ArchDemandInfo arch
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockDemands (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
forall arch.
ArchConstraints arch =>
ArchDemandInfo arch
-> ArchSegmentOff arch
-> BlockDemands (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
-> FunctionSummaries (ArchReg arch)
recordInferredFunctionDemands (FunArgContext arch -> ArchDemandInfo arch
forall arch. FunArgContext arch -> ArchDemandInfo arch
archDemandInfo FunArgContext arch
ctx) MemSegmentOff (RegAddrWidth (ArchReg arch))
addr BlockDemands (ArchReg arch)
entryDemands FunctionSummaries (ArchReg arch)
acc
postRegisterSetDemandsAtAddr :: OrdF r
=> Map (RegSegmentOff r) (FinalRegisterDemands r)
-> RegSegmentOff r
-> Set (Some r)
-> DemandSet r
postRegisterSetDemandsAtAddr :: forall (r :: Type -> Type).
OrdF r =>
Map (RegSegmentOff r) (FinalRegisterDemands r)
-> RegSegmentOff r -> Set (Some r) -> DemandSet r
postRegisterSetDemandsAtAddr Map (RegSegmentOff r) (FinalRegisterDemands r)
m RegSegmentOff r
addr Set (Some r)
retRegs =
(Some r -> DemandSet r) -> Set (Some r) -> DemandSet r
forall m a. Monoid m => (a -> m) -> Set a -> m
forall (t :: Type -> Type) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\(Some r x
r) -> FinalRegisterDemands r -> r x -> DemandSet r
forall (r :: Type -> Type) (tp :: Type).
OrdF r =>
FinalRegisterDemands r -> r tp -> DemandSet r
postRegisterDemands (Map (RegSegmentOff r) (FinalRegisterDemands r)
mMap (RegSegmentOff r) (FinalRegisterDemands r)
-> Getting
(FinalRegisterDemands r)
(Map (RegSegmentOff r) (FinalRegisterDemands r))
(FinalRegisterDemands r)
-> FinalRegisterDemands r
forall s a. s -> Getting a s a -> a
^.Index (Map (RegSegmentOff r) (FinalRegisterDemands r))
-> Traversal'
(Map (RegSegmentOff r) (FinalRegisterDemands r))
(IxValue (Map (RegSegmentOff r) (FinalRegisterDemands r)))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map (RegSegmentOff r) (FinalRegisterDemands r))
RegSegmentOff r
addr) r x
r) Set (Some r)
retRegs
calculateGlobalFixpoint :: forall r
. OrdF r
=> FunctionSummaries r
-> AddrDemandMap r
calculateGlobalFixpoint :: forall (r :: Type -> Type).
OrdF r =>
FunctionSummaries r -> AddrDemandMap r
calculateGlobalFixpoint FunctionSummaries r
s = Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
go (FunctionSummaries r
sFunctionSummaries r
-> Getting
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall s a. s -> Getting a s a -> a
^.Getting
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (DemandSet r)
-> f (Map (RegSegmentOff r) (DemandSet r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
alwaysDemandMap) (FunctionSummaries r
sFunctionSummaries r
-> Getting
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall s a. s -> Getting a s a -> a
^.Getting
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (DemandSet r)
-> f (Map (RegSegmentOff r) (DemandSet r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
alwaysDemandMap)
where
argDemandsMap :: Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
argDemandsMap = FunctionSummaries r
sFunctionSummaries r
-> Getting
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
(FunctionSummaries r)
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
-> Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
forall s a. s -> Getting a s a -> a
^.Getting
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
(FunctionSummaries r)
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(ArgDemandsMap r -> f (ArgDemandsMap r))
-> FunctionSummaries r -> f (FunctionSummaries r)
funArgMap
go :: AddrDemandMap r
-> AddrDemandMap r
-> AddrDemandMap r
go :: Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
go Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
new
| Just ((MemSegmentOff (RegAddrWidth r)
fun, DemandSet r
newDemands), Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
rest) <- Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Maybe
((MemSegmentOff (RegAddrWidth r), DemandSet r),
Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
forall k a. Map k a -> Maybe ((k, a), Map k a)
Map.maxViewWithKey Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
new =
let (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
nexts, Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc') = Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> MemSegmentOff (RegAddrWidth r)
-> DemandSet r
-> (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r),
Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
backPropagate Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc MemSegmentOff (RegAddrWidth r)
fun DemandSet r
newDemands
in Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
go Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc' ((DemandSet r -> DemandSet r -> DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
rest Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
nexts)
| Bool
otherwise = Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc
backPropagate :: AddrDemandMap r
-> RegSegmentOff r
-> DemandSet r
-> (AddrDemandMap r, AddrDemandMap r)
backPropagate :: Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> MemSegmentOff (RegAddrWidth r)
-> DemandSet r
-> (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r),
Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
backPropagate Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc MemSegmentOff (RegAddrWidth r)
fun (DemandSet RegisterSet r
regs Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
rets) =
let retDemands :: AddrDemandMap r
retDemands :: Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
retDemands = (MemSegmentOff (RegAddrWidth r) -> RegisterSet r -> DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a b. (k -> a -> b) -> Map k a -> Map k b
Map.mapWithKey (Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
-> MemSegmentOff (RegAddrWidth r) -> RegisterSet r -> DemandSet r
forall (r :: Type -> Type).
OrdF r =>
Map (RegSegmentOff r) (FinalRegisterDemands r)
-> RegSegmentOff r -> Set (Some r) -> DemandSet r
postRegisterSetDemandsAtAddr (FunctionSummaries r
sFunctionSummaries r
-> Getting
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
-> Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r)
forall s a. s -> Getting a s a -> a
^.Getting
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
(FunctionSummaries r)
(Map (MemSegmentOff (RegAddrWidth r)) (FinalRegisterDemands r))
forall (r :: Type -> Type) (f :: Type -> Type).
Functor f =>
(Map (RegSegmentOff r) (FinalRegisterDemands r)
-> f (Map (RegSegmentOff r) (FinalRegisterDemands r)))
-> FunctionSummaries r -> f (FunctionSummaries r)
funResMap)) Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)
rets
regsDemands :: AddrDemandMap r
regsDemands :: Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
regsDemands =
(DemandSet r -> DemandSet r -> DemandSet r)
-> [Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)]
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall (f :: Type -> Type) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
Map.unionsWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend [ Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
argDemandsMap Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> Getting
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall s a. s -> Getting a s a -> a
^. Index
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
-> Traversal'
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)))
(IxValue
(Map
(MemSegmentOff (RegAddrWidth r), Some r)
(Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r))))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix (MemSegmentOff (RegAddrWidth r)
fun, Some r
r) | Some r
r <- RegisterSet r -> [Some r]
forall a. Set a -> [a]
Set.toList RegisterSet r
regs ]
newDemands :: Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
newDemands = (DemandSet r -> DemandSet r -> DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
regsDemands Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
retDemands
novelDemands :: Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
novelDemands = (DemandSet r -> DemandSet r -> Maybe (DemandSet r))
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a b.
Ord k =>
(a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a
Map.differenceWith DemandSet r -> DemandSet r -> Maybe (DemandSet r)
forall (r :: Type -> Type).
OrdF r =>
DemandSet r -> DemandSet r -> Maybe (DemandSet r)
diff Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
newDemands Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc
in (Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
novelDemands, (DemandSet r -> DemandSet r -> DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
-> Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith DemandSet r -> DemandSet r -> DemandSet r
forall a. Monoid a => a -> a -> a
mappend Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
acc Map (MemSegmentOff (RegAddrWidth r)) (DemandSet r)
novelDemands )
diff :: DemandSet r -> DemandSet r -> Maybe (DemandSet r)
diff DemandSet r
ds1 DemandSet r
ds2 =
let ds' :: DemandSet r
ds' = DemandSet r
ds1 DemandSet r -> DemandSet r -> DemandSet r
forall (r :: Type -> Type).
OrdF r =>
DemandSet r -> DemandSet r -> DemandSet r
`demandSetDifference` DemandSet r
ds2 in
if DemandSet r
ds' DemandSet r -> DemandSet r -> Bool
forall a. Eq a => a -> a -> Bool
== DemandSet r
forall a. Monoid a => a
mempty then Maybe (DemandSet r)
forall a. Maybe a
Nothing else DemandSet r -> Maybe (DemandSet r)
forall a. a -> Maybe a
Just DemandSet r
ds'
functionDemands :: forall arch
. ArchConstraints arch
=> ArchDemandInfo arch
-> Memory (ArchAddrWidth arch)
-> ResolveCallArgsFn arch
-> [Some (DiscoveryFunInfo arch)]
-> (AddrDemandMap (ArchReg arch), FunctionSummaryFailureMap (ArchReg arch))
functionDemands :: forall arch.
ArchConstraints arch =>
ArchDemandInfo arch
-> Memory (ArchAddrWidth arch)
-> ResolveCallArgsFn arch
-> [Some (DiscoveryFunInfo arch)]
-> (AddrDemandMap (ArchReg arch),
FunctionSummaryFailureMap (ArchReg arch))
functionDemands ArchDemandInfo arch
archFns Memory (RegAddrWidth (ArchReg arch))
mem ResolveCallArgsFn arch
resolveCallFn [Some (DiscoveryFunInfo arch)]
entries = do
let m0 :: FunctionSummaries (ArchReg arch)
m0 :: FunctionSummaries (ArchReg arch)
m0 = FunctionSummaries
{ _funArgMap :: ArgDemandsMap (ArchReg arch)
_funArgMap = ArgDemandsMap (ArchReg arch)
forall k a. Map k a
Map.empty
, _funResMap :: Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch))
_funResMap = Map
(MemSegmentOff (RegAddrWidth (ArchReg arch)))
(FinalRegisterDemands (ArchReg arch))
forall k a. Map k a
Map.empty
, _alwaysDemandMap :: AddrDemandMap (ArchReg arch)
_alwaysDemandMap = AddrDemandMap (ArchReg arch)
forall k a. Map k a
Map.empty
, inferenceFails :: FunctionSummaryFailureMap (ArchReg arch)
inferenceFails = FunctionSummaryFailureMap (ArchReg arch)
forall k a. Map k a
Map.empty
}
let compAddrSet :: Set (MemSegmentOff (RegAddrWidth (ArchReg arch)))
compAddrSet = [MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> Set (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a. Ord a => [a] -> Set a
Set.fromList ([MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> Set (MemSegmentOff (RegAddrWidth (ArchReg arch))))
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
-> Set (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ (forall tp.
DiscoveryFunInfo arch tp
-> MemSegmentOff (RegAddrWidth (ArchReg arch)))
-> Some (DiscoveryFunInfo arch)
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall {k} (f :: k -> Type) r.
(forall (tp :: k). f tp -> r) -> Some f -> r
viewSome DiscoveryFunInfo arch tp
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall tp.
DiscoveryFunInfo arch tp
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall arch ids. DiscoveryFunInfo arch ids -> ArchSegmentOff arch
discoveredFunAddr (Some (DiscoveryFunInfo arch)
-> MemSegmentOff (RegAddrWidth (ArchReg arch)))
-> [Some (DiscoveryFunInfo arch)]
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [Some (DiscoveryFunInfo arch)]
entries
let ctx :: FunArgContext arch
ctx = FAC { archDemandInfo :: ArchDemandInfo arch
archDemandInfo = ArchDemandInfo arch
archFns
, ctxMemory :: Memory (RegAddrWidth (ArchReg arch))
ctxMemory = Memory (RegAddrWidth (ArchReg arch))
mem
, computedAddrSet :: Set (MemSegmentOff (RegAddrWidth (ArchReg arch)))
computedAddrSet = Set (MemSegmentOff (RegAddrWidth (ArchReg arch)))
compAddrSet
, resolveCallArgs :: ResolveCallArgsFn arch
resolveCallArgs = MemSegmentOff (RegAddrWidth (ArchReg arch))
-> RegState (ArchReg arch) (Value arch ids)
-> Either String [Some (Value arch ids)]
ResolveCallArgsFn arch
resolveCallFn
}
let summaries :: FunctionSummaries (ArchReg arch)
summaries = (FunctionSummaries (ArchReg arch)
-> Some (DiscoveryFunInfo arch)
-> FunctionSummaries (ArchReg arch))
-> FunctionSummaries (ArchReg arch)
-> [Some (DiscoveryFunInfo arch)]
-> FunctionSummaries (ArchReg arch)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> Some (DiscoveryFunInfo arch)
-> FunctionSummaries (ArchReg arch)
forall arch.
ArchConstraints arch =>
FunArgContext arch
-> FunctionSummaries (ArchReg arch)
-> Some (DiscoveryFunInfo arch)
-> FunctionSummaries (ArchReg arch)
summarizeFunction FunArgContext arch
ctx) FunctionSummaries (ArchReg arch)
m0 [Some (DiscoveryFunInfo arch)]
entries
(FunctionSummaries (ArchReg arch) -> AddrDemandMap (ArchReg arch)
forall (r :: Type -> Type).
OrdF r =>
FunctionSummaries r -> AddrDemandMap r
calculateGlobalFixpoint FunctionSummaries (ArchReg arch)
summaries, FunctionSummaries (ArchReg arch)
-> FunctionSummaryFailureMap (ArchReg arch)
forall (r :: Type -> Type).
FunctionSummaries r -> FunctionSummaryFailureMap r
inferenceFails FunctionSummaries (ArchReg arch)
summaries)