CPS shrinking

Matthew Fluet mfluet@intertrust.com
Fri, 13 Jul 2001 09:29:37 -0700 (PDT)


I was working on eliminating extraneous compares, and I found the
following:

   fun L_39 () =
      let
	 val x_13 = Int_quot (x_139, global_15)
	 val x_138 = MLton_eq (x_13, global_12)
      in
	 case x_138 of
	   false => L_84 | true => L_40
      end
   fun L_140 () =
      let
	 val x_141 = String_sub (global_17, x_143)
	 val chars_0 = ::_3 (x_142, x_141)
	 val x_140 = MLton_eq (x_139, global_28)
      in
	 case x_140 of
	   false => L_39 | true => L_39
      end

The backend is eliminating the transfer at the end of L_140, because both
branches are the same, combining L_140 with L_39, which makes the
comparision MLton_eq(x_139, global_28) extraneous.  I only save the
comparision, because x_139 is still live after the comparison, but I think
I've seen examples before where the comparision operands are dead, which
could lead to further optimizations (although I'm not iterating to a fixed
point on eliminating dead code).

Anyways, I think the above could best be taken care of in CPS.  I think
what essentially happened was the following function was inlined:

      fun quot (x, y) =
	 if y = 0
	    then raise Div
	 else if detectOverflow andalso x = minInt' andalso y = ~1
		 then raise Overflow
	      else Int.quot (x, y)

and constant propagation and evaluation (with y = 10) simplified it, but
for some reason didn't combine the resulting branches.