issues
search
kripken
/
BananaBread
BananaBread is a C++ 3D game engine that runs on the web using JavaScript+WebGL+HTML
1.38k
stars
347
forks
source link
test
#49
Closed
kripken
closed
10 years ago
kripken
commented
10 years ago
.
kripken
commented
10 years ago
x
kripken
commented
10 years ago
y
kripken
commented
10 years ago
z
kripken
commented
10 years ago
w
kripken
commented
10 years ago
// expensive | expensive can be turned into expensive ? 1 : expensive, and
// expensive | cheap can be turned into cheap ? 1 : expensive,
// so that we can avoid the expensive computation, if it has no side effects.
function conditionalize(ast) {
var MIN_COST = 4;
traverse(ast, function(node, type) {
if (type === 'if' || type === 'while') {
var cond = node[1];
if (cond[0] === 'binary' && (cond[1] === '|' || cond[1] === '&') && cond[3][0] !== 'num' && cond[2][0] !== 'num') {
// logical operator on two non-numerical values, all inside a condition
var left = cond[2];
var right = cond[3];
var leftEffects = hasSideEffects(left);
var rightEffects = hasSideEffects(right);
if (leftEffects && rightEffects) return; // both must execute
// canonicalize with side effects, if any, happening on the left
if (rightEffects) {
if (measureSize(left) < MIN_COST) return; // avoidable code is too cheap
var temp = left;
left = right;
right = temp;
} else if (leftEffects) {
if (measureSize(right) < MIN_COST) return; // avoidable code is too cheap
} else {
// no side effects, reorder based on cost estimation
var leftCost = measureSize(left);
var rightCost = measureSize(right);
if (Math.max(leftCost, rightCost) < MIN_COST) return; // avoidable code is too cheap
// canonicalize with expensive code on the right
if (leftCost > rightCost) {
var temp = left;
left = right;
right = temp;
}
}
// worth it, perform conditionalization
if (cond[1] === '|') {
node[1] = ['conditional', left, ['num', 1], right];
} else { // &
node[1] = ['conditional', left, right, ['num', 0]];
}
kripken
commented
10 years ago
// expensive | expensive can be turned into expensive ? 1 : expensive, and
// expensive | cheap can be turned into cheap ? 1 : expensive,
// so that we can avoid the expensive computation, if it has no side effects.
function conditionalize(ast) {
var MIN_COST = 4;
traverse(ast, function(node, type) {
if (type === 'if' || type === 'while') {
var cond = node[1];
if (cond[0] === 'binary' && (cond[1] === '|' || cond[1] === '&') && cond[3][0] !== 'num' && cond[2][0] !== 'num') {
// logical operator on two non-numerical values, all inside a condition
var left = cond[2];
var right = cond[3];
var leftEffects = hasSideEffects(left);
var rightEffects = hasSideEffects(right);
if (leftEffects && rightEffects) return; // both must execute
// canonicalize with side effects, if any, happening on the left
if (rightEffects) {
if (measureSize(left) < MIN_COST) return; // avoidable code is too cheap
var temp = left;
left = right;
right = temp;
} else if (leftEffects) {
if (measureSize(right) < MIN_COST) return; // avoidable code is too cheap
} else {
// no side effects, reorder based on cost estimation
var leftCost = measureSize(left);
var rightCost = measureSize(right);
if (Math.max(leftCost, rightCost) < MIN_COST) return; // avoidable code is too cheap
// canonicalize with expensive code on the right
if (leftCost > rightCost) {
var temp = left;
left = right;
right = temp;
}
}
// worth it, perform conditionalization
if (cond[1] === '|') {
node[1] = ['conditional', left, ['num', 1], right];
} else { // &
node[1] = ['conditional', left, right, ['num', 0]];
}
.