aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax99x <max99x@gmail.com>2011-08-28 13:11:17 +0300
committermax99x <max99x@gmail.com>2011-08-28 13:11:17 +0300
commit36a03b4ea08c7423c45a56bb7ee5e46c5a150a50 (patch)
tree7d446d1061d127ae0ce34316858f7c947d27c24d
parent19458449a6c3eca2f63bdaae134173a000a89ce0 (diff)
Eliminator: prevent inlining into loops & fix for circular dependencies.
-rw-r--r--tools/eliminator/eliminator-test-output.js18
-rw-r--r--tools/eliminator/eliminator-test.js12
-rw-r--r--tools/eliminator/eliminator.coffee35
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]