Skip to content

Commit 68c6fe2

Browse files
redfish64gallais
andauthored
[ Fix #1577 ] Actually use natMinus hack (#1578)
And also make sure that the output is truncated to 0. Co-authored-by: Guillaume ALLAIS <[email protected]>
1 parent f3177e0 commit 68c6fe2

File tree

8 files changed

+106
-10
lines changed

8 files changed

+106
-10
lines changed

libs/prelude/Prelude/Types.idr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ prim__integerToNat i
3333

3434
public export
3535
integerToNat : Integer -> Nat
36-
integerToNat 0 = Z -- Force evaluation and hencing caching of x at compile time
36+
integerToNat 0 = Z -- Force evaluation and hence caching of x at compile time
3737
integerToNat x
3838
= if intToBool (prim__lte_Integer x 0)
3939
then Z

src/Compiler/CompileExpr.idr

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,21 +176,32 @@ magic ms e = go ms e where
176176
Nothing => go ms e
177177
Just e' => e'
178178

179-
natMinus : FC -> FC -> forall vars. Vect 2 (CExp vars) -> CExp vars
180-
natMinus fc fc' [m,n] = CApp fc (CRef fc' (UN "prim__sub_Integer")) [m, n]
179+
%inline
180+
magic__integerToNat : FC -> FC -> forall vars. Vect 1 (CExp vars) -> CExp vars
181+
magic__integerToNat fc fc' [k]
182+
= CApp fc (CRef fc' (NS typesNS (UN "prim__integerToNat"))) [k]
183+
184+
magic__natMinus : FC -> FC -> forall vars. Vect 2 (CExp vars) -> CExp vars
185+
magic__natMinus fc fc' [m,n]
186+
= magic__integerToNat fc fc'
187+
[CApp fc (CRef fc' (UN "prim__sub_Integer")) [m, n]]
188+
189+
-- We don't reuse natMinus here because we assume that unsuc will only be called
190+
-- on S-headed numbers so we do not need the truncating integerToNat call!
191+
magic__natUnsuc : FC -> FC -> forall vars. Vect 1 (CExp vars) -> CExp vars
192+
magic__natUnsuc fc fc' [m]
193+
= CApp fc (CRef fc' (UN "prim__sub_Integer")) [m, CPrimVal fc (BI 1)]
181194

182195
-- TODO: next release remove this and use %builtin pragma
183196
natHack : List Magic
184197
natHack =
185-
[ MagicCRef (NS typesNS (UN "natToInteger")) 1
186-
(\ _, _, [k] => k)
187-
, MagicCRef (NS typesNS (UN "integerToNat")) 1
188-
(\ fc, fc', [k] => CApp fc (CRef fc' (NS typesNS (UN "prim__integerToNat"))) [k])
198+
[ MagicCRef (NS typesNS (UN "natToInteger")) 1 (\ _, _, [k] => k)
199+
, MagicCRef (NS typesNS (UN "integerToNat")) 1 magic__integerToNat
189200
, MagicCRef (NS typesNS (UN "plus")) 2
190201
(\ fc, fc', [m,n] => CApp fc (CRef fc' (UN "prim__add_Integer")) [m, n])
191202
, MagicCRef (NS typesNS (UN "mult")) 2
192203
(\ fc, fc', [m,n] => CApp fc (CRef fc' (UN "prim__mul_Integer")) [m, n])
193-
, MagicCRef (NS natNS (UN "minus")) 2 natMinus
204+
, MagicCRef (NS typesNS (UN "minus")) 2 magic__natMinus
194205
]
195206

196207
-- get all transformation from %builtin pragmas
@@ -237,7 +248,7 @@ trySBranch :
237248
trySBranch ss n (MkConAlt nm _ _ [arg] sc)
238249
= do guard $ isJust $ lookup nm ss
239250
let fc = getFC n
240-
pure (CLet fc arg True (natMinus fc fc [n, CPrimVal fc (BI 1)]) sc)
251+
pure (CLet fc arg True (magic__natUnsuc fc fc [n]) sc)
241252
trySBranch _ _ _ = Nothing
242253

243254
tryZBranch :

src/Idris/Package.idr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ partitionOpts opts = foldr pOptUpdate (MkPFR [] [] False) opts
711711
optType (OutputDir f) = POpt
712712
optType WarningsAsErrors = POpt
713713
optType HashesInsteadOfModTime = POpt
714+
optType Profile = POpt
714715
optType (ConsoleWidth n) = PIgnore
715716
optType (Color b) = PIgnore
716717
optType NoBanner = PIgnore

tests/Main.idr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ idrisTestsRegression = MkTestPool "Various regressions" []
123123
"reg015", "reg016", "reg017", "reg018", "reg019", "reg020", "reg021",
124124
"reg022", "reg023", "reg024", "reg025", "reg026", "reg027", "reg028",
125125
"reg029", "reg030", "reg031", "reg032", "reg033", "reg034", "reg035",
126-
"reg036", "reg037", "reg038", "reg039", "reg040", "reg041"]
126+
"reg036", "reg037", "reg038", "reg039", "reg040", "reg041", "reg042"]
127127

128128
idrisTestsData : TestPool
129129
idrisTestsData = MkTestPool "Data and record types" []

tests/idris2/reg042/NatSpeedBug.idr

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module NatSpeedBug
2+
3+
import System
4+
import System.Clock
5+
import Data.List
6+
import Data.Nat
7+
import Data.String
8+
9+
timeit : Lazy x -> IO (x,Clock Duration)
10+
timeit x =
11+
do
12+
start <- clockTime Monotonic
13+
let x' = force x
14+
end <- clockTime Monotonic
15+
pure (x', timeDifference end start)
16+
17+
v1 : Nat
18+
v1 = 100000000
19+
20+
v2 : Nat
21+
v2 = 100000000
22+
23+
v3 : Nat
24+
v3 = 100000001
25+
26+
test : List (Lazy Bool)
27+
test =
28+
[
29+
--fast ops
30+
delay $ (natToInteger $ v1 + v2) == 200000000
31+
,delay $ (natToInteger $ 2 * v1) == 200000000
32+
,delay $ (v1 `minus` v2) == 0 --should be fast, but is slow
33+
,delay $ (natToInteger v1) == 100000000
34+
,delay $ const True (integerToNat 100000000)
35+
]
36+
37+
toNano : Clock type -> Integer
38+
toNano (MkClock seconds nanoseconds) =
39+
let scale = 1000000000
40+
in scale * seconds + nanoseconds
41+
42+
main : IO ()
43+
main =
44+
do
45+
cutOff <- getCutoffArg
46+
ignore $ traverse (prnIt cutOff) (zip [0..length test] test)
47+
pure ()
48+
where
49+
getCutoffArg : IO (Maybe Integer)
50+
getCutoffArg =
51+
do
52+
args <- getArgs
53+
let (_ :: cutoffStr :: _) = args
54+
| x => pure Nothing
55+
let cutOff = cast $ stringToNatOrZ cutoffStr
56+
pure $ if cutOff == 0 then Nothing else Just cutOff
57+
58+
showit : Bool -> String -> String -> String
59+
showit v a b = if v then a else b
60+
prnIt : (Maybe Integer) -> (Nat, Lazy Bool) -> IO ()
61+
prnIt mCutOff (ind, lb) =
62+
do
63+
(b, diff) <- timeit lb
64+
putStrLn $ (show ind) ++ ": " ++ showit b "Pass" "Fail" ++ " " ++
65+
maybe
66+
(show diff)
67+
(\co => showit (toNano diff < co) "Fast" "Slow")
68+
mCutOff

tests/idris2/reg042/expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
1/1: Building NatSpeedBug (NatSpeedBug.idr)
2+
0: Pass Fast
3+
1: Pass Fast
4+
2: Pass Fast
5+
3: Pass Fast
6+
4: Pass Fast

tests/idris2/reg042/nsb.ipkg

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package nsb
2+
3+
modules = NatSpeedBug
4+
5+
executable = nsb
6+
main = NatSpeedBug

tests/idris2/reg042/run

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
$1 --build nsb.ipkg
2+
build/exec/nsb 100000
3+
4+
rm -rf build

0 commit comments

Comments
 (0)