diff options
-rw-r--r-- | tools/eliminator/eliminator-test-output.js | 18 | ||||
-rw-r--r-- | tools/eliminator/eliminator-test.js | 12 | ||||
-rw-r--r-- | tools/eliminator/eliminator.coffee | 35 |
3 files changed, 50 insertions, 15 deletions
diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index 1480f5e5..19faa80d 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -10,7 +10,7 @@ var g = function(a1, a2) { var c = a * 2 - 1; - a++; + a = c; foo(c); foo(2); @@ -62,6 +62,16 @@ function h() { x = y ? x + 1 : 7; var x = -5; } + + if (1) { + otherGlob = glob; + breakMe(); + } + var oneUse2 = glob2; + while (1) { + otherGlob2 = oneUse2; + breakMe(); + } return out; } function strtok_part(b, j, f) { @@ -77,7 +87,7 @@ function strtok_part(b, j, f) { function py() { - - - HEAP[HEAP[__PyThreadState_Current] + 12] = HEAP[HEAP[__PyThreadState_Current] + 12] + 1; + var $7 = HEAP[HEAP[__PyThreadState_Current] + 12] + 1; + var $8 = HEAP[__PyThreadState_Current] + 12; + HEAP[$8] = $7; } diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js index 88ea409c..8a364c0a 100644 --- a/tools/eliminator/eliminator-test.js +++ b/tools/eliminator/eliminator-test.js @@ -10,7 +10,7 @@ var g = function (a1, a2) { var b = a * 2; var c = b - 1; var qqq = "qwe"; - a++; + a = c; foo(c); var ww = 1, www, zzz = 2; foo(zzz); @@ -62,6 +62,16 @@ function h() { x = y ? x + 1 : 7; var x = -5; } + var oneUse = glob; + if (1) { + otherGlob = oneUse; + breakMe(); + } + var oneUse2 = glob2; + while (1) { + otherGlob2 = oneUse2; + breakMe(); + } return out; } function strtok_part(b, j, f) { diff --git a/tools/eliminator/eliminator.coffee b/tools/eliminator/eliminator.coffee index 08670096..c07e5974 100644 --- a/tools/eliminator/eliminator.coffee +++ b/tools/eliminator/eliminator.coffee @@ -204,10 +204,8 @@ class Eliminator # depsMutatedInLiveRange analyzeLiveRanges: -> isLive = {} - isDead = {} - # Checks if a given note may mutate any of the currently live variables, and - # if so, adds them to isDead. + # Checks if a given node may mutate any of the currently live variables. checkForMutations = (node, type) => usedInThisStatement = {} if type in ['assign', 'call'] @@ -223,34 +221,51 @@ class Eliminator reference = reference[1] if @dependsOn[reference]? for varName of @dependsOn[reference] - if isLive[varName] and not usedInThisStatement[varName] - isDead[varName] = true + if isLive[varName] + isLive[varName] = false if type of CONTROL_FLOW_NODES for varName of isLive if @dependsOnAGlobal[varName] or not usedInThisStatement[varName] - isDead[varName] = true + isLive[varName] = false else if type is 'assign' for varName of isLive if @dependsOnAGlobal[varName] and not usedInThisStatement[varName] - isDead[varName] = true + isLive[varName] = false else if type is 'name' reference = node[1] if @isSingleDef[reference] - if isDead[reference] or not isLive[reference] + if not isLive[reference] @depsMutatedInLiveRange[reference] = true return undefined # Analyzes a block and all its children for variable ranges. Makes sure to # account for the worst case of possible mutations. analyzeBlock = (node, type) => - if type in ['if', 'do', 'while', 'for', 'for-in', 'try'] - for child in node + if type in ['switch', 'if', 'try', 'do', 'while', 'for', 'for-in'] + traverseChild = (child) -> if typeof child == 'object' and child?.length savedLive = {} for name of isLive then savedLive[name] = true traverse child, analyzeBlock + for name of isLive + if not isLive[name] then savedLive[name] = false isLive = savedLive + if type is 'switch' + traverseChild node[1] + for child in node[2] + traverseChild child + else if type in ['if', 'try'] + for child in node + traverseChild child + else + # Don't put anything from outside into the body of a loop. + savedLive = isLive + isLive = {} + for child in node then traverseChild child + for name of isLive + if not isLive[name] then savedLive[name] = false + isLive = savedLive return node else if type is 'var' for [varName, varValue] in node[1] |