[MLton] MinGW hosted MLton

Stephen Weeks MLton@mlton.org
Wed, 4 May 2005 08:04:37 -0700


> I suspect that the issue arises from the fact that the computation
> of useCwait is caught up in the closure of the wait function above
> and constant propagation isn't able to push the constant value of
> Primitive.MLton.Platform.OS.useWindowsProcess though to its use.

Close.  It's actually that useCwait gets caught in the closure for 
the argument to SysCall.restart.

	       (fn () =>
		let
		   val pid = 
		      if useCwait 
			 then Prim.cwait (Pid.fromInt p, status)
		      else Prim.waitpid (Pid.fromInt p, status,
					 SysWord.toInt flags)
               ...

I traced through the optimization passes and by the time MLton gets to
constant propagation the code looks like the following.

    x_3428: word32 = Pointer_getWord32 (x_2594, x_2595)
    x_3427: bool = Word32_equal (x_3428, x_2596)
    case x_3427 of
      false => L_22 | true => L_21
  L_21 ()
    L_29 (x_2517)
  L_22 ()
    L_29 (x_2517)
  L_29 (useWindowsProcess_1: bool)
...
  L_400 (x_3633: word32)
    case useWindowsProcess_1 of
      true => L_403 | false => L_402
  L_402 ()
    L_404 (x_3371)
  L_403 ()
    L_404 (x_3370)
  L_404 (useCwait_1: bool)
    x_3636 (x_3369) NonTail {cont = L_408, handler = Dead}
  L_408 (flags_3: word32)
    x_3638: (lambdas_9 * word32 * word32 * bool) = (x_3608,
						    flags_3,
						    x_3633,
						    useCwait_1)


The Pointer_getWord32 for x_3428 is looking up
MLton_Platform_CygwinUseMmap.  Then it is converted to a boolean by
comparing to zer0.  Of course, the value doesn't matter, since MLton's
already figured out that the host is Linux and hence both branches set
useWindowsProcess to true.  Of course, constant propagation determines
this -- unfortunately, constant propagation doesn't do any
simplification, so it can't tell that useCwait is true.  So, useCwait
gets stuck in the closure.  Sadly, the simplification pass that runs
immediately after constant propagation uses the fact that
useWindowsProcess is true to conclude that useCwait is false, as can
be seen by the "global_3" (false) in the output.

    x_3428: word32 = Pointer_getWord32 (x_2594, global_2)
    x_3427: bool = Word32_equal (x_3428, global_2)
    case x_3427 of
      false => L_22 | true => L_21
  L_21 ()
    L_29 (global_3)
  L_22 ()
    L_29 (global_3)
  L_29 (useWindowsProcess_1: bool)
...
  L_408 (flags_3: word32)
    x_3638: (lambdas_9 * word32 * word32 * bool) = (global_22,
						    flags_3,
						    x_3633,
						    global_3)

Unfortunately, there's only one round of whole-program constant
propagation, so MLton never connects the fact that only false is stuck
in the closure with the point where useCwait is extracted.  And so the
test on useCwait (and the call to Prim.cwait) remains.