module Compiler.Hoopl.Passes.DList
( Doms, domEntry, domLattice
, domPass
)
where
import Compiler.Hoopl
type Doms = WithBot [Label]
domEntry :: Doms
domEntry = PElem []
domLattice :: DataflowLattice Doms
domLattice = addPoints "dominators" extend
extend :: JoinFun [Label]
extend _ (OldFact l) (NewFact l') = (changeIf (l `lengthDiffers` j), j)
where j = lcs l l'
lcs :: [Label] -> [Label] -> [Label]
lcs l l' | length l > length l' = lcs (drop (length l length l') l) l'
| length l < length l' = lcs l' l
| otherwise = dropUnlike l l' l
dropUnlike [] [] maybe_like = maybe_like
dropUnlike (x:xs) (y:ys) maybe_like =
dropUnlike xs ys (if x == y then maybe_like else xs)
dropUnlike _ _ _ = error "this can't happen"
lengthDiffers [] [] = False
lengthDiffers (_:xs) (_:ys) = lengthDiffers xs ys
lengthDiffers [] (_:_) = True
lengthDiffers (_:_) [] = True
domPass :: (NonLocal n, Monad m) => FwdPass m n Doms
domPass = FwdPass domLattice (mkFTransfer3 first (const id) distributeFact) noFwdRewrite
where first n = fmap (entryLabel n:)