[MLton-commit] r7219

Matthew Fluet fluet at mlton.org
Sun Aug 2 15:25:04 PDT 2009


Changelog entry; tweak documentation and eliminate eol whitespace.
----------------------------------------------------------------------

U   mlton/trunk/doc/changelog
U   mlton/trunk/mlton/ssa/combine-conversions.fun

----------------------------------------------------------------------

Modified: mlton/trunk/doc/changelog
===================================================================
--- mlton/trunk/doc/changelog	2009-07-26 15:26:46 UTC (rev 7218)
+++ mlton/trunk/doc/changelog	2009-08-02 22:25:03 UTC (rev 7219)
@@ -62,6 +62,9 @@
     * Eliminated top-level 'type int = Int.int' in output.
     * Include (*#line line:col "file.grm" *) directives in output.
 
+* 2009-07-10
+  - Added combine conversions SSA optimization.
+
 * 2009-06-09
    - Removed deprecated command line switch -show-anns {false, true}.
 

Modified: mlton/trunk/mlton/ssa/combine-conversions.fun
===================================================================
--- mlton/trunk/mlton/ssa/combine-conversions.fun	2009-07-26 15:26:46 UTC (rev 7218)
+++ mlton/trunk/mlton/ssa/combine-conversions.fun	2009-08-02 22:25:03 UTC (rev 7219)
@@ -10,61 +10,66 @@
 open S
 
 (*
- * This pass looks for nested calls to (signed) extension/truncation.
+ * This pass looks for and simplifies nested calls to (signed)
+ * extension/truncation.
  *
- * It processes each block in dfs order: (to visit definition before uses)
+ * It processes each block in dfs order (visiting defs before uses):
  *   If the statement is not a PrimApp Word_extdToWords, skip it.
- *   After processing a conversion, it tags the Var for subsequent use.
- *   When inspecting a conversion, check if the Var operated on is also the
- *   result of a conversion. If it is, try to combine the two operations.
- *   Repeatedly simplify until hitting either a non-conversion Var or a
- *   case where the conversions cause an effect.
+ *   After processing a conversion, it tags the Var for subsequent
+ *   use.
+ *   When inspecting a conversion, check if the Var operand is also
+ *   the result of a conversion.  If it is, try to combine the two
+ *   operations.  Repeatedly simplify until hitting either a
+ *   non-conversion Var or a case where the conversion cannot be
+ *   simplified.
  *
  * The optimization rules are very simple:
- *    x1 = ...
- *    x2 = Word_extdToWord (W1, W2, {signed=s1}) x1
- *    x3 = Word_extdToWord (W2, W3, {signed=s2}) x2
+ *    x1 : word<W1> = ...
+ *    x2 : word<W2> = Word_extdToWord (W1, W2, {signed=s1}) x1
+ *    x3 : word<W3> = Word_extdToWord (W2, W3, {signed=s2}) x2
  *
- *    W1 = width(x1), W2 = width(x2), W3 = width(x3)
- *    
- *    If W1=W2, then there is no conversions before x_1.
- *    This is guaranteed because W2=W3 will always trigger optimization.
- *    
+ *    If W1 = W2, then there is no conversions before x_1.
+ *    This is guaranteed because W2 = W3 will always trigger optimization.
+ *
  *    Case W1 <= W3 <= W2:
  *       x3 = Word_extdToWord (W1, W3, {signed=s1}) x1
- *    Case W1 <  W2 <  W3 AND (NOT signed1 OR signed2): 
+ *    Case W1 <  W2 <  W3 AND (NOT s1 OR s2):
  *       x3 = Word_extdToWord (W1, W3, {signed=s1}) x1
- *    Case W1 =  W2 <  W3
- *       do nothing; there are no conversions past W1 and x2 = x1.
+ *    Case W1 =  W2 <  W3:
+ *       unoptimized
+ *       because there are no conversions past W1 and x2 = x1
  *
- *    Case W3 <= W2 <= W1:                             ]
- *       x_3 = Word_extdToWord (W1, W3, {whatever}) x1 ]  W3 <= W1 && W3 <= W2
- *    Case W3 <= W1 <= W2:                             ]  just clip x1
- *       x_3 = Word_extdToWord (W1, W3, {whatever}) x1 ]
+ *    Case W3 <= W2 <= W1:
+ *    Case W3 <= W1 <= W2:
+ *       x_3 = Word_extdToWord (W1, W3, {signed=_}) x1
+ *       because W3 <= W1 && W3 <= W2, just clip x1
  *
- *    Case W2 < W1 <= W3: unoptimized   ] W2 < W1 && W2 < W3
- *    Case W2 < W3 <= W1: unoptimized   ] has side-effect: truncation
+ *    Case W2 < W1 <= W3:
+ *    Case W2 < W3 <= W1:
+ *       unoptimized
+ *       because W2 < W1 && W2 < W3, has truncation effect
  *
- *    Case W1 < W2 < W3 AND signed1 AND (NOT signed2): unoptimized
- *       ... each conversion affects the result separately
+ *    Case W1 < W2 < W3 AND s1 AND (NOT s2):
+ *       unoptimized
+ *       because each conversion affects the result separately
  *)
 
-val { get, set, ... } = 
+val { get, set, ... } =
    Property.getSetOnce (Var.plist, Property.initConst NONE)
 
 fun rules x3 (conversion as ((W2, W3, {signed=s2}), x2)) =
    let
       val { <, <=, ... } = Relation.compare WordSize.compare
-      
+
       fun stop () = set (x3, SOME conversion)
-      fun loop ((W1, _, {signed=s1}), x1) = 
+      fun loop ((W1, _, {signed=s1}), x1) =
          rules x3 ((W1, W3, {signed=s1}), x1)
    in
       case get x2 of
          NONE => stop ()
        | SOME (prev as ((W1, _, {signed=s1}), _)) =>
             if W1 <= W3 andalso W3 <= W2 then loop prev else
-            if W1 <  W2 andalso W2 <  W3 andalso (not s1 orelse s2) 
+            if W1 <  W2 andalso W2 <  W3 andalso (not s1 orelse s2)
                then loop prev else
             if W3 <= W1 andalso W3 <= W2 then loop prev else
             (* If W2=W3, we never reach here *)
@@ -89,8 +94,8 @@
             SOME (SOME (prim as (W2, W3, _), x2)) =>
                if WordSize.equals (W2, W3)
                then Exp.Var x2
-               else Exp.PrimApp { args  = Vector.new1 x2, 
-                                  prim  = Prim.wordExtdToWord prim, 
+               else Exp.PrimApp { args  = Vector.new1 x2,
+                                  prim  = Prim.wordExtdToWord prim,
                                   targs = Vector.new0 () }
           | _ => exp
    in
@@ -101,8 +106,8 @@
    let
       val Program.T { datatypes, functions, globals, main } = program
       val shrink = shrinkFunction {globals = globals}
-      
-      val functions = 
+
+      val functions =
          List.revMap
          (functions, fn f =>
           let
@@ -110,11 +115,11 @@
              fun markBlock (Block.T {statements, ... }) =
                 (Vector.foreach (statements, markStatement); fn () => ())
              val () = Function.dfs (f, markBlock)
-             
+
              (* Map the statements using the marks *)
              val {args, blocks, mayInline, name, raises, returns, start} =
                 Function.dest f
-             
+
              fun mapBlock block =
                 let
                    val Block.T {args, label, statements, transfer} = block
@@ -124,7 +129,7 @@
                             statements = Vector.map (statements, mapStatement),
                             transfer = transfer}
                 end
-             
+
              val f =
                 Function.new {args = args,
                               blocks = Vector.map (blocks, mapBlock),
@@ -133,17 +138,17 @@
                               raises = raises,
                               returns = returns,
                               start = start}
-             
+
              val f = shrink f
           in
              f
           end)
-      
+
       val () = Vector.foreach (globals, Statement.clear)
    in
-      Program.T { datatypes = datatypes, 
-                  functions = functions, 
-                  globals = globals, 
+      Program.T { datatypes = datatypes,
+                  functions = functions,
+                  globals = globals,
                   main = main }
    end
 




More information about the MLton-commit mailing list