20 |
structure F = FieldDef |
structure F = FieldDef |
21 |
|
|
22 |
(********** Counters for statistics **********) |
(********** Counters for statistics **********) |
23 |
val cntConstConvolve = ST.newCounter "high-opt:const-convolve" |
val cntProbeAdd = ST.newCounter "high-opt:probe-add" |
24 |
val cntConstField = ST.newCounter "high-opt:const-field" |
val cntProbeScale = ST.newCounter "high-opt:probe-scale" |
25 |
val cntConstDiff = ST.newCounter "high-opt:const-diff" |
val cntProbeNeg = ST.newCounter "high-opt:probe-neg" |
26 |
|
val cntDiffField = ST.newCounter "high-opt:diff-field" |
27 |
|
val cntDiffAdd = ST.newCounter "high-opt:diff-add" |
28 |
|
val cntDiffScale = ST.newCounter "high-opt:diff-scale" |
29 |
|
val cntDiffNeg = ST.newCounter "high-opt:diff-neg" |
30 |
val cntUnused = ST.newCounter "high-opt:unused" |
val cntUnused = ST.newCounter "high-opt:unused" |
31 |
val firstCounter = cntConstConvolve |
val firstCounter = cntProbeAdd |
32 |
val lastCounter = cntUnused |
val lastCounter = cntUnused |
33 |
|
|
34 |
fun useCount (IL.V{useCnt, ...}) = !useCnt |
fun useCount (IL.V{useCnt, ...}) = !useCnt |
35 |
|
|
36 |
(* decrement a variable's use count *) |
(* adjust a variable's use count *) |
37 |
|
fun incUse (IL.V{useCnt, ...}) = (useCnt := !useCnt + 1) |
38 |
fun decUse (IL.V{useCnt, ...}) = (useCnt := !useCnt - 1) |
fun decUse (IL.V{useCnt, ...}) = (useCnt := !useCnt - 1) |
39 |
|
|
40 |
fun getRHS x = (case V.binding x |
fun getRHS x = (case V.binding x |
43 |
(* end case *)) |
(* end case *)) |
44 |
|
|
45 |
(* optimize the rhs of an assignment, returning NONE if there is no change *) |
(* optimize the rhs of an assignment, returning NONE if there is no change *) |
46 |
(* |
fun doRHS (lhs, IL.OP rhs) = (case rhs |
47 |
fun doRHS rhs = (case rhs |
of (Op.Probe(domTy, rngTy), [f, pos]) => (case getRHS f |
48 |
of IL.OP(Op.DiffField, [f]) => (case (getRHS f) |
of SOME(Op.Field _, _) => NONE (* direct probe does not need rewrite *) |
49 |
of SOME(Op.Field(img, h), []) => (case getRHS h |
| SOME(Op.AddField, [f, g]) => raise Fail "Probe(f+g)" |
50 |
ST.tick cntConstDiff; |
| SOME(Op.ScaleField, [s, f]) => raise Fail "Probe(s*f)" |
51 |
decUse f; |
| SOME(Op.NegField, [f]) => raise Fail "Probe(-f)" |
52 |
SOME(IL.OP(Op.Field(F.diff f'), []))) |
| _ => raise Fail(concat[ |
53 |
| IL.OP(Op.AddField, [f, g]) => (case (getRHS f, getRHS g) |
"bogus field binding ", V.toString f, " = ", IL.vbToString(V.binding f) |
54 |
of (SOME(Op.Field f', []), SOME(Op.Field g', [])) => ( |
]) |
55 |
ST.tick cntConstField; |
(* end case *)) |
56 |
decUse f; decUse g; |
| (Op.DiffField, [f]) => (case (getRHS f) |
57 |
SOME(IL.OP(Op.Field(F.SUM(f', g')), []))) |
of SOME(Op.Field dim, [v, h]) => (case getRHS h |
58 |
| _ => NONE |
of SOME(Op.Kernel(kernel, k), []) => let |
59 |
(* end case *)) |
val h' = IL.Var.copy h |
60 |
| IL.OP(Op.NegField, [f]) => (case (getRHS f) |
in |
61 |
of SOME(Op.Field f', []) => ( |
ST.tick cntDiffField; |
|
ST.tick cntConstField; |
|
62 |
decUse f; |
decUse f; |
63 |
SOME(IL.OP(Op.Field(F.neg f'), []))) |
incUse h'; incUse v; |
64 |
|
SOME[ |
65 |
|
(h', IL.OP(Op.Kernel(kernel, k+1), [])), |
66 |
|
(lhs, IL.OP(Op.Field dim, [v, h'])) |
67 |
|
] |
68 |
|
end |
69 |
|
| _ => raise Fail(concat[ |
70 |
|
"bogus kernel binding ", V.toString h, " = ", IL.vbToString(V.binding h) |
71 |
|
]) |
72 |
|
(* end case *)) |
73 |
|
| SOME(Op.AddField, [f, g]) => raise Fail "Diff(f+g)" |
74 |
|
| SOME(Op.ScaleField, [s, f]) => raise Fail "Diff(s*f)" |
75 |
|
| SOME(Op.NegField, [f]) => raise Fail "Diff(-f)" |
76 |
| _ => NONE |
| _ => NONE |
77 |
(* end case *)) |
(* end case *)) |
|
| _ => raise Fail "non-constant DiffField" |
|
|
(* end case *)) |
|
78 |
| _ => NONE |
| _ => NONE |
79 |
(* end case *)) |
(* end case *)) |
80 |
*) |
| doRHS _ = NONE |
|
fun doRHS _ = NONE |
|
81 |
|
|
82 |
(* simplify expressions *) |
(* simplify expressions *) |
83 |
local |
fun simplify (nd as IL.ND{kind=IL.ASSIGN{stm=(y, rhs), ...}, ...}) = |
84 |
fun doAssign (y, rhs) = (case doRHS rhs |
if (useCount y = 0) |
85 |
of SOME rhs' => (V.setBinding(y, IL.VB_RHS rhs'); (y, rhs')) |
then () (* skip unused assignments *) |
86 |
| NONE => (y, rhs) |
else (case doRHS(y, rhs) |
87 |
(* end case *)) |
of SOME[] => IL.CFG.deleteNode nd |
88 |
in |
| SOME assigns => ( |
89 |
fun simplify (nd as IL.ND{kind=IL.ASSIGN{stm=(y, rhs), ...}, ...}) = (case doRHS rhs |
List.app (fn (y, rhs) => V.setBinding(y, IL.VB_RHS rhs)) assigns; |
90 |
of SOME rhs' => ( |
IL.CFG.splice (nd, IL.CFG.mkBlock assigns)) |
|
V.setBinding(y, IL.VB_RHS rhs'); |
|
|
IL.CFG.replaceNode (nd, IL.Node.mkASSIGN(y, rhs'))) |
|
91 |
| NONE => () |
| NONE => () |
92 |
(* end case *)) |
(* end case *)) |
93 |
| simplify _ = () |
| simplify _ = () |
|
end (* local *) |
|
94 |
|
|
95 |
(* reduce the code by removing variables with use counts of 0 *) |
(* reduce the code by removing variables with use counts of 0 *) |
96 |
local |
local |