Skip to content

Commit 7b67b51

Browse files
committed
Analysis: use Repr.FValue for constant folding
1 parent 562d41c commit 7b67b51

File tree

3 files changed

+20
-54
lines changed

3 files changed

+20
-54
lines changed

src/Language/Fortran/Analysis.hs

+4-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
-- |
44
-- Common data structures and functions supporting analysis of the AST.
55
module Language.Fortran.Analysis
6-
( initAnalysis, stripAnalysis, Analysis(..), Constant(..)
6+
( initAnalysis, stripAnalysis, Analysis(..)
77
, varName, srcName, lvVarName, lvSrcName, isNamedExpression
88
, genVar, puName, puSrcName, blockRhsExprs, rhsExprs
99
, ModEnv, NameType(..), IDType(..), ConstructType(..)
@@ -31,6 +31,8 @@ import Data.Bifunctor (first)
3131

3232
import Language.Fortran.Analysis.SemanticTypes (SemType(..))
3333

34+
import Language.Fortran.Repr
35+
3436
--------------------------------------------------
3537

3638
-- | Basic block
@@ -105,18 +107,6 @@ data IDType = IDType
105107
instance Out IDType
106108
instance Binary IDType
107109

108-
-- | Information about potential / actual constant expressions.
109-
data Constant
110-
= ConstInt Integer -- ^ interpreted integer
111-
| ConstUninterpInt String -- ^ uninterpreted integer
112-
| ConstUninterpReal String -- ^ uninterpreted real
113-
| ConstBinary BinaryOp Constant Constant -- ^ binary operation on potential constants
114-
| ConstUnary UnaryOp Constant -- ^ unary operation on potential constants
115-
deriving (Show, Ord, Eq, Typeable, Generic, Data)
116-
117-
instance Out Constant
118-
instance Binary Constant
119-
120110
data Analysis a = Analysis
121111
{ prevAnnotation :: a -- ^ original annotation
122112
, uniqueName :: Maybe String -- ^ unique name for function/variable, after variable renaming phase
@@ -126,7 +116,7 @@ data Analysis a = Analysis
126116
, moduleEnv :: Maybe ModEnv
127117
, idType :: Maybe IDType
128118
, allLhsVarsAnn :: [Name]
129-
, constExp :: Maybe Constant
119+
, constExp :: Maybe FValue
130120
} deriving stock (Show, Generic, Data, Eq)
131121

132122
instance Functor Analysis where

src/Language/Fortran/Analysis/DataFlow.hs

+16-38
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Language.Fortran.Analysis.DataFlow
88
, genUDMap, genDUMap, duMapToUdMap, UDMap, DUMap
99
, genFlowsToGraph, FlowsGraph
1010
, genVarFlowsToMap, VarFlowsMap
11-
, Constant(..), ParameterVarMap, ConstExpMap, genConstExpMap, analyseConstExps, analyseParameterVars, constantFolding
11+
, ParameterVarMap, ConstExpMap, genConstExpMap, analyseConstExps, analyseParameterVars
1212
, genBlockMap, genDefMap, BlockMap, DefMap
1313
, genCallMap, CallMap
1414
, loopNodes, genBackEdgeMap, sccWith, BackEdgeMap
@@ -43,12 +43,9 @@ import Data.Maybe
4343
import Data.List (foldl', foldl1', (\\), union, intersect)
4444
import Control.Monad.Writer hiding (fix)
4545

46-
<<<<<<< HEAD
47-
=======
48-
--import qualified Language.Fortran.Repr as Repr
46+
import qualified Language.Fortran.Repr as Repr
4947
import qualified Language.Fortran.Repr.Eval.Value as Repr
5048

51-
>>>>>>> 63cef41 (Repr: replace some constant folding)
5249
--------------------------------------------------
5350
-- Better names for commonly used types
5451
type BBNodeMap = IM.IntMap
@@ -360,30 +357,13 @@ maxConst = (2::Integer) ^ (31::Integer) - (1::Integer)
360357
inBounds :: Integer -> Bool
361358
inBounds x = minConst <= x && x <= maxConst
362359

363-
-- | Evaluate possible constant expressions within tree.
364-
constantFolding :: Constant -> Constant
365-
constantFolding c = case c of
366-
ConstBinary binOp a b | ConstInt x <- constantFolding a
367-
, ConstInt y <- constantFolding b -> case binOp of
368-
Addition | inBounds (x + y) -> ConstInt (x + y)
369-
Subtraction | inBounds (x - y) -> ConstInt (x - y)
370-
Multiplication | inBounds (x * y) -> ConstInt (x * y)
371-
Division | y /= 0 -> ConstInt (x `div` y)
372-
-- gfortran appears to do real exponentiation (allowing negative exponent)
373-
-- and cast back to integer via floor() (?) as required
374-
-- but we keep it simple & stick with Haskell-style integer exponentiation
375-
Exponentiation | y >= 0 -> ConstInt (x ^ y)
376-
_ -> ConstBinary binOp (ConstInt x) (ConstInt y)
377-
ConstUnary Minus a | ConstInt x <- constantFolding a -> ConstInt (-x)
378-
ConstUnary Plus a -> constantFolding a
379-
_ -> c
380-
381360
-- | The map of all parameter variables and their corresponding values
382-
type ParameterVarMap = M.Map Name Constant
361+
type ParameterVarMap = M.Map Name Repr.FValue
362+
383363
-- | The map of all expressions and whether they are undecided (not
384-
-- present in map), a constant value (Just Constant), or probably not
385-
-- constant (Nothing).
386-
type ConstExpMap = ASTExprNodeMap (Maybe Constant)
364+
-- present in map), a constant value ('Just'), or probably not
365+
-- constant ('Nothing').
366+
type ConstExpMap = ASTExprNodeMap (Maybe Repr.FValue)
387367

388368
-- | Generate a constant-expression map with information about the
389369
-- expressions (identified by insLabel numbering) in the ProgramFile
@@ -400,23 +380,21 @@ genConstExpMap pf = ceMap
400380
[ (varName v, getE e)
401381
| st@StParameter{} <- universeBi pf :: [Statement (Analysis a)]
402382
, (Declarator _ _ v ScalarDecl _ (Just e)) <- universeBi st ]
403-
getV :: Expression (Analysis a) -> Maybe Constant
383+
getV :: Expression (Analysis a) -> Maybe Repr.FValue
404384
getV e = constExp (getAnnotation e) `mplus` (join . flip M.lookup pvMap . varName $ e)
405385

406386
-- Generate map of information about 'constant expressions'.
407387
ceMap = IM.fromList [ (label, doExpr e) | e <- universeBi pf, Just label <- [labelOf e] ]
408-
getE :: Expression (Analysis a) -> Maybe Constant
388+
getE :: Expression (Analysis a) -> Maybe Repr.FValue
409389
getE = join . (flip IM.lookup ceMap <=< labelOf)
410390
labelOf = insLabel . getAnnotation
411-
doExpr :: Expression (Analysis a) -> Maybe Constant
412-
doExpr e = case e of
413-
ExpValue _ _ (ValInteger intStr _) -> Just . ConstInt $ read intStr
414-
ExpValue _ _ (ValReal r _) -> Just $ ConstUninterpReal (prettyHsRealLit r) -- TODO
415-
ExpValue _ _ (ValVariable _) -> getV e
416-
-- Recursively seek information about sub-expressions, relying on laziness.
417-
ExpBinary _ _ binOp e1 e2 -> constantFolding <$> liftM2 (ConstBinary binOp) (getE e1) (getE e2)
418-
ExpUnary _ _ unOp e' -> constantFolding <$> ConstUnary unOp <$> getE e'
419-
_ -> Nothing
391+
doExpr :: Expression (Analysis a) -> Maybe Repr.FValue
392+
doExpr e =
393+
-- TODO constants may use other constants! but genConstExpMap needs more
394+
-- changes to support that
395+
case Repr.runEvalFValuePure mempty (Repr.evalExpr e) of
396+
Left _err -> Nothing
397+
Right (a, _msgs) -> Just a
420398

421399
-- | Get constant-expression information and put it into the AST
422400
-- analysis annotation. Must occur after analyseBBlocks.

test/Language/Fortran/Analysis/DataFlowSpec.hs

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ module Language.Fortran.Analysis.DataFlowSpec where
22

33
import Test.Hspec
44
import TestUtil
5-
import Test.Hspec.QuickCheck
6-
import Test.QuickCheck (Positive(..))
75

86
import Language.Fortran.AST
97
import Language.Fortran.Analysis

0 commit comments

Comments
 (0)