Adds a couple more dead code optimizations, and also cleans up creation of JExpressionStatements throughout the compiler.
Review by: mmendez (desk check), alex.tkachman
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1003 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 476b023..ec419f2 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -25,7 +25,6 @@
import com.google.gwt.dev.jjs.InternalCompilerException.NodeInfo;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JExpression;
-import com.google.gwt.dev.jjs.ast.JExpressionStatement;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JNewInstance;
@@ -166,8 +165,7 @@
// qualifier will be null if onModuleLoad is static
JMethodCall onModuleLoadCall = new JMethodCall(program, null, qualifier,
mainMethod);
- bootStrapMethod.body.statements.add(new JExpressionStatement(program,
- null, onModuleLoadCall));
+ bootStrapMethod.body.statements.add(onModuleLoadCall.makeStatement());
}
program.addEntryMethod(bootStrapMethod);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JExpression.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JExpression.java
index ada9ff7..eee6c9a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JExpression.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JExpression.java
@@ -28,4 +28,7 @@
public abstract boolean hasSideEffects();
+ public JExpressionStatement makeStatement() {
+ return new JExpressionStatement(program, getSourceInfo(), this);
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JExpressionStatement.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JExpressionStatement.java
index 2379c91..6aa909c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JExpressionStatement.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JExpressionStatement.java
@@ -18,13 +18,16 @@
import com.google.gwt.dev.jjs.SourceInfo;
/**
- * Repesents a statement that is an expression.
+ * Represents a statement that is an expression.
*/
public class JExpressionStatement extends JStatement {
private JExpression expr;
- public JExpressionStatement(JProgram program, SourceInfo info,
+ /**
+ * Constructed via {@link JExpression#makeStatement()}.
+ */
+ JExpressionStatement(JProgram program, SourceInfo info,
JExpression expr) {
super(program, info);
this.expr = expr;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index 67785c4..991aad6 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -227,7 +227,7 @@
JExpression lhs, JExpression rhs) {
JBinaryOperation assign = new JBinaryOperation(this, info, lhs.getType(),
JBinaryOperator.ASG, lhs, rhs);
- return new JExpressionStatement(this, info, assign);
+ return assign.makeStatement();
}
public JClassType createClass(SourceInfo info, char[][] name,
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
index e2cd025..7863f74 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
@@ -236,23 +236,27 @@
}
/**
- * Prune "if (false)" statements.
+ * Simplify if statements.
*/
public void endVisit(JIfStatement x, Context ctx) {
- JExpression expression = x.getIfExpr();
- if (expression instanceof JBooleanLiteral) {
- JBooleanLiteral booleanLiteral = (JBooleanLiteral) expression;
-
- if (booleanLiteral.getValue()) {
+ JExpression expr = x.getIfExpr();
+ JStatement thenStmt = x.getThenStmt();
+ JStatement elseStmt = x.getElseStmt();
+ if (expr instanceof JBooleanLiteral) {
+ JBooleanLiteral booleanLiteral = (JBooleanLiteral) expr;
+ boolean boolVal = booleanLiteral.getValue();
+ if (boolVal && !isEmpty(thenStmt)) {
// If true, replace myself with then statement
- ctx.replaceMe(x.getThenStmt());
- } else if (x.getElseStmt() != null) {
+ ctx.replaceMe(thenStmt);
+ } else if (!boolVal && !isEmpty(elseStmt)) {
// If false, replace myself with else statement
- ctx.replaceMe(x.getElseStmt());
+ ctx.replaceMe(elseStmt);
} else {
// just prune me
removeMe(x, ctx);
}
+ } else if (isEmpty(thenStmt) && isEmpty(elseStmt)) {
+ ctx.replaceMe(expr.makeStatement());
}
}
@@ -341,8 +345,7 @@
// Compute properties regarding the state of this try statement
boolean noTry = x.getTryBlock().statements.isEmpty();
// TODO: normalize finally block handling
- boolean noFinally = (x.getFinallyBlock() == null)
- || x.getFinallyBlock().statements.isEmpty();
+ boolean noFinally = isEmpty(x.getFinallyBlock());
boolean noCatch = catchArgs.size() == 0;
if (noTry) {
@@ -371,6 +374,16 @@
}
}
+ /**
+ * TODO: if the AST were normalized, we wouldn't need this.
+ */
+ private boolean isEmpty(JStatement stmt) {
+ if (stmt == null) {
+ return true;
+ }
+ return (stmt instanceof JBlock && ((JBlock) stmt).statements.isEmpty());
+ }
+
private Class mapType(JType type) {
return (Class) typeClassMap.get(type);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index f0bc1f5..3ad0ec8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -37,7 +37,6 @@
import com.google.gwt.dev.jjs.ast.JDoStatement;
import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
import com.google.gwt.dev.jjs.ast.JExpression;
-import com.google.gwt.dev.jjs.ast.JExpressionStatement;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JFieldRef;
import com.google.gwt.dev.jjs.ast.JFloatLiteral;
@@ -364,7 +363,7 @@
if (expr == null) {
return null;
}
- stmt = new JExpressionStatement(program, makeSourceInfo(x), expr);
+ stmt = expr.makeStatement();
} else {
stmt = (JStatement) dispatch("processStatement", x);
}
@@ -441,10 +440,11 @@
currentMethod = ctor;
currentMethodScope = x.scope;
- JMethodCall call = null;
+ JMethodCall superOrThisCall = null;
ExplicitConstructorCall ctorCall = x.constructorCall;
if (ctorCall != null) {
- call = (JMethodCall) dispatch("processExpression", ctorCall);
+ superOrThisCall = (JMethodCall) dispatch("processExpression",
+ ctorCall);
}
/*
@@ -463,8 +463,7 @@
JMethod clinitMethod = (JMethod) enclosingType.methods.get(0);
JMethodCall clinitCall = new JMethodCall(program, info, null,
clinitMethod);
- ctor.body.statements.add(new JExpressionStatement(program, info,
- clinitCall));
+ ctor.body.statements.add(clinitCall.makeStatement());
/*
* All synthetic fields must be assigned, unless we have an explicit
@@ -503,9 +502,8 @@
}
// optional this or super constructor call
- if (call != null) {
- ctor.body.statements.add(new JExpressionStatement(program,
- makeSourceInfo(ctorCall), call));
+ if (superOrThisCall != null) {
+ ctor.body.statements.add(superOrThisCall.makeStatement());
}
JExpression thisRef = createThisRef(info, enclosingType);
@@ -519,8 +517,7 @@
JMethod initMethod = (JMethod) enclosingType.methods.get(1);
JMethodCall initCall = new JMethodCall(program, info, thisRef,
initMethod);
- ctor.body.statements.add(new JExpressionStatement(program, info,
- initCall));
+ ctor.body.statements.add(initCall.makeStatement());
}
// user code (finally!)
@@ -1000,14 +997,15 @@
JExpression qualifier = dispProcessExpression(x.enclosingInstance);
List qualList = new ArrayList();
qualList.add(qualifier);
-
+
/*
* Really weird: Sometimes an allocation expression needs both its
* explicit qualifier AND its implicit enclosing class! We add this second
* because the explicit qualifier takes precedence.
*/
if (!currentMethod.isStatic()) {
- JExpression implicitOuter = program.getExprThisRef(info, (JClassType) currentClass);
+ JExpression implicitOuter = program.getExprThisRef(info,
+ (JClassType) currentClass);
qualList.add(implicitOuter);
}
@@ -1393,8 +1391,10 @@
SourceInfo info = makeSourceInfo(x);
JExpression expr = dispProcessExpression(x.condition);
- JStatement thenStmt = removeThen ? null : dispProcessStatement(x.thenStatement);
- JStatement elseStmt = removeElse ? null : dispProcessStatement(x.elseStatement);
+ JStatement thenStmt = removeThen ? null
+ : dispProcessStatement(x.thenStatement);
+ JStatement elseStmt = removeElse ? null
+ : dispProcessStatement(x.elseStatement);
JIfStatement ifStmt = new JIfStatement(program, info, expr, thenStmt,
elseStmt);
return ifStmt;
@@ -1449,7 +1449,7 @@
SourceInfo info = makeSourceInfo(x);
JBlock block = (JBlock) dispProcessStatement(x.block);
JExpression expr = dispProcessExpression(x.expression);
- block.statements.add(0, new JExpressionStatement(program, info, expr));
+ block.statements.add(0, expr.makeStatement());
return block;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
index 7603f1d..afeca7a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
@@ -18,7 +18,6 @@
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JClassType;
-import com.google.gwt.dev.jjs.ast.JExpressionStatement;
import com.google.gwt.dev.jjs.ast.JLocal;
import com.google.gwt.dev.jjs.ast.JLocalRef;
import com.google.gwt.dev.jjs.ast.JMethod;
@@ -126,7 +125,7 @@
}
JStatement statement;
if (oldReturnType == program.getTypeVoid()) {
- statement = new JExpressionStatement(program, bodyInfo, newCall);
+ statement = newCall.makeStatement();
} else {
statement = new JReturnStatement(program, bodyInfo, newCall);
}