@@ -3735,6 +3735,35 @@ castUnDetVarsForVar det_vars x =
3735
3735
implCastPermM Proxy x eqp >>>
3736
3736
implPopM x (someEqProofRHS eqp)
3737
3737
3738
+
3739
+ -- | Simplify @lowned@ permissions @p@ on variable @x@ so they only depend on
3740
+ -- the determined variables given in the supplied list. This function only ends
3741
+ -- lifetimes, so that all lifetime ending happens before other unneeded
3742
+ -- permissions are dropped.
3743
+ simplify1LOwnedPermForDetVars :: NuMatchingAny1 r =>
3744
+ NameSet CrucibleType -> Name a -> ValuePerm a ->
3745
+ ImplM vars s r RNil RNil ()
3746
+
3747
+ -- For permission l:lowned[ls](ps_in -o ps_out) where l or some free variable in
3748
+ -- ps_in or ps_out is not determined, end l
3749
+ simplify1LOwnedPermForDetVars det_vars l (ValPerm_LOwned _ ps_in ps_out)
3750
+ | vars <- NameSet. insert l $ freeVars (ps_in,ps_out)
3751
+ , not $ NameSet. nameSetIsSubsetOf vars det_vars
3752
+ = implEndLifetimeRecM l
3753
+
3754
+ -- For lowned permission l:lowned[ls](ps_in -o ps_out), end any lifetimes in ls
3755
+ -- that are not determined and remove them from the lowned permission for ls
3756
+ simplify1LOwnedPermForDetVars det_vars l (ValPerm_LOwned ls _ _)
3757
+ | l': _ <- flip mapMaybe ls (asVar >=> \ l' ->
3758
+ if NameSet. member l' det_vars then Nothing
3759
+ else return l') =
3760
+ implEndLifetimeRecM l' >>>
3761
+ getPerm l >>>= \ p' -> simplify1PermForDetVars det_vars l p'
3762
+
3763
+ -- Otherwise do nothing
3764
+ simplify1LOwnedPermForDetVars _ _ _ = return ()
3765
+
3766
+
3738
3767
-- | Simplify and drop permissions @p@ on variable @x@ so they only depend on
3739
3768
-- the determined variables given in the supplied list
3740
3769
simplify1PermForDetVars :: NuMatchingAny1 r =>
@@ -3768,22 +3797,6 @@ simplify1PermForDetVars det_vars x (ValPerm_Conj ps)
3768
3797
getPerm x >>>= \ new_p ->
3769
3798
simplify1PermForDetVars det_vars x new_p
3770
3799
3771
- -- For permission l:lowned[ls](ps_in -o ps_out) where l or some free variable in
3772
- -- ps_in or ps_out is not determined, end l
3773
- simplify1PermForDetVars det_vars l (ValPerm_LOwned _ ps_in ps_out)
3774
- | vars <- NameSet. insert l $ freeVars (ps_in,ps_out)
3775
- , not $ NameSet. nameSetIsSubsetOf vars det_vars
3776
- = implEndLifetimeRecM l
3777
-
3778
- -- For lowned permission l:lowned[ls](ps_in -o ps_out), end any lifetimes in ls
3779
- -- that are not determined and remove them from the lowned permission for ls
3780
- simplify1PermForDetVars det_vars l (ValPerm_LOwned ls _ _)
3781
- | l': _ <- flip mapMaybe ls (asVar >=> \ l' ->
3782
- if NameSet. member l' det_vars then Nothing
3783
- else return l') =
3784
- implEndLifetimeRecM l' >>>
3785
- getPerm l >>>= \ p' -> simplify1PermForDetVars det_vars l p'
3786
-
3787
3800
-- If none of the above cases match but p has only determined free variables,
3788
3801
-- just leave p as is
3789
3802
simplify1PermForDetVars det_vars _ p
@@ -3808,8 +3821,15 @@ simplifyPermsForDetVars :: NuMatchingAny1 r => [SomeName CrucibleType] ->
3808
3821
simplifyPermsForDetVars det_vars_list =
3809
3822
let det_vars = NameSet. fromList det_vars_list in
3810
3823
(permSetVars <$> getPerms) >>>= \ vars ->
3824
+ -- Step 1: cast all the primary permissions using non-determined variables, to
3825
+ -- try to simplify them out
3826
+ mapM_ (\ (SomeName x) -> castUnDetVarsForVar det_vars x) vars >>>
3827
+ -- Step 2: end any unneeded lifetimes, but do this before any other unneeded
3828
+ -- permissions have been dropped, in case they are needed to end lifetimes
3829
+ mapM_ (\ (SomeName x) ->
3830
+ getPerm x >>>= simplify1LOwnedPermForDetVars det_vars x) vars >>>
3831
+ -- Step 3: simplify any other remaining permissions
3811
3832
mapM_ (\ (SomeName x) ->
3812
- castUnDetVarsForVar det_vars x >>>
3813
3833
getPerm x >>>= simplify1PermForDetVars det_vars x) vars
3814
3834
3815
3835
@@ -3920,6 +3940,18 @@ tcJumpTarget ctx (JumpTarget blkID args_tps args) =
3920
3940
namesToNamesList tops_args_ext_ns ++
3921
3941
determinedVars orig_cur_perms tops_args_ext_ns in
3922
3942
3943
+ implTraceM (\ i ->
3944
+ pretty (" tcJumpTarget " ++ show blkID) <>
3945
+ {- (if gen_perms_hint then pretty "(gen)" else emptyDoc) <> -}
3946
+ line <>
3947
+ (case permSetAllVarPerms orig_cur_perms of
3948
+ Some all_perms ->
3949
+ pretty " Current perms:" <+>
3950
+ align (permPretty i all_perms))
3951
+ <> line <>
3952
+ pretty " Determined vars:" <+>
3953
+ align (list (map (permPretty i) det_vars))) >>>
3954
+
3923
3955
-- Step 2: Simplify and drop permissions so they do not depend on undetermined
3924
3956
-- variables
3925
3957
simplifyPermsForDetVars det_vars >>>
@@ -3950,15 +3982,7 @@ tcJumpTarget ctx (JumpTarget blkID args_tps args) =
3950
3982
tops_perms args_perms) ghosts_perms in
3951
3983
implTraceM (\ i ->
3952
3984
pretty (" tcJumpTarget " ++ show blkID) <>
3953
- {- (if gen_perms_hint then pretty "(gen)" else emptyDoc) <> -}
3954
3985
line <>
3955
- (case permSetAllVarPerms orig_cur_perms of
3956
- Some all_perms ->
3957
- pretty " Current perms:" <+>
3958
- align (permPretty i all_perms))
3959
- <> line <>
3960
- pretty " Determined vars:" <+>
3961
- align (list (map (permPretty i) det_vars)) <> line <>
3962
3986
pretty " Input perms:" <+>
3963
3987
hang 2 (permPretty i perms_in)) >>>
3964
3988
0 commit comments