@@ -65,8 +65,8 @@ module AST (
6565 speczVersionToId , SpeczProcBodies ,
6666 MultiSpeczDepInfo , CallSiteProperty (.. ), InterestingCallProperty (.. ),
6767 ProcAnalysis (.. ), emptyProcAnalysis ,
68- ProcBody (.. ), PrimFork (.. ), Ident , VarName ,
69- ProcName , ResourceDef (.. ), FlowDirection (.. ), showFlowName ,
68+ ProcBody (.. ), PrimFork (.. ), MergedForkTable , prependToBody , appendToBody , unMergeFork , guardedMergedFork ,
69+ Ident , VarName , ProcName , ResourceDef (.. ), FlowDirection (.. ), showFlowName ,
7070 argFlowDirection , argType , setArgType , setArgFlow , setArgFlowType , maybeArgFlowType ,
7171 argDescription , argIntVal , trustArgInt , setParamType , paramIsResourceful ,
7272 setPrimParamType , setTypeFlowType ,
@@ -2456,14 +2456,65 @@ data ProcBody = ProcBody {
24562456data PrimFork =
24572457 NoFork |
24582458 PrimFork {
2459+ forkVar :: PrimVarName , -- ^ The variable that selects branch to take
2460+ forkVarType :: TypeSpec , -- ^ The Wybe type of the forkVar
2461+ forkVarLast :: Bool , -- ^ Is this the last occurrence of forkVar
2462+ forkBodies :: [(Integer ,ProcBody )],
2463+ -- ^ one branch for each value of forkVar
2464+ forkDefault :: Maybe ProcBody -- ^ branch to take if forkVar is out of range
2465+ } |
2466+ MergedFork {
24592467 forkVar :: PrimVarName , -- ^ The variable that selects branch to take
24602468 forkVarType :: TypeSpec , -- ^ The Wybe type of the forkVar
24612469 forkVarLast :: Bool , -- ^ Is this the last occurrence of forkVar
2462- forkBodies :: [ProcBody ], -- ^ one branch for each value of forkVar
2463- forkDefault :: Maybe ProcBody -- ^ branch to take if forkVar is out of range
2470+ forkTable :: MergedForkTable ,
2471+ -- ^ Each variable factored out from each branch,
2472+ -- with the list of values indexed by the branch
2473+ forkBody :: ProcBody , -- ^ The rest of the "branch",
2474+ forkDefault :: Maybe ProcBody
2475+ -- ^ The branch if the var is out of range
24642476 }
24652477 deriving (Eq , Show , Generic )
24662478
2479+ type MergedForkTable = [(PrimVarName , TypeSpec , [PrimArg ])]
2480+
2481+ -- | Add the specified statements at the end of the given body
2482+ appendToBody :: ProcBody -> [Placed Prim ] -> ProcBody
2483+ appendToBody (ProcBody prims NoFork ) after
2484+ = ProcBody (prims++ after) NoFork
2485+ appendToBody (ProcBody prims (PrimFork v ty lst bodies deflt)) after
2486+ = let bodies' = List. map (mapSnd (`appendToBody` after)) bodies
2487+ in ProcBody prims $ PrimFork v ty lst bodies'
2488+ $ (`appendToBody` after) <$> deflt
2489+ appendToBody body@ ProcBody {bodyFork= merged@ MergedFork {forkBody= fork}} after
2490+ = body{bodyFork= merged{forkBody= fork `appendToBody` after}}
2491+
2492+ -- | Add the specified statements at the front of the given body
2493+ prependToBody :: [Placed Prim ] -> ProcBody -> ProcBody
2494+ prependToBody before (ProcBody prims fork)
2495+ = ProcBody (before++ prims) fork
2496+
2497+ -- | Un-merge a fork, replacing the tabled variables with a series of moved in the PrimFork branches
2498+ unMergeFork :: PrimFork -> PrimFork
2499+ unMergeFork (MergedFork var ty final table body dlft) =
2500+ let untabled = List. transpose
2501+ $ List. map (\ (var', ty', vals) -> List. map (\ p -> Unplaced $ PrimForeign " llvm" " move" [] [p, ArgVar var' ty' FlowOut Ordinary False ]) vals)
2502+ table
2503+ in if List. null untabled
2504+ then NoFork
2505+ else PrimFork var ty final (zip [0 .. ] (List. map (`prependToBody` body) untabled)) dlft
2506+ unMergeFork fork = shouldnt $ " unMergeFork on non-merged " ++ show fork
2507+
2508+ -- | Replace a default-y MergedFork with a guarded non-defaulted MergedFork in a ProcBody,
2509+ -- with the given var used int the fork
2510+ guardedMergedFork :: PrimVarName -> PrimVarName -> TypeSpec -> Integer -> ProcBody -> Maybe ProcBody -> ProcBody
2511+ guardedMergedFork _ _ _ _ body Nothing = body
2512+ guardedMergedFork tmp var ty limit body (Just dflt) =
2513+ ProcBody
2514+ [Unplaced $ PrimForeign " llvm" " icmp_ule" []
2515+ [ArgVar var ty FlowIn Ordinary False , ArgInt limit ty, ArgVar tmp bit FlowOut Ordinary False ]]
2516+ $ PrimFork tmp bit True (zip [0 .. ] [dflt,body]) Nothing
2517+ where bit = Representation $ Bits 1
24672518
24682519data LLBlock = LLBlock {
24692520 llInstrs :: [LLInstr ],
@@ -2621,13 +2672,14 @@ foldBodyPrims primFn emptyConj abDisj (ProcBody pprims fork) =
26212672 [] -> a
26222673 (pp: pps) -> primFn (final && List. null pps) (content pp) a)
26232674 emptyConj $ tails pprims
2675+ foldAll = List. foldl (\ a b -> abDisj a $ foldBodyPrims primFn common abDisj b)
26242676 in case fork of
26252677 NoFork -> common
2626- PrimFork _ _ _ [] _ -> shouldnt " empty clause list in a PrimFork"
2678+ PrimFork _ _ _ [] _ -> shouldnt " foldBodyPrims empty clause list in a PrimFork"
26272679 PrimFork _ _ _ (body: bodies) deflt ->
2628- List. foldl ( \ a b -> abDisj a $ foldBodyPrims primFn common abDisj b)
2629- (foldBodyPrims primFn common abDisj body)
2630- $ bodies ++ maybeToList deflt
2680+ foldAll (foldBodyPrims primFn common abDisj $ snd body) $ List. map snd bodies ++ maybeToList deflt
2681+ MergedFork {forkBody = body, forkDefault = deflt} ->
2682+ foldAll (foldBodyPrims primFn common abDisj body) $ maybeToList deflt
26312683
26322684
26332685-- | Similar to foldBodyPrims, except that it assumes that abstract
@@ -2647,14 +2699,16 @@ foldBodyDistrib primFn emptyConj abDisj abConj (ProcBody pprims fork) =
26472699 [] -> a
26482700 (pp: pps) -> primFn (final && List. null pps) (content pp) a)
26492701 emptyConj $ tails pprims
2702+ foldAll = (abConj common . ) . List. foldl (\ a b -> abDisj a $ foldBodyDistrib primFn common abDisj abConj b)
26502703 in case fork of
26512704 NoFork -> common
2652- PrimFork _ _ _ [] _ -> shouldnt " empty clause list in a PrimFork"
2705+ PrimFork _ _ _ [] _ -> shouldnt " foldBodyDistrib empty clause list in a PrimFork"
26532706 PrimFork _ _ _ (body: bodies) deflt ->
2654- abConj common $
2655- List. foldl (\ a b -> abDisj a $ foldBodyDistrib primFn common abDisj abConj b)
2656- (foldBodyPrims primFn common abDisj body)
2657- $ bodies ++ maybeToList deflt
2707+ foldAll (foldBodyDistrib primFn common abDisj abConj $ snd body) $ List. map snd bodies ++ maybeToList deflt
2708+ MergedFork {forkBody= body, forkDefault= deflt} ->
2709+ foldAll (foldBodyDistrib primFn common abDisj abConj body) $ maybeToList deflt
2710+
2711+
26582712
26592713
26602714-- | Traverse a ProcBody applying a monadic primFn to every Prim and applying a
@@ -2667,8 +2721,11 @@ mapLPVMBodyM primFn argFn (ProcBody pprims fork) = do
26672721 case fork of
26682722 NoFork -> return ()
26692723 (PrimFork _ _ _ bodies deflt) -> do
2670- mapM_ (mapLPVMBodyM primFn argFn) bodies
2671- maybe (return () ) (mapLPVMBodyM primFn argFn) deflt
2724+ mapM_ (mapLPVMBodyM primFn argFn . snd ) bodies
2725+ forM_ deflt (mapLPVMBodyM primFn argFn)
2726+ MergedFork {forkBody= body,forkDefault= deflt} -> do
2727+ mapLPVMBodyM primFn argFn body
2728+ forM_ deflt (mapLPVMBodyM primFn argFn)
26722729
26732730
26742731-- | Handle a single Prim for mapLPVMBodyM doing the needful.
@@ -3631,6 +3688,7 @@ expOutputs (DisjExp pexp1 pexp2) = pexpListOutputs [pexp1,pexp2]
36313688expOutputs (Where _ pexp) = expOutputs $ content pexp
36323689expOutputs (CondExp _ pexp1 pexp2) = pexpListOutputs [pexp1,pexp2]
36333690expOutputs (Fncall _ _ _ args) = pexpListOutputs args
3691+ expOutputs (ForeignFn " lpvm" " sizeof" _ (_: args)) = pexpListOutputs args
36343692expOutputs (ForeignFn _ _ _ args) = pexpListOutputs args
36353693expOutputs (CaseExp _ cases deflt) =
36363694 pexpListOutputs $ maybe id (:) deflt (snd <$> cases)
@@ -4097,8 +4155,17 @@ showFork ind (PrimFork var ty last bodies deflt) =
40974155 " :" ++ show ty ++ " of" ++
40984156 List. concatMap (\ (val,body) ->
40994157 startLine ind ++ show val ++ " :" ++
4100- showBlock (ind+ 4 ) body ++ " \n " )
4101- (zip [0 .. ] bodies)
4158+ showBlock (ind+ 4 ) body ++ " \n " ) bodies
4159+ ++ maybe " " (\ b -> startLine ind ++ " else:"
4160+ ++ showBlock (ind+ 4 ) b ++ " \n " ) deflt
4161+ showFork ind (MergedFork var ty last vars body deflt) =
4162+ startLine ind ++ " factored " ++ (if last then " ~" else " " ) ++ show var ++
4163+ " :" ++ show ty ++ " of" ++
4164+ List. concatMap (\ (var, ty, vals) ->
4165+ startLine (ind + 2 ) ++ " ?" ++ show var ++ " :" ++ show ty ++
4166+ " <- [ " ++ intercalate " , " (List. map show vals) ++ " ]" )
4167+ vars
4168+ ++ showBlock (ind+ 4 ) body
41024169 ++ maybe " " (\ b -> startLine ind ++ " else:"
41034170 ++ showBlock (ind+ 4 ) b ++ " \n " ) deflt
41044171
0 commit comments