{- Copyright 2016, Dominic Orchard, Andrew Rice, Mistral Contrastin, Matthew Danish Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} module Camfort.Transformation.DataTypeIntroduction where import qualified Language.Fortran.AST as F import qualified Language.Fortran.Analysis as FA import qualified Language.Fortran.Analysis.DataFlow as FAD import qualified Language.Fortran.Analysis.Renaming as FAR import qualified Language.Fortran.Analysis.BBlocks as FAB import qualified Language.Fortran.Analysis.Types as FAT import qualified Language.Fortran.Util.Position as FU import qualified Language.Fortran.ParserMonad as PM import qualified Language.Fortran.PrettyPrint as PP import qualified Data.Graph.Inductive.PatriciaTree as G import qualified Data.Graph.Inductive.Graph as IGr import qualified Data.Map.Lazy as M import Data.Generics.Uniplate.Operations import qualified Data.Set as S import Control.Monad.State.Lazy import Camfort.Helpers import Camfort.Helpers.Syntax import Camfort.Analysis.Annotations import qualified Data.IntMap as IM -- Array-subscript interference graphs, in a map from -- the array variable to the interference graph type IGraphs = M.Map F.Name (G.Gr F.Name Int) -- Top-level dataTypeIntro :: [(Filename, F.ProgramFile A)] -> (Report, [(Filename, F.ProgramFile A)]) dataTypeIntro pfs = (r, []) where r = buildInterferenceGraph pfs -- Stub, coalesce LVA information -- TODO, build interference graph buildInterferenceGraph :: [(Filename, F.ProgramFile A)] -> String buildInterferenceGraph = show . (foldr IM.union IM.empty) . map analysePerPF -- Stub, generate LVA information analysePerPF :: (Filename, F.ProgramFile A) -> FAD.InOutMap (S.Set F.Name) analysePerPF (fname, pf) = undefined where -- (report, pf'') = transformBiM (perStmt lva) pf -- initialise analysis pf' = FAB.analyseBBlocks . FAR.analyseRenames . FA.initAnalysis $ pf -- get map of program unit ==> basic block graph bbm = FAB.genBBlockMap pf' -- build the supergraph of global dependency sgr = FAB.genSuperBBGr bbm -- extract the supergraph itself gr = FAB.superBBGrGraph sgr -- live variables lva = FAD.liveVariableAnalysis gr -- Core of the transformation happens here on assignment statements --perStmt :: FAD.InOutMap -> S.Set F.Name -- -> F.Statement (FA.Analysis A) -> State IGraphs (F.Statement (FA.Analysis A)) perStmt lva x = case (FA.insLabel (F.getAnnotation x)) of Just label -> case (IM.lookup label lva) of Just (lva_in, _) -> undefined -- transformBiM (perStmt lva_in) x {- perExpr :: FAD.InOutMap (S.Set F.Name) -> F.Expression (FA.Analysis A) -> State IGraphs (F.Expression (FA.Analysis A)) perExpr lva_in x@(F.ExpSubscript _ _ (F.ExpValue _ _ (F.ValVariable arrVar)) subs) = do let subscript_vars = [v | (F.ValVariable v) <- universeBi (F.aStrip subs) ] let intefering = [(v, w) | v <- subscript_vars, w <- subscript_vars, v `S.member` lva_in && w `S.member` lva_in] igraphs <- get case (M.lookup arrVar igraphs) of Just igraph -> return x -- TODO: update graph here Nothing -> do let g0 = IGr.mkGraph undefined -- [(0, u),(1, v)] [(0, 1, ())] let m = M.fromList [(arrVar, g0)] put (m `M.union` igraphs) return x perExpr _ x = return x -}