Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Commit

Permalink
Fixed cse.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbebenita committed Jun 13, 2012
1 parent a077e59 commit f3e58ad
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 47 deletions.
6 changes: 2 additions & 4 deletions src/avm2/bin/shu.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,6 @@ def execute(self, args):
print "KINDOF - the \"PASSED\" and \"FAILED\" string appear in the output."
print "FAILED - the \"PASSED\" string doesn't appear anywhere."
print "---------------------------------------------------------------------------------------------------------"
print "Interpreter Time, Time Ratio, Compiler, Time, Time Ratio, Interpreter/Compiler, Time Ratio, Number, File"
print "---------------------------------------------------------------------------------------------------------"

tests = Queue.Queue();

Expand Down Expand Up @@ -338,8 +336,8 @@ def runTest(tests, counts):
modes = {}
modes["a"] = [self.avm, test]
modes["i"] = ["js", "-m", "-n", "avm.js", "-x", "-i", test];
modes["c"] = ["js", "-m", "-n", "avm.js", "-x", "-cse=false", test];
modes["o"] = ["js", "-m", "-n", "avm.js", "-x", "-acc=false", test];
modes["c"] = ["js", "-m", "-n", "avm.js", "-x", "-opt=false", test];
modes["o"] = ["js", "-m", "-n", "avm.js", "-x", test];

results = {}

Expand Down
101 changes: 66 additions & 35 deletions src/avm2/compiler/compiler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var enableCSE = options.register(new Option("cse", "cse", true, "Common Subexpression Elimination"));
var enableAccessors = options.register(new Option("acc", "acc", true, "Use accessors to get/set values via runtime multinames. "));
var enableOpt = options.register(new Option("opt", "opt", true, "Enable optimizations."));

const T = estransform;

Expand Down Expand Up @@ -121,6 +120,9 @@ var Compiler = (function () {
Literal.call(this, value);
}
}
constant.prototype.isEquivalent = function (other) {
return other instanceof Constant && this.value === other.value;
};
return constant;
})();

Expand Down Expand Up @@ -296,7 +298,9 @@ var Compiler = (function () {
};
findProperty.prototype = Object.create(CallExpression.prototype);
findProperty.prototype.isEquivalent = function isEquivalent(other) {
return other instanceof findProperty && this.multiname === other.multiname && this.strict === other.strict;
return other instanceof findProperty &&
this.multiname.isEquivalent(other.multiname) &&
this.strict === other.strict;
};
return findProperty;
})();
Expand All @@ -322,23 +326,27 @@ var Compiler = (function () {
* Keeps track of a pool of variables that may be reused.
*/
var VariablePool = (function () {
var count = 0;
function variablePool() {
this.count = 0;
this.used = [];
this.available = [];
}
variablePool.prototype.acquire = function () {
if (!this.available.empty()) {
return this.available.pop();
}
var variable = new Variable("v" + count++);
var variable = new Variable("v" + this.count++);
this.used.push(variable);
return variable;
};
variablePool.prototype.release = function (variable) {
assert (this.used.contains(variable));
this.available.push(variable);
};
variablePool.prototype.releaseAll = function () {
this.available = this.available.concat(this.used);
this.used = [];
};
return variablePool;
})();

Expand All @@ -358,7 +366,7 @@ var Compiler = (function () {

/**
* Finds and returns an equivalent value or returns null if not found.
* If [allocate] is true, then if an equivalent value is not found the
* If |allocate| is true and an equivalent value is not found, then
* a variable is allocated for the current value and the original value
* is returned.
*/
Expand Down Expand Up @@ -388,6 +396,11 @@ var Compiler = (function () {
return value;
};

cse.prototype.reset = function reset() {
this.values = [];
this.variablePool.releaseAll();
};

return cse;
})();

Expand Down Expand Up @@ -592,21 +605,26 @@ var Compiler = (function () {

function push(value) {
assert (typeof value !== "string");
if (enableCSE.value && value instanceof FindProperty) {
cseValue(value);
} else {
state.stack.push(value);
}
state.stack.push(value);
}

function cseValue(value) {
assert (value);
if (block.cse) {
var otherValue = block.cse.get(value, true);
if (otherValue === value) {
// flushStack();
emit(assignment(value.variable, value));
value.variable.value = value;
// print("CSE: " + generate(value) + " -> " + value.variable);
}
state.stack.push(otherValue.variable);
return otherValue.variable;
}
return value;
}

function flushScope() {
if (block.cse) {
block.cse.reset();
}
}

Expand Down Expand Up @@ -671,7 +689,7 @@ var Compiler = (function () {
// TODO
}

if (enableCSE.value) {
if (enableOpt.value) {
if (block.dominator === block) {
block.cse = new CSE(null, this.variablePool);
} else {
Expand Down Expand Up @@ -720,29 +738,24 @@ var Compiler = (function () {
* Find the scope object containing the specified multiname.
*/
function findProperty(multiname, strict) {
/*
if (false && !multiname.isQName()) {
if (savedScope) {
var resolved = savedScope.resolveMultiname(multiname);
if (resolved) {
return new FindProperty(resolved, strict);
}
}
}
*/
return new FindProperty(multiname, strict);
return cseValue(new FindProperty(multiname, strict));
}

function getProperty(obj, multiname) {
assert (!(multiname instanceof Multiname), multiname);

/*
if (obj instanceof FindProperty &&
obj.multiname.name === multiname.name &&
obj.multiname.isQName()) {
return property(obj, obj.multiname.getQualifiedName());
if (enableOpt.value && multiname instanceof RuntimeMultiname) {
return new MemberExpression(obj, multiname.name, true);
}

if (multiname instanceof Constant) {
var val = obj instanceof Variable ? obj.value : obj;
if (val instanceof FindProperty && multiname.isEquivalent(val.multiname)) {
if (multiname.value.isQName()) {
return property(obj, multiname.value.getQualifiedName());
}
}
}
*/

/**
* Looping over arrays by index will use a MultinameL
Expand Down Expand Up @@ -770,14 +783,30 @@ var Compiler = (function () {
}

function setProperty(obj, multiname, value) {
if (enableOpt.value && multiname instanceof RuntimeMultiname) {
return assignment(new MemberExpression(obj, multiname.name, true), value);
}
return call(id("setProperty"), [obj, multiname, value]);
}

function getMultiname(index) {
assert (!multinames[index].isRuntime());
return constant(multinames[index]);
var multiname = multinames[index];
assert (!multiname.isRuntime());
var c = constant(multiname);
c.multiname = multiname;
return c;
}

var RuntimeMultiname = (function () {
function runtimeMultiname(multiname, ns, name) {
this.multiname = multiname;
this.ns = ns;
this.name = name;
NewExpression.call(this, id("Multiname"), [ns, name]);
};
return runtimeMultiname;
})();

function popMultiname(index) {
var multiname = multinames[index];
if (multiname.isRuntime()) {
Expand All @@ -788,7 +817,7 @@ var Compiler = (function () {
if (multiname.isRuntimeNamespace()) {
ns = state.stack.pop();
}
return new NewExpression(id("Multiname"), [ns, name]);
return new RuntimeMultiname(multiname, ns, name);
} else {
return constant(multiname);
}
Expand Down Expand Up @@ -850,6 +879,7 @@ var Compiler = (function () {
break;
case OP_popscope:
flushStack();
flushScope();
emit(assignment(scopeName, property(scopeName, "parent")));
state.scopeHeight -= 1;
break;
Expand Down Expand Up @@ -889,6 +919,7 @@ var Compiler = (function () {
case OP_swap: state.stack.push(state.stack.pop(), state.stack.pop()); break;
case OP_pushscope:
flushStack();
flushScope();
obj = state.stack.pop();
emit(assignment(scopeName, new NewExpression(id("Scope"), [scopeName, obj])));
state.scopeHeight += 1;
Expand Down Expand Up @@ -1072,7 +1103,7 @@ var Compiler = (function () {
break;
case OP_coerce_b:
case OP_convert_b:
push(call(id("toBoolean"), [state.stack.pop()]));
push(new UnaryExpression(Operator.FALSE, new UnaryExpression(Operator.FALSE, state.stack.pop())));
break;
case OP_convert_o: notImplemented(); break;
case OP_checkfilter: notImplemented(); break;
Expand Down
14 changes: 6 additions & 8 deletions src/avm2/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function toDouble(x) {
}

function toBoolean(x) {
return Boolean(x);
return !!x;
}

function toUint(x) {
Expand Down Expand Up @@ -422,17 +422,15 @@ function setProperty(obj, multiname, value) {
}

var name = resolved.getQualifiedName();
var type = obj.types[name];

if (tracePropertyAccess.value && type) {
print("setProperty: coercing to type:" + type);
}
setPropertyQuick(obj, name, value);
}

function setPropertyQuick(obj, qualifiedName, value) {
var type = obj.types[qualifiedName];
if (type && type.coerce) {
value = type.coerce(value);
}

obj[name] = value;
obj[qualifiedName] = value;
}

function throwErrorFromVM(errorClass, message) {
Expand Down

0 comments on commit f3e58ad

Please sign in to comment.