Closed shwestrick closed 4 weeks ago
I decided to fix it with the easy solution: adding val ((), ()) = ForkJoin.pcallFork (fn () => (), fn () => ())
to the bottom of the scheduler as mentioned above.
Adding a use of ForkJoin.pcallFork
seems reasonable. Dropping the PCall_forkThreadAndSetData
primitive when the data argument is unit
would also be acceptable; if the data argument is unit
then there must not be any pcall
s in the program and the PCall_forkThreadAndSetData
will never execute (because it is downstream of a conditional that checks for a promotable frame, of which there will be none).
On Ubuntu 20.04, commit ef2588b3a3ba1b5dca8f2c472a7c7f2250021596 (current
main
).As far as I can tell, this happens when the scheduler is loaded but
ForkJoin.par
is never used in the program.Minimal example
foo.sml
foo.mlb
Compiling
foo.mlb
raises an exceptionDigging
As far as I can tell, the bug happens when the scheduler is loaded but never used. (If I change the source in the above example to use
ForkJoin.par
, then it works; alternatively, if I don't load$(SML_LIB)/basis/fork-join.mlb
at all, then it also works.)I've confirmed that the bug is here: the call
a 1
in turn callsvarOp
which raisesOption
.In the generated SSA2, we see this:
This makes sense? If we load the scheduler but don't use it, then there won't be any calls to
PCall_getData
, and therefore all data that flows throughPCall_forkThreadAndSetData
would be useless and could be eliminated.Solution?
An easy fix might be to case on the RType for arg 1 of
PCall_forkThreadAndSetData
and just eliminate the prim call entirely in this case.Alternatively, I've confirmed that if we add
val ((), ()) = ForkJoin.pcallFork (fn () => (), fn () => ())
to the bottom ofMkScheduler.sml
, then the issue goes away, because this ensures that there's always at least one use ofPCall_getData
. Maybe this is easiest...