{-# LANGUAGE GADTs #-} {-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-} module Compiler.Hoopl.Passes.DList ( Doms, domEntry, domLattice , domPass ) where import Compiler.Hoopl type Doms = WithBot [Label] -- ^ List of labels, extended with a standard bottom element -- | The fact that goes into the entry of a dominator analysis: the first node -- is dominated only by the entry point, which is represented by the empty list -- of labels. 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] -- longest common suffix 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 -- | Dominator pass domPass :: (NonLocal n, Monad m) => FwdPass m n Doms domPass = FwdPass domLattice (mkFTransfer3 first (const id) distributeFact) noFwdRewrite where first n = fmap (entryLabel n:)