@@ -154,7 +154,7 @@ generate codegen mainmod ir
155irMain :: TT Name -> Idris LDecl
155irMain :: TT Name -> Idris LDecl
156irMain tm = do
156irMain tm = do
157− i <- irTerm M.empty [] tm
157+ i <- irTerm (sMN 0 "runMain") M.empty [] tm
158 return $ LFun [] (sMN 0 "runMain") [] (LForce i)
158 return $ LFun [] (sMN 0 "runMain") [] (LForce i)
160mkDecls :: [Name] -> Idris [(Name, LDecl)]
160mkDecls :: [Name] -> Idris [(Name, LDecl)]
@@ -218,10 +218,10 @@ declArgs args inl n (LLam xs x) = declArgs (args ++ xs) inl n x
218declArgs args inl n x = LFun (if inl then [Inline] else []) n args x
218declArgs args inl n x = LFun (if inl then [Inline] else []) n args x
220mkLDecl n (Function tm _)
220mkLDecl n (Function tm _)
221− = declArgs [] True n <$> irTerm M.empty [] tm
221+ = declArgs [] True n <$> irTerm n M.empty [] tm
223mkLDecl n (CaseOp ci _ _ _ pats cd)
223mkLDecl n (CaseOp ci _ _ _ pats cd)
224− = declArgs [] (case_inlinable ci || caseName n) n <$> irTree args sc
224+ = declArgs [] (case_inlinable ci || caseName n) n <$> irTree n args sc
226 (args, sc) = cases_runtime cd
226 (args, sc) = cases_runtime cd
@@ -244,8 +244,8 @@ data VarInfo = VI
245type Vars = M.Map Name VarInfo
245type Vars = M.Map Name VarInfo
247−irTerm :: Vars -> [Name] -> Term -> Idris LExp
247+irTerm :: Name -> Vars -> [Name] -> Term -> Idris LExp
248−irTerm vs env tm@(App _ f a) = do
248+irTerm top vs env tm@(App _ f a) = do
249 ist <- getIState
249 ist <- getIState
250 case unApply tm of
250 case unApply tm of
251 (P _ n _, args)
251 (P _ n _, args)
@@ -257,12 +257,16 @@ irTerm vs env tm@(App _ f a) = do
258 (P _ (UN u) _, [_, arg])
258 (P _ (UN u) _, [_, arg])
259 | u == txt "unsafePerformPrimIO"
259 | u == txt "unsafePerformPrimIO"
260− -> irTerm vs env arg
260+ -> irTerm top vs env arg
263+ | u == txt "assert_unreachable"
264+ -> return $ LError $ "ABORT: Reached an unreachable case in " ++ show top
262 -- TMP HACK - until we get inlining.
266 -- TMP HACK - until we get inlining.
263 (P _ (UN r) _, [_, _, _, _, _, arg])
267 (P _ (UN r) _, [_, _, _, _, _, arg])
264 | r == txt "replace"
268 | r == txt "replace"
265− -> irTerm vs env arg
269+ -> irTerm top vs env arg
267 -- 'void' doesn't have any pattern clauses and only gets called on
271 -- 'void' doesn't have any pattern clauses and only gets called on
268 -- erased things in higher order contexts (also a TMP HACK...)
272 -- erased things in higher order contexts (also a TMP HACK...)
@@ -277,42 +281,42 @@ irTerm vs env tm@(App _ f a) = do
278 (P _ (UN l) _, [_, arg])
282 (P _ (UN l) _, [_, arg])
279 | l == txt "force"
283 | l == txt "force"
280− -> LForce <$> irTerm vs env arg
284+ -> LForce <$> irTerm top vs env arg
282 -- Laziness, the new way
286 -- Laziness, the new way
283 (P _ (UN l) _, [_, _, arg])
287 (P _ (UN l) _, [_, _, arg])
284 | l == txt "Delay"
288 | l == txt "Delay"
285− -> LLazyExp <$> irTerm vs env arg
289+ -> LLazyExp <$> irTerm top vs env arg
287 (P _ (UN l) _, [_, _, arg])
291 (P _ (UN l) _, [_, _, arg])
288 | l == txt "Force"
292 | l == txt "Force"
289− -> LForce <$> irTerm vs env arg
293+ -> LForce <$> irTerm top vs env arg
291 (P _ (UN a) _, [_, _, _, arg])
295 (P _ (UN a) _, [_, _, _, arg])
292 | a == txt "assert_smaller"
296 | a == txt "assert_smaller"
293− -> irTerm vs env arg
297+ -> irTerm top vs env arg
295 (P _ (UN a) _, [_, arg])
299 (P _ (UN a) _, [_, arg])
296 | a == txt "assert_total"
300 | a == txt "assert_total"
297− -> irTerm vs env arg
301+ -> irTerm top vs env arg
299 (P _ (UN p) _, [_, arg])
303 (P _ (UN p) _, [_, arg])
300 | p == txt "par"
304 | p == txt "par"
301− -> do arg' <- irTerm vs env arg
305+ -> do arg' <- irTerm top vs env arg
302 return $ LOp LPar [LLazyExp arg']
306 return $ LOp LPar [LLazyExp arg']
304 (P _ (UN pf) _, [arg])
308 (P _ (UN pf) _, [arg])
305 | pf == txt "prim_fork"
309 | pf == txt "prim_fork"
306− -> do arg' <- irTerm vs env arg
310+ -> do arg' <- irTerm top vs env arg
307 return $ LOp LFork [LLazyExp arg']
311 return $ LOp LFork [LLazyExp arg']
309 (P _ (UN m) _, [_,size,t])
313 (P _ (UN m) _, [_,size,t])
310 | m == txt "malloc"
314 | m == txt "malloc"
311− -> irTerm vs env t
315+ -> irTerm top vs env t
313 (P _ (UN tm) _, [_,t])
317 (P _ (UN tm) _, [_,t])
314 | tm == txt "trace_malloc"
318 | tm == txt "trace_malloc"
315− -> irTerm vs env t -- TODO
319+ -> irTerm top vs env t -- TODO
317 -- This case is here until we get more general inlining. It's just
321 -- This case is here until we get more general inlining. It's just
318 -- a really common case, and the laziness hurts...
322 -- a really common case, and the laziness hurts...
@@ -324,9 +328,9 @@ irTerm vs env tm@(App _ f a) = do
324 , b == txt "Bool"
328 , b == txt "Bool"
325 , p == txt "Prelude"
329 , p == txt "Prelude"
327− x' <- irTerm vs env x
331+ x' <- irTerm top vs env x
328− t' <- irTerm vs env t
332+ t' <- irTerm top vs env t
329− e' <- irTerm vs env e
333+ e' <- irTerm top vs env e
330 return (LCase Shared x'
334 return (LCase Shared x'
331 [LConCase 0 (sNS (sUN "False") ["Bool","Prelude"]) [] e'
335 [LConCase 0 (sNS (sUN "False") ["Bool","Prelude"]) [] e'
332 ,LConCase 1 (sNS (sUN "True" ) ["Bool","Prelude"]) [] t'
336 ,LConCase 1 (sNS (sUN "True" ) ["Bool","Prelude"]) [] t'
@@ -375,7 +379,7 @@ irTerm vs env tm@(App _ f a) = do
376 -- exactly saturated
380 -- exactly saturated
377 EQ | isNewtype
381 EQ | isNewtype
378− -> irTerm vs env (head argsPruned)
382+ -> irTerm top vs env (head argsPruned)
380 | otherwise -- not newtype, plain data ctor
384 | otherwise -- not newtype, plain data ctor
381 -> buildApp (LV $ Glob n) argsPruned
385 -> buildApp (LV $ Glob n) argsPruned
@@ -384,7 +388,7 @@ irTerm vs env tm@(App _ f a) = do
384 LT | isNewtype -- newtype
388 LT | isNewtype -- newtype
385 , length argsPruned == 1 -- and we already have the value
389 , length argsPruned == 1 -- and we already have the value
386 -> padLams . (\tm [] -> tm) -- the [] asserts there are no unerased args
390 -> padLams . (\tm [] -> tm) -- the [] asserts there are no unerased args
387− <$> irTerm vs env (head argsPruned)
391+ <$> irTerm top vs env (head argsPruned)
389 | isNewtype -- newtype but the value is not among args yet
393 | isNewtype -- newtype but the value is not among args yet
390 -> return . padLams $ \[vn] -> LApp False (LV $ Glob n) [LV $ Glob vn]
394 -> return . padLams $ \[vn] -> LApp False (LV $ Glob n) [LV $ Glob vn]
@@ -398,7 +402,7 @@ irTerm vs env tm@(App _ f a) = do
399 -- an external name applied to arguments
403 -- an external name applied to arguments
400 (P _ n _, args) | S.member (n, length args) (idris_externs ist) -> do
404 (P _ n _, args) | S.member (n, length args) (idris_externs ist) -> do
401− LOp (LExternal n) <$> mapM (irTerm vs env) args
405+ LOp (LExternal n) <$> mapM (irTerm top vs env) args
403 -- a name applied to arguments
407 -- a name applied to arguments
404 (P _ n _, args) -> do
408 (P _ n _, args) -> do
@@ -406,23 +410,23 @@ irTerm vs env tm@(App _ f a) = do
406 -- if it's a primitive that is already saturated,
410 -- if it's a primitive that is already saturated,
407 -- compile to the corresponding op here already to save work
411 -- compile to the corresponding op here already to save work
408 Just (arity, op) | length args == arity
412 Just (arity, op) | length args == arity
409− -> LOp op <$> mapM (irTerm vs env) args
413+ -> LOp op <$> mapM (irTerm top vs env) args
411 -- otherwise, just apply the name
415 -- otherwise, just apply the name
412 _ -> applyName n ist args
416 _ -> applyName n ist args
414 -- turn de bruijn vars into regular named references and try again
418 -- turn de bruijn vars into regular named references and try again
415− (V i, args) -> irTerm vs env $ mkApp (P Bound (env !! i) Erased) args
419+ (V i, args) -> irTerm top vs env $ mkApp (P Bound (env !! i) Erased) args
417 (f, args)
421 (f, args)
418 -> LApp False
422 -> LApp False
419− <$> irTerm vs env f
423+ <$> irTerm top vs env f
420− <*> mapM (irTerm vs env) args
424+ <*> mapM (irTerm top vs env) args
423 buildApp :: LExp -> [Term] -> Idris LExp
427 buildApp :: LExp -> [Term] -> Idris LExp
424 buildApp e [] = return e
428 buildApp e [] = return e
425− buildApp e xs = LApp False e <$> mapM (irTerm vs env) xs
429+ buildApp e xs = LApp False e <$> mapM (irTerm top vs env) xs
427 applyToNames :: LExp -> [Name] -> LExp
431 applyToNames :: LExp -> [Name] -> LExp
428 applyToNames tm [] = tm
432 applyToNames tm [] = tm
@@ -437,7 +441,7 @@ irTerm vs env tm@(App _ f a) = do
438 applyName :: Name -> IState -> [Term] -> Idris LExp
442 applyName :: Name -> IState -> [Term] -> Idris LExp
439 applyName n ist args =
443 applyName n ist args =
440− LApp False (LV $ Glob n) <$> mapM (irTerm vs env . erase) (zip [0..] args)
444+ LApp False (LV $ Glob n) <$> mapM (irTerm top vs env . erase) (zip [0..] args)
442 erase (i, x)
446 erase (i, x)
443 | i >= arity || i `elem` used = x
447 | i >= arity || i `elem` used = x
@@ -459,31 +463,31 @@ irTerm vs env tm@(App _ f a) = do
459 used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
463 used = maybe [] (map fst . usedpos) $ lookupCtxtExact uName (idris_callgraph ist)
460 fst4 (x,_,_,_,_) = x
464 fst4 (x,_,_,_,_) = x
462−irTerm vs env (P _ n _) = return $ LV (Glob n)
466+irTerm top vs env (P _ n _) = return $ LV (Glob n)
463−irTerm vs env (V i)
467+irTerm top vs env (V i)
464 | i >= 0 && i < length env = return $ LV (Glob (env!!i))
468 | i >= 0 && i < length env = return $ LV (Glob (env!!i))
465 | otherwise = ifail $ "bad de bruijn index: " ++ show i
469 | otherwise = ifail $ "bad de bruijn index: " ++ show i
467−irTerm vs env (Bind n (Lam _) sc) = LLam [n'] <$> irTerm vs (n':env) sc
471+irTerm top vs env (Bind n (Lam _) sc) = LLam [n'] <$> irTerm top vs (n':env) sc
469 n' = uniqueName n env
473 n' = uniqueName n env
471−irTerm vs env (Bind n (Let _ v) sc)
475+irTerm top vs env (Bind n (Let _ v) sc)
472− = LLet n <$> irTerm vs env v <*> irTerm vs (n : env) sc
476+ = LLet n <$> irTerm top vs env v <*> irTerm top vs (n : env) sc
474−irTerm vs env (Bind _ _ _) = return $ LNothing
478+irTerm top vs env (Bind _ _ _) = return $ LNothing
476−irTerm vs env (Proj t (-1)) = do
480+irTerm top vs env (Proj t (-1)) = do
477− t' <- irTerm vs env t
481+ t' <- irTerm top vs env t
478 return $ LOp (LMinus (ATInt ITBig))
482 return $ LOp (LMinus (ATInt ITBig))
479 [t', LConst (BI 1)]
483 [t', LConst (BI 1)]
481−irTerm vs env (Proj t i) = LProj <$> irTerm vs env t <*> pure i
485+irTerm top vs env (Proj t i) = LProj <$> irTerm top vs env t <*> pure i
482−irTerm vs env (Constant TheWorld) = return $ LNothing
486+irTerm top vs env (Constant TheWorld) = return $ LNothing
483−irTerm vs env (Constant c) = return $ LConst c
487+irTerm top vs env (Constant c) = return $ LConst c
484−irTerm vs env (TType _) = return $ LNothing
488+irTerm top vs env (TType _) = return $ LNothing
485−irTerm vs env Erased = return $ LNothing
489+irTerm top vs env Erased = return $ LNothing
486−irTerm vs env Impossible = return $ LNothing
490+irTerm top vs env Impossible = return $ LNothing
488doForeign :: Vars -> [Name] -> [Term] -> Idris LExp
492doForeign :: Vars -> [Name] -> [Term] -> Idris LExp
489doForeign vs env (ret : fname : world : args)
493doForeign vs env (ret : fname : world : args)
@@ -494,7 +498,7 @@ doForeign vs env (ret : fname : world : args)
495 splitArg tm | (_, [_,_,l,r]) <- unApply tm -- pair, two implicits
499 splitArg tm | (_, [_,_,l,r]) <- unApply tm -- pair, two implicits
496 = do let l' = toFDesc l
500 = do let l' = toFDesc l
497− r' <- irTerm vs env r
501+ r' <- irTerm (sMN 0 "__foreignCall") vs env r
498 return (l', r')
502 return (l', r')
499 splitArg _ = ifail $ "Badly formed foreign function call"
503 splitArg _ = ifail $ "Badly formed foreign function call"
@@ -508,24 +512,24 @@ doForeign vs env (ret : fname : world : args)
508 deNS n = n
512 deNS n = n
509doForeign vs env xs = ifail "Badly formed foreign function call"
513doForeign vs env xs = ifail "Badly formed foreign function call"
511−irTree :: [Name] -> SC -> Idris LExp
515+irTree :: Name -> [Name] -> SC -> Idris LExp
512−irTree args tree = do
516+irTree top args tree = do
513 logCodeGen 3 $ "Compiling " ++ show args ++ "\n" ++ show tree
517 logCodeGen 3 $ "Compiling " ++ show args ++ "\n" ++ show tree
514− LLam args <$> irSC M.empty tree
518+ LLam args <$> irSC top M.empty tree
516−irSC :: Vars -> SC -> Idris LExp
520+irSC :: Name -> Vars -> SC -> Idris LExp
517−irSC vs (STerm t) = irTerm vs [] t
521+irSC top vs (STerm t) = irTerm top vs [] t
518−irSC vs (UnmatchedCase str) = return $ LError str
522+irSC top vs (UnmatchedCase str) = return $ LError str
520−irSC vs (ProjCase tm alts) = do
524+irSC top vs (ProjCase tm alts) = do
521− tm' <- irTerm vs [] tm
525+ tm' <- irTerm top vs [] tm
522− alts' <- mapM (irAlt vs tm') alts
526+ alts' <- mapM (irAlt top vs tm') alts
523 return $ LCase Shared tm' alts'
527 return $ LCase Shared tm' alts'
525-- Transform matching on Delay to applications of Force.
529-- Transform matching on Delay to applications of Force.
526−irSC vs (Case up n [ConCase (UN delay) i [_, _, n'] sc])
530+irSC top vs (Case up n [ConCase (UN delay) i [_, _, n'] sc])
527 | delay == txt "Delay"
531 | delay == txt "Delay"
528− = do sc' <- irSC vs $ mkForce n' n sc
532+ = do sc' <- irSC top vs $ mkForce n' n sc
529 return $ LLet n' (LForce (LV (Glob n))) sc'
533 return $ LLet n' (LForce (LV (Glob n))) sc'
531-- There are two transformations in this case:
535-- There are two transformations in this case:
@@ -550,7 +554,7 @@ irSC vs (Case up n [ConCase (UN delay) i [_, _, n'] sc])
550-- Hence, we check whether the variables are used at all
554-- Hence, we check whether the variables are used at all
551-- and erase the casesplit if they are not.
555-- and erase the casesplit if they are not.
553−irSC vs (Case up n [alt]) = do
557+irSC top vs (Case up n [alt]) = do
554 replacement <- case alt of
558 replacement <- case alt of
555 ConCase cn a ns sc -> do
559 ConCase cn a ns sc -> do
556 detag <- fgetState (opt_detaggable . ist_optimisation cn)
560 detag <- fgetState (opt_detaggable . ist_optimisation cn)
@@ -561,9 +565,9 @@ irSC vs (Case up n [alt]) = do
561 _ -> return Nothing
565 _ -> return Nothing
563 case replacement of
567 case replacement of
564− Just sc -> irSC vs sc
568+ Just sc -> irSC top vs sc
566− alt' <- irAlt vs (LV (Glob n)) alt
570+ alt' <- irAlt top vs (LV (Glob n)) alt
567 return $ case namesBoundIn alt' `usedIn` subexpr alt' of
571 return $ case namesBoundIn alt' `usedIn` subexpr alt' of
568 [] -> subexpr alt' -- strip the unused top-most case
572 [] -> subexpr alt' -- strip the unused top-most case
569 _ -> LCase up (LV (Glob n)) [alt']
573 _ -> LCase up (LV (Glob n)) [alt']
@@ -594,13 +598,13 @@ irSC vs (Case up n [alt]) = do
594-- This work-around is not entirely optimal; the best approach would be
598-- This work-around is not entirely optimal; the best approach would be
595-- to ensure that such case trees don't arise in the first place.
599-- to ensure that such case trees don't arise in the first place.
597−irSC vs (Case up n alts@[ConCase cn a ns sc, DefaultCase sc']) = do
601+irSC top vs (Case up n alts@[ConCase cn a ns sc, DefaultCase sc']) = do
598 detag <- fgetState (opt_detaggable . ist_optimisation cn)
602 detag <- fgetState (opt_detaggable . ist_optimisation cn)
600− then irSC vs (Case up n [ConCase cn a ns sc])
604+ then irSC top vs (Case up n [ConCase cn a ns sc])
601− else LCase up (LV (Glob n)) <$> mapM (irAlt vs (LV (Glob n))) alts
605+ else LCase up (LV (Glob n)) <$> mapM (irAlt top vs (LV (Glob n))) alts
603−irSC vs sc@(Case up n alts) = do
607+irSC top vs sc@(Case up n alts) = do
604 -- check that neither alternative needs the newtype optimisation,
608 -- check that neither alternative needs the newtype optimisation,
605 -- see comment above
609 -- see comment above
606 goneWrong <- or <$> mapM isDetaggable alts
610 goneWrong <- or <$> mapM isDetaggable alts
@@ -608,20 +612,20 @@ irSC vs sc@(Case up n alts) = do
608 $ ifail ("irSC: non-trivial case-match on detaggable data: " ++ show sc)
612 $ ifail ("irSC: non-trivial case-match on detaggable data: " ++ show sc)
610 -- everything okay
614 -- everything okay
611− LCase up (LV (Glob n)) <$> mapM (irAlt vs (LV (Glob n))) alts
615+ LCase up (LV (Glob n)) <$> mapM (irAlt top vs (LV (Glob n))) alts
613 isDetaggable (ConCase cn _ _ _) = fgetState $ opt_detaggable . ist_optimisation cn
617 isDetaggable (ConCase cn _ _ _) = fgetState $ opt_detaggable . ist_optimisation cn
614 isDetaggable _ = return False
618 isDetaggable _ = return False
616−irSC vs ImpossibleCase = return LNothing
620+irSC top vs ImpossibleCase = return LNothing
618−irAlt :: Vars -> LExp -> CaseAlt -> Idris LAlt
622+irAlt :: Name -> Vars -> LExp -> CaseAlt -> Idris LAlt
620-- this leaves out all unused arguments of the constructor
624-- this leaves out all unused arguments of the constructor
621−irAlt vs _ (ConCase n t args sc) = do
625+irAlt top vs _ (ConCase n t args sc) = do
622 used <- map fst <$> fgetState (cg_usedpos . ist_callgraph n)
626 used <- map fst <$> fgetState (cg_usedpos . ist_callgraph n)
623 let usedArgs = [a | (i,a) <- zip [0..] args, i `elem` used]
627 let usedArgs = [a | (i,a) <- zip [0..] args, i `elem` used]
624− LConCase (-1) n usedArgs <$> irSC (methodVars `M.union` vs) sc
628+ LConCase (-1) n usedArgs <$> irSC top (methodVars `M.union` vs) sc
626 methodVars = case n of
630 methodVars = case n of
627 SN (InstanceCtorN className)
631 SN (InstanceCtorN className)
@@ -631,9 +635,9 @@ irAlt vs _ (ConCase n t args sc) = do
632 -> M.empty -- not an instance constructor
636 -> M.empty -- not an instance constructor
634−irAlt vs _ (ConstCase x rhs)
638+irAlt top vs _ (ConstCase x rhs)
635− | matchable x = LConstCase x <$> irSC vs rhs
639+ | matchable x = LConstCase x <$> irSC top vs rhs
636− | matchableTy x = LDefaultCase <$> irSC vs rhs
640+ | matchableTy x = LDefaultCase <$> irSC top vs rhs
638 matchable (I _) = True
642 matchable (I _) = True
639 matchable (BI _) = True
643 matchable (BI _) = True
@@ -657,14 +661,14 @@ irAlt vs _ (ConstCase x rhs)
658 matchableTy _ = False
662 matchableTy _ = False
660−irAlt vs tm (SucCase n rhs) = do
664+irAlt top vs tm (SucCase n rhs) = do
661− rhs' <- irSC vs rhs
665+ rhs' <- irSC top vs rhs
662 return $ LDefaultCase (LLet n (LOp (LMinus (ATInt ITBig))
666 return $ LDefaultCase (LLet n (LOp (LMinus (ATInt ITBig))
664 LConst (BI 1)]) rhs')
668 LConst (BI 1)]) rhs')
666−irAlt vs _ (ConstCase c rhs)
670+irAlt top vs _ (ConstCase c rhs)
667 = ifail $ "Can't match on (" ++ show c ++ ")"
671 = ifail $ "Can't match on (" ++ show c ++ ")"
669−irAlt vs _ (DefaultCase rhs)
673+irAlt top vs _ (DefaultCase rhs)
670− = LDefaultCase <$> irSC vs rhs
674+ = LDefaultCase <$> irSC top vs rhs