@@ -420,20 +420,35 @@ reconstructTabApp ctx expr ixs =
420420reconstructCase :: Emits o
421421 => Context SExpr e o -> SExpr o -> [SAlt i ] -> SType i -> EffectRow SimpIR i
422422 -> InlineM i o (e o )
423- reconstructCase ctx scrutExpr alts resultTy effs = do
424- -- TODO Opportunity here to inspect `scrutExpr` and perform case-of-case
425- -- optimization
426- scrut <- emitExprToAtom scrutExpr
427- case trySelectBranch scrut of
428- Just (i, val) -> do
429- Abs b body <- return $ alts !! i
430- extendSubst (b @> (SubstVal $ DoneEx $ Atom val)) do
431- inlineBlockEmits ctx body
432- Nothing -> do
433- alts' <- mapM visitAlt alts
423+ reconstructCase ctx scrutExpr alts resultTy effs =
424+ case scrutExpr of
425+ Case sscrut salts _ _ -> do
426+ -- Perform case-of-case optimization
427+ -- TODO Add join points to reduce code duplication (and repeated inlining)
428+ -- of the arms of the outer case
434429 resultTy' <- inline Stop resultTy
435- effs' <- inline Stop effs
436- reconstruct ctx $ Case scrut alts' resultTy' effs'
430+ reconstruct ctx =<< (buildCase' sscrut resultTy' \ i val -> do
431+ ans <- applyAbs (sink $ salts !! i) (SubstVal val) >>= emitBlock
432+ buildCase ans (sink resultTy') \ j jval -> do
433+ Abs b body <- return $ alts !! j
434+ extendSubst (b @> (SubstVal $ DoneEx $ Atom jval)) do
435+ inlineBlockEmits Stop body >>= emitExprToAtom)
436+ _ -> do
437+ -- Attempt case-of-known-constructor optimization
438+ -- I can't use `buildCase` here because I want to propagate the incoming
439+ -- context `ctx` into the selected alternative if the optimization fires,
440+ -- but leave it around the whole reconstructed `Case` if it doesn't.
441+ scrut <- emitExprToAtom scrutExpr
442+ case trySelectBranch scrut of
443+ Just (i, val) -> do
444+ Abs b body <- return $ alts !! i
445+ extendSubst (b @> (SubstVal $ DoneEx $ Atom val)) do
446+ inlineBlockEmits ctx body
447+ Nothing -> do
448+ alts' <- mapM visitAlt alts
449+ resultTy' <- inline Stop resultTy
450+ effs' <- inline Stop effs
451+ reconstruct ctx $ Case scrut alts' resultTy' effs'
437452
438453instance Inlinable (EffectRow SimpIR )
439454instance Inlinable (EffectAndType SimpIR )
0 commit comments