diff options
author | Barry Wardell <barry.wardell@gmail.com> | 2011-03-03 23:40:57 +0100 |
---|---|---|
committer | Barry Wardell <barry.wardell@gmail.com> | 2011-03-16 17:44:03 +0100 |
commit | 1f9650ff6b63a1e75b5279e1f5e308fbeb8e82c6 (patch) | |
tree | 334726df0043119b94f08d453234f28f87c09653 /Tools/CodeGen/CodeGen.m | |
parent | b455f101396e5538e6f64d263e925b2c3b94000d (diff) |
Improved common subexpression elimination support.
Diffstat (limited to 'Tools/CodeGen/CodeGen.m')
-rw-r--r-- | Tools/CodeGen/CodeGen.m | 175 |
1 files changed, 0 insertions, 175 deletions
diff --git a/Tools/CodeGen/CodeGen.m b/Tools/CodeGen/CodeGen.m index e8175a1..197c6af 100644 --- a/Tools/CodeGen/CodeGen.m +++ b/Tools/CodeGen/CodeGen.m @@ -121,7 +121,6 @@ CommaNewlineSeparated::usage = ""; (* This should not really be in CodeGen *) CommaSeparated::usage = ""; ReplacePowers::usage = ""; CFormHideStrings::usage = ""; -CSE::usage = ""; BoundaryLoop::usage = ""; BoundaryWithGhostsLoop::usage = ""; GenericGridLoop::usage = ""; @@ -926,180 +925,6 @@ CFormHideStrings[x_, opts___] := StringReplace[ToString[CForm[x,opts]], "\"" -> -(* Debug output *) -DebugCSE = True; - -(* Eliminate common subexpressions in a code sequence *) -CSE[code_] := Module[ - {expr, optexpr, - decomposed, locals, block, - block1, block2, temps1, stmts1, stmts2, stmts3, - replacevar, - stmts4, - stmts5, stmts6, stmts7}, - if [DebugCSE, Print["code\n", code, "\nendcode\n"]]; - - (* The code is passed in as list of {lhs,rhs} tuples. Turn this - list into a single expression, so that it can be optimised. *) - expr = code //. {a_, b__} -> CSequence[a, {b}] - //. {a_} -> a - //. (a_ -> b_) -> CAssign[a, b]; - If [DebugCSE, Print["expr\n", expr, "\nendexpr\n"]]; - - (* Optimise this expression *) - optexpr = Experimental`OptimizeExpression[expr]; - If [DebugCSE, Print["optexpr\n", optexpr, "\nendoptexpr\n"]]; - - (* This expression is a Mathematica expression. Decompose it into - the set of newly introduced local variables and the optimised - expression itself. *) - decomposed = - ReleaseHold[(Hold @@ optexpr) - /. Verbatim[Block][vars_, seq_] :> {vars, Hold[seq]}]; - - If[decomposed[[0]] =!= List, - (* If the optimiser didn't create a Block expression, we assume it - didn't do anything useful and return the original. *) - code, - - {locals, block} = decomposed; - If [DebugCSE, Print["locals\n", locals, "\nendlocals\n"]]; - If [DebugCSE, Print["block\n", block, "\nendblock\n"]]; - - block1 = block /. Hold[CompoundExpression[seq__]] :> Hold[{seq}]; - If [DebugCSE, Print["block1\n", block1, "\nendblock1\n"]]; - block2 = First[block1 //. Hold[{a___Hold, b_, c___}] - /; Head[Unevaluated[b]] =!= Hold - :> Hold[{a, Hold[b], c}]]; - If [DebugCSE, Print["block2\n", block2, "\nendblock2\n"]]; - - (* Temporaries, including a fake declaration for them *) - temps1 = Most[block2] //. Hold[lhs_ = rhs_] -> CAssign[CDeclare[lhs], rhs]; - If [DebugCSE, Print["temps1\n", temps1, "\nendtemps1\n"]]; - - (* Expression *) - stmts1 = ReleaseHold[Last[block2]]; - If [DebugCSE, Print["stmts1\n", stmts1, "\nendstmts1\n"]]; - - (* Turn CSequence back into a list *) - stmts2 = Flatten[{stmts1} //. CSequence[a_,b_] -> {a,b}]; - If [DebugCSE, Print["stmts2\n", stmts2, "\nendstmts2\n"]]; - - (* Combine temporaries and expression *) - stmts3 = Join[temps1, stmts2]; - If [DebugCSE, Print["stmts3\n", stmts3, "\nendstmts3\n"]]; - - (* Replace the internal names of the newly generated temporaries - with legal C names *) - replacevar = - Rule @@@ Transpose[{(*ToString[CForm[#]] & /@*) locals, - Symbol[ - StringReplace[StringReplace[ToString[#], {__ ~~ "`" ~~ a_ :> a}], - "$" -> "T"]] & /@ locals}]; - If [DebugCSE, Print["replacevar\n", replacevar, "\nendreplacevar\n"]]; - - stmts4 = stmts3 //. replacevar; - If [DebugCSE, Print["stmts4\n", stmts4, "\nendstmts4\n"]]; - - (* Sort statements topologically *) -(* - stmts5 = stmts4; -*) - If [DebugCSE, Print["A\n"]]; - stmts5 = - Module[{debug, - tmpVars, newVars, i, - stmtsLeft, stmtsDone, - lhs, rhs, any, contains, containsAny, - canDoStmts, cannotDoStmts, - selfStmts, selfVars, allVars, nonSelfVars}, - debug = False; - stmtsLeft = stmts4; - If [DebugCSE, Print["B\n"]]; - stmtsDone = {}; - If [DebugCSE, Print["C\n"]]; - (* lhs[x_] := x[[1]]; *) - lhs[x_] := x /. (CAssign[lhs_, rhs_] -> lhs); - If [DebugCSE, Print["D\n"]]; - (* rhs[x_] := x[[2]]; *) - rhs[x_] := x /. (CAssign[lhs_, rhs_] -> rhs); - If [DebugCSE, Print["E\n"]]; - (* any[xs_] := Fold[Or, False, xs]; *) - any[xs_] := MemberQ[xs, True]; - If [DebugCSE, Print["F\n"]]; - (* contains[e_, x_] := (e /. x -> {}) =!= e; *) - (* contains[e_, x_] := Count[{e}, x, Infinity] > 0; *) - contains[e_, x_] := MemberQ[{e}, x, Infinity]; - If [DebugCSE, Print["G\n"]]; - containsAny[e_, xs_] := any[Map[contains[e,#]&, xs]]; - If [DebugCSE, Print["H\n"]]; - getVars[stmts_] := Map[lhs, stmts] //. (CDeclare[lhs_] -> lhs); - - (* Rename temporary variables deterministically *) - tmpVars = Select[getVars[stmtsLeft], - StringMatchQ[ToString[#], "TT"~~__]&]; - newVars = Table[Symbol["T"<>ToString[1000000+i]], - {i, 1, Length[tmpVars]}]; - stmtsLeft = stmtsLeft /. MapThread[(#1->#2)&, {tmpVars, newVars}]; - - allVars = getVars[stmtsLeft]; - While[stmtsLeft =!= {}, - If[debug, Print["stmtsLeft = \n", stmtsLeft]]; - If[debug, Print["stmtsDone = \n", stmtsDone]]; - allVars = getVars[stmtsLeft]; - If[debug, Print["allVars = \n", allVars]]; - canDoStmts = - Select[stmtsLeft, Not[containsAny[rhs[#], allVars]] &]; - cannotDoStmts = - Select[stmtsLeft, containsAny[rhs[#], allVars] &]; - If[debug, Print["canDoStmts = \n", canDoStmts]]; - If[debug, Print["cannotDoStmts = \n", cannotDoStmts]]; - If[False && canDoStmts == {}, - (* Handle assignment where LHS and RHS access the same variables - (hopefully without taking derivatives!) *) - selfStmts = Select[stmtsLeft, contains[rhs[#], lhs[#]]]; - selfVars = getVars[selfStmts]; - nonSelfVars = Select[allVars, Not[contains[selfVars, #]] &]; - canDoStmts = - Select[stmtsLeft, Not[containsAny[rhs[#], nonSelfVars]] &]; - cannotDoStmts = - Select[stmtsLeft, containsAny[rhs[#], nonSelfVars] &]; - If[debug, Print["nonself/canDoStmts = \n", canDoStmts]]; - If[debug, Print["nonself/cannotDoStmts = \n", cannotDoStmts]]; - ]; - If[canDoStmts == {}, - (* Accept the first statement *) - canDoStmts = {First[stmtsLeft]}; - cannotDoStmts = Rest[stmtsLeft]; - If[debug, Print["takeone/canDoStmts = \n", canDoStmts]]; - If[debug, Print["takeone/cannotDoStmts = \n", cannotDoStmts]]; - ]; - If[canDoStmts == {}, ThrowError["canDoStmts == {}"]]; - stmtsDone = Join[stmtsDone, canDoStmts]; - If [DebugCSE, Print["I\n"]]; - stmtsLeft = cannotDoStmts; - If [DebugCSE, Print["J\n"]]; - ]; - If[debug, Print["stmtsLeft\n", stmtsLeft]]; - If[debug, Print["stmtsDone\n", stmtsDone]]; - stmtsDone]; - If [DebugCSE, Print["Z\n"]]; - - (* Turn CAssign statements back into (->) tuples *) - stmts6 = stmts5 //. CAssign[lhs_,rhs_] -> (lhs -> rhs); - If [DebugCSE, Print["stmts6\n", stmts6, "\nendstmts6\n"]]; - - (* Turn CDeclare statements into "faked" declarations *) - stmts7 = stmts6 - //. CDeclare[var_] - :> "const " <> - StringReplace[ToString[var], __ ~~ "`" -> ""]; - If [DebugCSE, Print["stmts7\n", stmts7, "\nendstmts7\n"]]; - - stmts7 - ] -]; - Quote[x_] := {"\"", x, "\""}; End[]; |