@@ -96,9 +96,14 @@ data PState =
9696 stateSubst :: Subst ,
9797 stateChange :: ChangeFlag ,
9898 stateRawVarTypes :: Map RawVar RawType , -- for assertions optimizations
99- stateLValTypes :: Map VarName RawType -- for assertions optimizations
99+ stateLValTypes :: Map VarName RawType -- for assertions optimizations
100100 }
101101
102+
103+ data ReadEnv =
104+ ReadEnv { readConsts :: Map RawVar Core. Lit }
105+
106+
102107-- 2021-02-28; AA
103108-- As we traverse the AST we collect information about how
104109-- different bindings are used. We distinguish two different
@@ -113,7 +118,7 @@ type Used = (Set VarName, Set RawVar)
113118type ChangeFlag = Bool
114119
115120-- Optimization monad: keep track of used variables, to be able to eliminate unused variables.
116- type Opt = RWS () Used PState
121+ type Opt = RWS ReadEnv Used PState
117122
118123class PEval a where
119124 peval :: a -> Opt a
@@ -266,13 +271,13 @@ _setLValType x t = modify (\pstate ->
266271-- Partially evaluate instruction. This is called multiple times in the optimization sequence.
267272-- First pass: partially evaluate functions (instructions).
268273-- Removes e.g. redundant state projections state (e.g. if multiple in same block).
269- -- Returns 'Nothing' if the instruction is to be ommitted.
270- pevalInst :: RawInst -> Opt ( Maybe RawInst )
274+ --
275+ pevalInst :: RawInst -> Opt [ RawInst ]
271276pevalInst i = do
272277 pstate <- get
273278 i' <- subst i -- apply the collected substitutions
274- let _omit x = x >> ( return Nothing )
275- let _keep x = x >> ( return $ Just i')
279+ let _omit x = x >> return []
280+ let _keep x = x >> return [i']
276281
277282 case i' of
278283 AssignRaw r (ProjectState p) -> do
@@ -319,21 +324,39 @@ pevalInst i = do
319324 case guessType rexpr of
320325 Nothing -> return ()
321326 Just ty -> _setRawType r ty
322-
323327
324- AssignLVal v complexExpr -> _keep $ do
325- case complexExpr of
326- Bin op (UseNativeBinop False ) r1 r2 | op `elem` [Basics. Eq , Basics. Neq ] ->
327- _setLValType v RawBoolean
328- _ -> return ()
328+ AssignLVal v complexExpr@ (Bin op (UseNativeBinop False ) r1 r2)
329+ | op `elem` [Basics. Eq , Basics. Neq ] -> do
330+ _setLValType v RawBoolean
331+ a <- isSuitableForNativeEq r1
332+ b <- isSuitableForNativeEq r2
333+ if a || b
334+ then do
335+ let VN s = v
336+ r3 = RawVar $ s ++ " $val_opt"
337+ r4 = RawVar $ s ++ " $vlev_opt"
338+ r5 = RawVar $ s ++ " $tlev_opt"
339+ markUsed v
340+ markUsed [r1, r2, r3, r4, r5]
341+ return $
342+ [ AssignRaw r3 (Bin op (UseNativeBinop True ) r1 r2)
343+ , AssignRaw r4 (ProjectState MonPC )
344+ , AssignRaw r5 (ProjectState MonPC )
345+ , AssignLVal v (ConstructLVal r3 r4 r5)
346+ ]
347+ else
348+ _keep $ markUsed complexExpr
349+
350+
351+ AssignLVal v complexExpr ->
329352 _keep $ markUsed complexExpr
330353
331354 SetState p r -> _keep $ do
332355 markUsed r
333356 monInsert p r
334357 RTAssertion (AssertType r rt) -> do
335358 case Map. lookup r (stateRawVarTypes pstate) of
336- Just rt' | rt' == rt -> return Nothing
359+ Just rt' | rt' == rt -> return []
337360 _ -> _keep $ _setRawType r rt >> markUsed r
338361 -- RTAssertion (AssertEqTypes opt_ls x y) -> do
339362 -- let _m = stateTypes pstate
@@ -353,19 +376,34 @@ pevalInst i = do
353376 case (Map. lookup x _m, Map. lookup y _m) of
354377 (Just t1 , Just t2) | t1 == t2 ->
355378 if t1 `elem` [RawNumber , RawString ]
356- then return Nothing
379+ then return []
357380 else keep
358381 _ -> keep
359382 -- TODO track tuple length
360383 RTAssertion (AssertTupleLengthGreaterThan r n) -> _keep $ markUsed r
361384 -- TODO track record fields
362385 RTAssertion (AssertRecordHasField r f) -> _keep $ markUsed r
363- RTAssertion (AssertNotZero r) -> _keep $ markUsed r
386+ RTAssertion (AssertNotZero r) -> do
387+ renv <- ask
388+ case Map. lookup r (readConsts renv) of
389+ Just (Core. LInt x _) | x /= 0 -> return []
390+ _ -> _keep $ markUsed r
364391 MkFunClosures ee _ -> _keep $ markUsed (snd (unzip ee))
365392 -- No applicable optimizations.
366- SetBranchFlag -> return $ Just i'
367- InvalidateSparseBit -> return $ Just i'
368-
393+ SetBranchFlag -> return [i']
394+ InvalidateSparseBit -> return [i']
395+
396+
397+ isSuitableForNativeEq r = do
398+ pstate <- get
399+ return $
400+ case Map. lookup r (stateRawVarTypes pstate) of
401+ Nothing -> False
402+ Just t -> case t of
403+ RawNumber -> True
404+ RawString -> True
405+ _ -> False
406+
369407
370408instance PEval RawTerminator where
371409 peval tr = do
@@ -488,7 +526,7 @@ instOrder ii = work [] ii
488526instance PEval RawBBTree where
489527 peval bb@ (BB insts tr) = do
490528 (BB jj tr'', used) <- listen $ do
491- ii <- Data.Maybe. catMaybes <$> mapM pevalInst insts
529+ ii <- concat <$> mapM pevalInst insts
492530 tr' <- peval tr
493531 return $ BB ii tr'
494532 let (insts_no_ret, set_pc_bl) = filterInstBwd (filter (isLiveInstFwd used) jj)
@@ -538,8 +576,11 @@ funopt (FunDef hfn consts bb ir) =
538576 stateRawVarTypes = constTypes,
539577 stateLValTypes = Map. empty
540578 }
541- (bb', _, _) = runRWS (peval bb) () pstate
542- new = FunDef hfn consts' bb' ir
579+
580+ readenv = ReadEnv { readConsts = Map. fromList consts }
581+ (bb', _, (_, used_rvars)) = runRWS (peval bb) readenv pstate
582+ const_used = filter (\ (x,_) -> Set. member x used_rvars) consts'
583+ new = FunDef hfn const_used bb' ir
543584 in if bb /= bb' then funopt new else new
544585
545586
0 commit comments