|
1 | 1 | module Gibbon.Passes.AddCastInstructions (addCasts) where |
2 | 2 |
|
3 | | -import Data.Foldable (foldrM) |
| 3 | +import Data.Foldable (foldrM, foldlM) |
4 | 4 | import qualified Data.List as L |
5 | 5 | import qualified Data.Map as M |
6 | 6 | import Gibbon.Common |
@@ -49,6 +49,24 @@ addCastsExp fundef cenv env ex = |
49 | 49 | bod' <- addCastsExp fundef cenv' env' bod |
50 | 50 | let ex' = foldr (\expr acc -> expr acc) bod' let_expr |
51 | 51 | pure $ ex' |
| 52 | + |
| 53 | + LetE (v, locs, ty, rhs@(VarE v')) bod -> do |
| 54 | + let new_env = extendVEnv v ty env |
| 55 | + let tyv' = lookupVEnv v' env |
| 56 | + (let_expr, cenv', env') <- case (ty == tyv') of |
| 57 | + True -> return $ ([LetE (v, locs, ty, rhs)], cenv, new_env) |
| 58 | + False -> do |
| 59 | + casted_var <- gensym "cast" |
| 60 | + let ncenv = M.insert v' v cenv |
| 61 | + let cursory_ty3 :: Ty3 = CursorTy |
| 62 | + let nenv = extendVEnv casted_var cursory_ty3 new_env |
| 63 | + let cast_ins = Ext $ CastPtr casted_var ty |
| 64 | + -- let new_inst = [LetE (v, locs, ty, rhs)] ++ [LetE (casted_var, [], CursorTy, cast_ins)] |
| 65 | + let new_inst = [LetE (casted_var, locs, CursorTy, rhs)] ++ [LetE (v, [], ty, cast_ins)] |
| 66 | + pure $ (new_inst, ncenv, nenv) |
| 67 | + bod' <- addCastsExp fundef cenv' env' bod |
| 68 | + let ex' = foldr (\expr acc -> expr acc) bod' let_expr |
| 69 | + pure $ ex' |
52 | 70 |
|
53 | 71 | LetE (v, locs, ty, rhs@(Ext (AddrOfCursor (Ext (IndexCursorArray _ _)))) ) bod -> do |
54 | 72 | let new_env = extendVEnv v ty env |
@@ -204,7 +222,25 @@ addCastsExp fundef cenv env ex = |
204 | 222 | CharE {} -> pure ex |
205 | 223 | FloatE {} -> pure ex |
206 | 224 | LitSymE {} -> pure ex |
207 | | - AppE f locs args -> AppE f locs <$> mapM go args |
| 225 | + AppE f locs args -> do |
| 226 | + let funTy = lookupFEnv f env |
| 227 | + let args_zip_ty = zip args (fst funTy ++ [snd funTy]) |
| 228 | + (lets, new_args) <- foldlM (\(l, args') zipped -> case zipped of |
| 229 | + (VarE arg, ty) -> do |
| 230 | + let argTy = lookupVEnv arg env |
| 231 | + if argTy == ty |
| 232 | + then |
| 233 | + return $ (l, args' ++ [VarE arg]) |
| 234 | + else do |
| 235 | + let new_arg = case (M.lookup arg cenv) of |
| 236 | + Just v' -> VarE v' |
| 237 | + Nothing -> error "TODO : Cast not found in env!!" |
| 238 | + return $ (l, args' ++ [new_arg]) |
| 239 | + _ -> return $ (l, args' ++ [fst zipped]) |
| 240 | + ) ([], []) args_zip_ty |
| 241 | + -- Expecting AppE to be flat, so only variables are present in AppE. |
| 242 | + return $ AppE f locs new_args |
| 243 | + |
208 | 244 | PrimAppE pr args -> PrimAppE pr <$> mapM go args |
209 | 245 | IfE a b c -> do |
210 | 246 | a' <- go a |
|
0 commit comments