MLton.size bug
Matthew Fluet
Matthew Fluet <fluet@CS.Cornell.EDU>
Fri, 27 Apr 2001 10:57:27 -0400 (EDT)
> One thing we have to do is to figure why the hash table size is zero in the
> compiler -v3 output. I'm not sure whether it's for the same reason as your
> example above or some other funny interaction with the useless analysis. If the
> former, then we may need to rethink size altogether.
I believe that it because of the remove-useless pass. I tried the
following program:
val table = HashSet.new {hash = Word.fromInt}
fun fill 0 = ()
| fill n = let
val _ = HashSet.lookupOrInsert(table,
Word.fromInt n,
fn _ => false,
fn () => n)
in
fill (n - 1)
end
val _ = fill 1000
val table_size = HashSet.size table
val _ = print (concat ["table_size: ", Int.toString table_size, "\n"])
val table_fold = HashSet.fold (table, 0, op +)
val _ = print (concat ["table_fold: ", Int.toString table_fold, "\n"])
val _ = HashSet.remove(table, fn i => i mod 2 = 0)
val table_forall = HashSet.forall(table, fn i => i mod 2 = 1)
val _ = print (concat ["table_forall: ", Bool.toString table_forall, "\n"])
val r = ref (0: Int.int)
val _ = HashSet.foreach(table, fn i => r := !r + i)
val _ = print (concat ["!r: ", Int.toString (!r), "\n"])
val table_layout = HashSet.layout Int.layout table
val _ = Layout.output(table_layout, TextIO.stdOut)
val _ = print "\n"
val table_stats = HashSet.stats ()
val _ = Layout.output(table_stats, TextIO.stdOut)
val _ = print "\n"
val table_peek = HashSet.peek(table, Word.fromInt 123, fn _ => true)
val _ = print (concat ["table_peek: ",
case table_peek
of NONE => "NONE"
| SOME i => concat ["SOME ", Int.toString i], "\n"])
val s = MLton.size table
val _ = print (concat ["s: ", Int.toString s, "\n"])
The important part is that I call every HashSet function and print the
resulting values -- so that should maximize the usefull and used values.
Looking at the cps after each simplification pass, I see that before the
first remove-unused, we have:
t_380 = T_59 of ((list_7 array ref * lambdas_85 * word ref * int ref))
val x_71316: int = MLton_size(t_380) (x_71315)
and after the first remove-unused, we have:
t_380 = dummy_62
val x_71316: int = MLton_size(t_380) (x_71315)
So, by the time the useless analysis is run, we've already forced the
MLton_size call to return 0.