[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