Skip to content

Commit

Permalink
[ fix ] Fix issue with eager evaluation of crashing functions (fixes #…
Browse files Browse the repository at this point in the history
…3003) (#3004)

* [ fix ] Fix issue with eager evaluation of crashing functions

* Mark functions that call unsafe builtins as non-constant

* Better detection of crash primop when deciding if functions can be constant
  • Loading branch information
dunhamsteve authored Jun 28, 2023
1 parent 5dcf624 commit ecf4765
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 3 deletions.
18 changes: 16 additions & 2 deletions src/Compiler/Opts/ToplevelConstants.idr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Libraries.Data.SortedMap
-- Call Graph
--------------------------------------------------------------------------------

-- direct calls from a top-level funtion's expression to other
-- direct calls from a top-level function's expression to other
-- top-level functions.
0 CallGraph : Type
CallGraph = SortedMap Name (SortedSet Name)
Expand Down Expand Up @@ -71,6 +71,7 @@ data SortTag : Type where
record SortST where
constructor SST
processed : SortedSet Name
nonconst : SortedSet Name
triples : SnocList (Name, FC, NamedDef)
map : SortedMap Name (Name, FC, NamedDef)
graph : CallGraph
Expand All @@ -94,6 +95,15 @@ markProcessed n = do
isProcessed : Ref SortTag SortST => Name -> Core Bool
isProcessed n = map (contains n . processed) (get SortTag)

checkCrash : Ref SortTag SortST => (Name, FC, NamedDef) -> Core ()
checkCrash (n, _, MkNmError _) = update SortTag $ { nonconst $= insert n }
checkCrash (n, _, MkNmFun args (NmCrash _ _)) = update SortTag $ { nonconst $= insert n }
checkCrash (n, _, MkNmFun args (NmOp _ Crash _)) = update SortTag $ { nonconst $= insert n }
checkCrash (n, _, def) = do
st <- get SortTag
when (any (flip contains st.nonconst) !(getCalls n)) $
put SortTag $ { nonconst $= insert n } st

sortDef : Ref SortTag SortST => Name -> Core ()
sortDef n = do
False <- isProcessed n | True => pure ()
Expand All @@ -102,6 +112,7 @@ sortDef n = do
traverse_ sortDef cs
Just t <- getTriple n | Nothing => pure ()
appendDef t
checkCrash t

isConstant : (recursiveFunctions : SortedSet Name) -> (Name,FC,NamedDef) -> Bool
isConstant rec (n, _, MkNmFun [] _) = not $ contains n rec
Expand All @@ -115,12 +126,15 @@ sortDefs ts =
consts := map fst $ filter (isConstant rec) ts
init := SST {
processed = empty
, nonconst = empty
, triples = Lin
, map = fromList (map (\t => (fst t, t)) ts)
, graph = graph
}
in do
s <- newRef SortTag init
traverse_ sortDef (map fst ts)
sorted <- map ((<>> []) . triples) (get SortTag)
st <- get SortTag
let sorted = triples st <>> []
let consts = filter (not . flip contains (nonconst st)) consts
pure (sorted, fromList consts)
2 changes: 1 addition & 1 deletion tests/Main.idr
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ chezTests = MkTestPool "Chez backend" [] (Just Chez)
, "chez013", "chez014", "chez015", "chez016", "chez017", "chez018"
, "chez019", "chez020", "chez021", "chez022", "chez023", "chez024"
, "chez025", "chez026", "chez027", "chez028", "chez029", "chez030"
, "chez031", "chez032", "chez033", "chez034", "chez035"
, "chez031", "chez032", "chez033", "chez034", "chez035", "chez036"
, "futures001"
, "bitops"
, "casts"
Expand Down
14 changes: 14 additions & 0 deletions tests/chez/chez036/Crash.idr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- no_clauses.idr
%default total

bad : (0 _ : Z = S Z) -> Void
bad _ impossible

data BadPrf = Ok | No (Z = S Z)

Show BadPrf where
show Ok = "Ok"
show (No prf) = absurd $ bad prf

main : IO ()
main = printLn Ok
15 changes: 15 additions & 0 deletions tests/chez/chez036/Crash2.idr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
%noinline
foo : (0 _ : Z = S Z) -> Void
foo _ impossible

%noinline
bah : (0 _ : Z = S Z) -> Void
bah prf = foo prf
data BadPrf = Ok | No (Z = S Z)

Show BadPrf where
show Ok = "Ok"
show (No prf) = absurd $ bah prf

main : IO ()
main = printLn Ok
9 changes: 9 additions & 0 deletions tests/chez/chez036/Crash3.idr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import System
partial
unreachable : a
unreachable = idris_crash "unreachable"

main : IO Int
main = do
exitSuccess
assert_total unreachable
2 changes: 2 additions & 0 deletions tests/chez/chez036/expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Ok
Ok
5 changes: 5 additions & 0 deletions tests/chez/chez036/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$1 --no-banner --no-color --console-width 0 --exec main Crash.idr
$1 --no-banner --no-color --console-width 0 --exec main Crash2.idr
$1 --no-banner --no-color --console-width 0 --exec main Crash3.idr

rm -rf build

0 comments on commit ecf4765

Please sign in to comment.