module ReplaceRefs (replaceRef, replaceRefsIns, replaceRefsTerm, replaceRefsBB, replaceRefsBBList, findAllRefs, findAllRefsInss, findAllRefsIns, findAllRefsTerm, findAllRefsBBList) where import Data.List import Intermediate import Utils replaceRef :: Ref -> Ref -> Ref -> Ref replaceRef = trans replaceRefsIns :: Ref -> Ref -> IRIns -> IRIns replaceRefsIns from to (IMov a b) = IMov (trans from to a) (trans from to b) replaceRefsIns from to (ILea a n) = ILea (trans from to a) n replaceRefsIns from to (IStore a b) = IStore (trans from to a) (trans from to b) replaceRefsIns from to (ILoad a b) = ILoad (trans from to a) (trans from to b) replaceRefsIns from to (ISet a n b) = ISet (trans from to a) n (trans from to b) replaceRefsIns from to (IGet a b n) = IGet (trans from to a) (trans from to b) n replaceRefsIns from to (IAri at a b c) = IAri at (trans from to a) (trans from to b) (trans from to c) replaceRefsIns from to (ICall n al) = ICall n (map (trans from to) al) replaceRefsIns from to (ICallr a n al) = ICallr (trans from to a) n (map (trans from to) al) replaceRefsIns from to (IResize a b) = IResize (trans from to a) (trans from to b) replaceRefsIns _ _ IDebugger = IDebugger replaceRefsIns _ _ INop = INop replaceRefsTerm :: Ref -> Ref -> IRTerm -> IRTerm replaceRefsTerm from to (IJcc ct a b i1 i2) = IJcc ct (trans from to a) (trans from to b) i1 i2 replaceRefsTerm _ _ (IJmp i) = IJmp i replaceRefsTerm _ _ IRet = IRet replaceRefsTerm from to (IRetr a) = IRetr (trans from to a) replaceRefsTerm _ _ IUnreachable = IUnreachable replaceRefsTerm _ _ ITermNone = ITermNone replaceRefsBB :: Ref -> Ref -> BB -> BB replaceRefsBB from to (BB bid inss term) = BB bid (map (replaceRefsIns from to) inss) (replaceRefsTerm from to term) replaceRefsBBList :: Ref -> Ref -> [BB] -> [BB] replaceRefsBBList from to bbs = map (\bb -> replaceRefsBB from to bb) bbs trans :: Ref -> Ref -> Ref -> Ref trans from to ref | ref == from = to | otherwise = ref findAllRefs :: BB -> [Ref] findAllRefs (BB _ inss _) = findAllRefsInss inss findAllRefsInss :: [IRIns] -> [Ref] findAllRefsInss inss = uniq $ sort $ concatMap findAllRefsIns inss findAllRefsIns :: IRIns -> [Ref] findAllRefsIns (IMov a b) = [a, b] findAllRefsIns (ILea a _) = [a] findAllRefsIns (IStore a b) = [a, b] findAllRefsIns (ILoad a b) = [a, b] findAllRefsIns (ISet a _ b) = [a, b] findAllRefsIns (IGet a b _) = [a, b] findAllRefsIns (IAri _ a b c) = [a, b, c] findAllRefsIns (ICall _ al) = al findAllRefsIns (ICallr a _ al) = a : al findAllRefsIns (IResize a b) = [a, b] findAllRefsIns IDebugger = [] findAllRefsIns INop = [] findAllRefsTerm :: IRTerm -> [Ref] findAllRefsTerm (IJcc _ a b _ _) = [a, b] findAllRefsTerm (IJmp _) = [] findAllRefsTerm IRet = [] findAllRefsTerm (IRetr a) = [a] findAllRefsTerm IUnreachable = [] findAllRefsTerm ITermNone = undefined findAllRefsBBList :: [BB] -> [Ref] findAllRefsBBList = uniq . sort . concatMap findAllRefs