module Camfort.Transformation.DeadCode where
import Camfort.Analysis.Annotations
import Camfort.Analysis.LVA
import Camfort.Analysis.Syntax
import Camfort.Transformation.Syntax
import Camfort.Traverse
import Language.Fortran
import Camfort.Helpers
import Generics.Deriving.Copoint
import GHC.Generics
import Debug.Trace
import Data.Generics.Uniplate.Operations
deadCode :: Bool -> (Filename, Program Annotation) -> (Report, (Filename, Program Annotation))
deadCode flag (fname, p) =
let (r, p') = mapM ((transformBi elimEmptyFseq) . transformBiM (elimDead flag)) (lva p)
in if r == "" then (r, (fname, p'))
else (r, (fname, p')) >>= (deadCode flag)
elimEmptyFseq :: Fortran Annotation -> Fortran Annotation
elimEmptyFseq (FSeq _ _ (NullStmt _ _) n2@(NullStmt _ _)) = n2
elimEmptyFseq f = f
elimDead :: Bool -> Fortran Annotation -> (Report, Fortran Annotation)
elimDead flag x@(Assg a sp@(s1, s2) e1 e2) | (pRefactored a) == flag =
let lOut = liveOut a
in if ((varExprToAccesses e1) == []) || ((head $ varExprToAccesses e1) `elem` lOut) then
return x
else let report = "o" ++ (show . srcLineCol $ s1) ++ ": removed dead code\n"
in (report, NullStmt (a { refactored = (Just s1) }) (dropLine sp))
elimDead _ x = return x