mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 08:24:10 -08:00
Fix evaluation order when eliminating redundant variables from AST
See #330
This commit is contained in:
parent
52a23fcadd
commit
788e506175
|
@ -122,16 +122,35 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
Expr b = expr.getSecondOperand();
|
Expr b = expr.getSecondOperand();
|
||||||
Expr a = expr.getFirstOperand();
|
Expr a = expr.getFirstOperand();
|
||||||
|
|
||||||
if (a instanceof VariableExpr || a instanceof ConstantExpr) {
|
int barrierPosition = 0;
|
||||||
b.acceptVisitor(this);
|
if (isSideEffectFree(a)) {
|
||||||
b = resultExpr;
|
barrierPosition++;
|
||||||
if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) {
|
if (isSideEffectFree(b)) {
|
||||||
if (tryMakePositive((ConstantExpr) b)) {
|
barrierPosition++;
|
||||||
expr.setOperation(BinaryOperation.ADD);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
a.acceptVisitor(this);
|
}
|
||||||
a = resultExpr;
|
|
||||||
|
Statement barrier = addBarrier();
|
||||||
|
|
||||||
|
if (barrierPosition == 2) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
|
b.acceptVisitor(this);
|
||||||
|
b = resultExpr;
|
||||||
|
if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) {
|
||||||
|
if (tryMakePositive((ConstantExpr) b)) {
|
||||||
|
expr.setOperation(BinaryOperation.ADD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (barrierPosition == 1) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
|
a.acceptVisitor(this);
|
||||||
|
a = resultExpr;
|
||||||
|
|
||||||
|
if (barrierPosition == 0) {
|
||||||
|
removeBarrier(barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr p = a;
|
Expr p = a;
|
||||||
|
@ -223,10 +242,14 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
try {
|
try {
|
||||||
expr.getCondition().acceptVisitor(this);
|
expr.getCondition().acceptVisitor(this);
|
||||||
Expr cond = resultExpr;
|
Expr cond = resultExpr;
|
||||||
|
|
||||||
|
Statement barrier = addBarrier();
|
||||||
expr.getConsequent().acceptVisitor(this);
|
expr.getConsequent().acceptVisitor(this);
|
||||||
Expr consequent = resultExpr;
|
Expr consequent = resultExpr;
|
||||||
expr.getAlternative().acceptVisitor(this);
|
expr.getAlternative().acceptVisitor(this);
|
||||||
Expr alternative = resultExpr;
|
Expr alternative = resultExpr;
|
||||||
|
removeBarrier(barrier);
|
||||||
|
|
||||||
expr.setCondition(cond);
|
expr.setCondition(cond);
|
||||||
expr.setConsequent(consequent);
|
expr.setConsequent(consequent);
|
||||||
expr.setAlternative(alternative);
|
expr.setAlternative(alternative);
|
||||||
|
@ -288,10 +311,37 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
public void visit(SubscriptExpr expr) {
|
public void visit(SubscriptExpr expr) {
|
||||||
pushLocation(expr.getLocation());
|
pushLocation(expr.getLocation());
|
||||||
try {
|
try {
|
||||||
|
Expr index = expr.getIndex();
|
||||||
|
Expr array = expr.getArray();
|
||||||
|
|
||||||
|
int barrierPosition = 0;
|
||||||
|
if (isSideEffectFree(array)) {
|
||||||
|
++barrierPosition;
|
||||||
|
if (isSideEffectFree(index)) {
|
||||||
|
++barrierPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement barrier = addBarrier();
|
||||||
|
|
||||||
|
if (barrierPosition == 2) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
expr.getIndex().acceptVisitor(this);
|
expr.getIndex().acceptVisitor(this);
|
||||||
Expr index = resultExpr;
|
index = resultExpr;
|
||||||
|
|
||||||
|
if (barrierPosition == 1) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
expr.getArray().acceptVisitor(this);
|
expr.getArray().acceptVisitor(this);
|
||||||
Expr array = resultExpr;
|
array = resultExpr;
|
||||||
|
|
||||||
|
if (barrierPosition == 0) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
expr.setArray(array);
|
expr.setArray(array);
|
||||||
expr.setIndex(index);
|
expr.setIndex(index);
|
||||||
resultExpr = expr;
|
resultExpr = expr;
|
||||||
|
@ -318,13 +368,32 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
pushLocation(expr.getLocation());
|
pushLocation(expr.getLocation());
|
||||||
try {
|
try {
|
||||||
Expr[] args = new Expr[expr.getArguments().size()];
|
Expr[] args = new Expr[expr.getArguments().size()];
|
||||||
for (int i = expr.getArguments().size() - 1; i >= 0; --i) {
|
int barrierPos;
|
||||||
|
|
||||||
|
for (barrierPos = 0; barrierPos < args.length; ++barrierPos) {
|
||||||
|
if (!isSideEffectFree(args[barrierPos])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement barrier = addBarrier();
|
||||||
|
|
||||||
|
if (barrierPos == args.length) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = args.length - 1; i >= 0; --i) {
|
||||||
expr.getArguments().get(i).acceptVisitor(this);
|
expr.getArguments().get(i).acceptVisitor(this);
|
||||||
args[i] = resultExpr;
|
args[i] = resultExpr;
|
||||||
|
if (i == barrierPos) {
|
||||||
|
removeBarrier(barrier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < args.length; ++i) {
|
for (int i = 0; i < args.length; ++i) {
|
||||||
expr.getArguments().set(i, args[i]);
|
expr.getArguments().set(i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
resultExpr = expr;
|
resultExpr = expr;
|
||||||
} finally {
|
} finally {
|
||||||
popLocation();
|
popLocation();
|
||||||
|
@ -901,4 +970,50 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
popLocation();
|
popLocation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Statement addBarrier() {
|
||||||
|
SequentialStatement barrier = new SequentialStatement();
|
||||||
|
resultSequence.add(barrier);
|
||||||
|
return barrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeBarrier(Statement barrier) {
|
||||||
|
Statement removedBarrier = resultSequence.remove(resultSequence.size() - 1);
|
||||||
|
if (removedBarrier != barrier) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSideEffectFree(Expr expr) {
|
||||||
|
if (expr == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof VariableExpr || expr instanceof ConstantExpr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof BinaryExpr) {
|
||||||
|
BinaryExpr binary = (BinaryExpr) expr;
|
||||||
|
return isSideEffectFree(binary.getFirstOperand()) && isSideEffectFree(binary.getSecondOperand());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof UnaryExpr) {
|
||||||
|
return isSideEffectFree(((UnaryExpr) expr).getOperand());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof InstanceOfExpr) {
|
||||||
|
return isSideEffectFree(((InstanceOfExpr) expr).getExpr());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof PrimitiveCastExpr) {
|
||||||
|
return isSideEffectFree(((PrimitiveCastExpr) expr).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof NewExpr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user