spawn fewer solver instances during typechecking

This appears to increase performance of the test and benchmark suites
substantially, but there may be more opportunities to cut down on the
number of solver instances.
This commit is contained in:
Adam C. Foltzer 2016-01-11 15:50:14 -08:00
parent 5c80fc2e1c
commit 1d2a135e44
5 changed files with 31 additions and 44 deletions

View File

@ -232,7 +232,7 @@ ${CS_BIN}/cryptol-test-runner: \
test: ${CS_BIN}/cryptol-test-runner
( cd tests && \
echo "Testing on $(UNAME)-$(ARCH)" && \
$(realpath $(CS_BIN)/cryptol-test-runner) \
time $(realpath $(CS_BIN)/cryptol-test-runner) \
$(TESTS) \
-c $(call adjust-path,${CURDIR}/${PKG_BIN}/cryptol${EXE_EXT}) \
-r output \

View File

@ -66,6 +66,7 @@ import qualified Cryptol.TypeCheck.AST as T
import qualified Cryptol.TypeCheck.Subst as T
import qualified Cryptol.TypeCheck.InferTypes as T
import Cryptol.TypeCheck.Solve(defaultReplExpr)
import qualified Cryptol.TypeCheck.Solver.CrySAT as CrySAT
import Cryptol.TypeCheck.PP (dump,ppWithNames)
import Cryptol.Utils.PP
import Cryptol.Utils.Panic(panic)
@ -889,7 +890,7 @@ replEvalExpr expr =
me <- getModuleEnv
let cfg = M.meSolverConfig me
mbDef <- io (defaultReplExpr cfg def sig)
mbDef <- io $ CrySAT.withSolver cfg (\s -> defaultReplExpr s def sig)
(def1,ty) <-
case mbDef of

View File

@ -706,8 +706,8 @@ generalize bs0 gs0 =
when (not (null ambig)) $ recordError $ AmbiguousType $ map dName bs
cfg <- getSolverConfig
(as0,here1,defSu,ws) <- io $ improveByDefaulting cfg maybeAmbig here0
solver <- getSolver
(as0,here1,defSu,ws) <- io $ improveByDefaultingWith solver maybeAmbig here0
mapM_ recordWarning ws
let here = map goal here1
@ -810,8 +810,8 @@ checkSigB b (Forall as asmps0 t0, validSchema) = case thing (P.bDef b) of
when (not (null ambig)) $ recordError
$ AmbiguousType [ thing (P.bName b) ]
cfg <- getSolverConfig
(_,_,defSu2,ws) <- io $ improveByDefaulting cfg maybeAmbig later
solver <- getSolver
(_,_,defSu2,ws) <- io $ improveByDefaultingWith solver maybeAmbig later
mapM_ recordWarning ws
extendSubst defSu2

View File

@ -20,9 +20,12 @@ import Cryptol.TypeCheck.AST
import Cryptol.TypeCheck.Subst
import Cryptol.TypeCheck.Unify(mgu, Result(..), UnificationError(..))
import Cryptol.TypeCheck.InferTypes
import qualified Cryptol.TypeCheck.Solver.CrySAT as CrySAT
import Cryptol.Utils.PP(pp, (<+>), Doc, text, quotes)
import Cryptol.Utils.Panic(panic)
import qualified Control.Applicative as A
import Control.Monad.Fix(MonadFix(..))
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Map (Map)
@ -31,8 +34,6 @@ import Data.List(find, minimumBy, groupBy, sortBy)
import Data.Maybe(mapMaybe)
import Data.Function(on)
import MonadLib hiding (mapM)
import qualified Control.Applicative as A
import Control.Monad.Fix(MonadFix(..))
import GHC.Generics (Generic)
import Control.DeepSeq.Generics
@ -86,7 +87,7 @@ data InferOutput a
deriving Show
runInferM :: TVars a => InferInput -> InferM a -> IO (InferOutput a)
runInferM info (IM m) =
runInferM info (IM m) = CrySAT.withSolver (inpSolverConfig info) $ \solver ->
do rec ro <- return RO { iRange = inpRange info
, iVars = Map.map ExtVar (inpVars info)
, iTVars = []
@ -94,7 +95,7 @@ runInferM info (IM m) =
, iNewtypes = fmap mkExternal (inpNewtypes info)
, iSolvedHasLazy = iSolvedHas finalRW -- RECURSION
, iMonoBinds = inpMonoBinds info
, iSolverConfig = inpSolverConfig info
, iSolver = solver
, iPrimNames = inpPrimNames info
}
@ -187,7 +188,7 @@ data RO = RO
-- in where-blocks will never be generalized. Bindings with type
-- signatures, and all bindings at top level are unaffected.
, iSolverConfig :: SolverConfig
, iSolver :: CrySAT.Solver
, iPrimNames :: !PrimMap
}
@ -270,10 +271,10 @@ recordWarning w =
do r <- curRange
IM $ sets_ $ \s -> s { iWarnings = (r,w) : iWarnings s }
getSolverConfig :: InferM SolverConfig
getSolverConfig =
getSolver :: InferM CrySAT.Solver
getSolver =
do RO { .. } <- IM ask
return iSolverConfig
return iSolver
-- | Retrieve the mapping between identifiers and declarations in the prelude.
getPrimMap :: InferM PrimMap

View File

@ -13,7 +13,7 @@ module Cryptol.TypeCheck.Solve
, proveImplication
, wfType
, wfTypeFunction
, improveByDefaulting
, improveByDefaultingWith
, defaultReplExpr
, simpType
, simpTypeMaybe
@ -86,8 +86,8 @@ simplifyAllConstraints :: InferM ()
simplifyAllConstraints =
do mapM_ tryHasGoal =<< getHasGoals
gs <- getGoals
cfg <- getSolverConfig
(mb,su) <- io (Num.withSolver cfg (`simpGoals'` gs))
solver <- getSolver
(mb,su) <- io (simpGoals' solver gs)
extendSubst su
case mb of
Right gs1 -> addGoals gs1
@ -97,15 +97,15 @@ simplifyAllConstraints =
proveImplication :: Name -> [TParam] -> [Prop] -> [Goal] -> InferM Subst
proveImplication lnam as ps gs =
do evars <- varsWithAsmps
cfg <- getSolverConfig
(mbErr,su) <- io (proveImplicationIO cfg lnam evars as ps gs)
solver <- getSolver
(mbErr,su) <- io (proveImplicationIO solver lnam evars as ps gs)
case mbErr of
Right ws -> mapM_ recordWarning ws
Left err -> recordError err
return su
proveImplicationIO :: SolverConfig
proveImplicationIO :: Num.Solver
-> Name -- ^ Checking this function
-> Set TVar -- ^ These appear in the env., and we should
-- not try to default the
@ -114,8 +114,7 @@ proveImplicationIO :: SolverConfig
-> [Goal] -- ^ Collected constraints
-> IO (Either Error [Warning], Subst)
proveImplicationIO _ _ _ _ [] [] = return (Right [], emptySubst)
proveImplicationIO cfg lname varsInEnv as ps gs =
Num.withSolver cfg $ \s ->
proveImplicationIO s lname varsInEnv as ps gs =
debugBlock s "proveImplicationIO" $
do debugBlock s "assumes" (debugLog s ps)
@ -419,18 +418,6 @@ importSideConds = go [] []
3. a substitution which indicates what got defaulted.
-}
improveByDefaulting ::
SolverConfig ->
[TVar] -> -- candidates for defaulting
[Goal] -> -- constraints
IO ( [TVar] -- non-defaulted
, [Goal] -- new constraints
, Subst -- improvements from defaulting
, [Warning] -- warnings about defaulting
)
improveByDefaulting cfg xs gs =
Num.withSolver cfg $ \s -> improveByDefaultingWith s xs gs
improveByDefaultingWith ::
Num.Solver ->
[TVar] -> -- candidates for defaulting
@ -543,16 +530,15 @@ improveByDefaultingWith s as ps =
-- | Try to pick a reasonable instantiation for an expression, with
-- the given type. This is useful when we do evaluation at the REPL.
-- The resulting types should satisfy the constraints of the schema.
defaultReplExpr :: SolverConfig -> Expr -> Schema
defaultReplExpr :: Num.Solver -> Expr -> Schema
-> IO (Maybe ([(TParam,Type)], Expr))
defaultReplExpr cfg e s =
defaultReplExpr so e s =
if all (\v -> kindOf v == KNum) (sVars s)
then do let params = map tpVar (sVars s)
mbSubst <- tryGetModel cfg params (sProps s)
mbSubst <- tryGetModel so params (sProps s)
case mbSubst of
Just su ->
do (res,su1) <- Num.withSolver cfg $ \so ->
simpGoals' so (map (makeGoal su) (sProps s))
do (res,su1) <- simpGoals' so (map (makeGoal su) (sProps s))
return $
case res of
Right [] | isEmptySubst su1 ->
@ -581,14 +567,13 @@ defaultReplExpr cfg e s =
-- | Attempt to default the given constraints by asserting them in the SMT
-- solver, and asking it for a model.
tryGetModel ::
SolverConfig ->
Num.Solver ->
[TVar] -> -- variables to try defaulting
[Prop] -> -- constraints
IO (Maybe Subst)
tryGetModel cfg xs ps =
Num.withSolver cfg $ \ s ->
-- We are only interested in finite instantiations
Num.getModel s (map (pFin . TVar) xs ++ ps)
tryGetModel s xs ps =
-- We are only interested in finite instantiations
Num.getModel s (map (pFin . TVar) xs ++ ps)
--------------------------------------------------------------------------------