module LinearScan
(
allocate
, BlockInfo(..)
, OpInfo(..)
, OpKind(..)
, VarInfo(..)
, VarKind(..)
, PhysReg
) where
import qualified LinearScan.Main as LS
import LinearScan.Main
( VarKind(..)
, OpKind(..)
, PhysReg
)
data VarInfo v = VarInfo
{ varId :: v -> Int
, varKind :: v -> VarKind
, regRequired :: v -> Bool
}
deriving instance Eq VarKind
deriving instance Show VarKind
fromVarInfo :: VarInfo v -> LS.VarInfo v
fromVarInfo (VarInfo a b c) = LS.Build_VarInfo a b c
data OpInfo accType o v a b = OpInfo
{ opKind :: o a -> OpKind
, opRefs :: o a -> ([v], [PhysReg])
, saveOp :: Int -> PhysReg -> accType -> (o b, accType)
, restoreOp :: Int -> PhysReg -> accType -> (o b, accType)
, applyAllocs :: o a -> [(Int, PhysReg)] -> o b
}
deriving instance Eq OpKind
deriving instance Show OpKind
fromOpInfo :: OpInfo accType o v a b -> LS.OpInfo accType (o a) (o b) v
fromOpInfo (OpInfo a b c d e) = LS.Build_OpInfo a b c d e
data BlockInfo blk o a b = BlockInfo
{ blockId :: blk a -> Int
, blockSuccessors :: blk a -> [Int]
, blockOps :: blk a -> [o a]
, setBlockOps :: blk a -> [o b] -> blk b
}
fromBlockInfo :: BlockInfo blk o a b -> LS.BlockInfo (blk a) (blk b) (o a) (o b)
fromBlockInfo (BlockInfo a b c d) = LS.Build_BlockInfo a b c d
allocate :: BlockInfo blk o a b -> OpInfo accType o v a b -> VarInfo v
-> [blk a] -> accType -> Either String ([blk b], accType)
allocate _ _ _ [] _ = Left "No basic blocks were provided"
allocate (fromBlockInfo -> binfo) (fromOpInfo -> oinfo)
(fromVarInfo -> vinfo) blocks acc =
case LS.linearScan binfo oinfo vinfo blocks acc of
Left x -> Left $ case x of
LS.ECannotSplitSingleton n ->
"Current interval is a singleton (" ++ show n ++ ")"
LS.ECannotSplitAssignedSingleton n ->
"Current interval is an assigned singleton (" ++ show n ++ ")"
LS.ENoIntervalsToSplit ->
"There are no intervals to split"
LS.ERegisterAlreadyAssigned n ->
"Register is already assigned (" ++ show n ++ ")"
LS.ERegisterAssignmentsOverlap n ->
"Register assignments overlap (" ++ show n ++ ")"
LS.EFuelExhausted -> "Fuel was exhausted"
LS.EUnexpectedNoMoreUnhandled ->
"The unexpected happened: no more unhandled intervals"
Right z -> Right z