Some deadcode optimizations on JMultiExpressions to remove side-effect free expressions.  Includes an optimization for field references whose only side-effect is a clinit.  This is in anticipation of a change to remove unused parameters.

Patch by: mmastrac
Review by: scottb


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1479 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 d103fd7..ded8056 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
@@ -28,6 +28,7 @@
 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.JFieldRef;
 import com.google.gwt.dev.jjs.ast.JForStatement;
 import com.google.gwt.dev.jjs.ast.JIfStatement;
 import com.google.gwt.dev.jjs.ast.JIntLiteral;
@@ -47,6 +48,7 @@
 import com.google.gwt.dev.jjs.ast.JValueLiteral;
 import com.google.gwt.dev.jjs.ast.JVisitor;
 import com.google.gwt.dev.jjs.ast.JWhileStatement;
+import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -286,6 +288,41 @@
     }
 
     /**
+     * Remove any parts of JMultiExpression that have no side-effect.
+     */
+    @Override
+    public void endVisit(JMultiExpression x, Context ctx) {
+      for (int i = 0; i < x.exprs.size() - 1; i++) {
+        JExpression expr = x.exprs.get(i);
+        if (!expr.hasSideEffects()) {
+          x.exprs.remove(i);
+          i--;
+          continue;
+        }
+
+        if (expr instanceof JFieldRef) {
+          JFieldRef fieldRef = (JFieldRef) expr;
+          JExpression instance = fieldRef.getInstance();
+          if (instance == null || !instance.hasSideEffects()) {
+            // If the instance doesn't have side-effects, but the field ref
+            // does, it's because a clinit() needs to happen.
+            JMethod clinit = fieldRef.getField().getEnclosingType().methods.get(0);
+            assert (clinit.getName().equals("$clinit"));
+
+            // Replace the field ref with a direct call to the clinit.
+            JMethodCall methodCall = new JMethodCall(program,
+                expr.getSourceInfo(), instance, clinit);
+            x.exprs.set(i, methodCall);
+          }
+        }
+      }
+
+      if (x.exprs.size() == 1) {
+        ctx.replaceMe(x.exprs.get(0));
+      }
+    }
+
+    /**
      * Simplify the ! operator if possible.
      */
     @Override
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
index a395f83..cb2b7dd 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
@@ -110,11 +110,17 @@
     public void endVisit(JMethodCall x, Context ctx) {
       JMethod method = x.getTarget();
 
-      // The method call must be known statically
+      // The method call must be known statically.
       if (!method.isStatic() || method.isNative()) {
         return;
       }
 
+      // The target must not be a clinit method.
+      if (method.getEnclosingType() != null
+          && method.getEnclosingType().methods.get(0) == method) {
+        return;
+      }
+
       if (cannotInline.contains(method)) {
         return;
       }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
index 53ff0de..aa37346 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.dev.jjs.impl;
 
+import com.google.gwt.dev.jjs.ast.CanBeStatic;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.JAbsentArrayDimension;
 import com.google.gwt.dev.jjs.ast.JArrayType;
@@ -225,13 +226,9 @@
       return false;
     }
 
-    private boolean pruneViaNoninstantiability(boolean isInstantiated, JField it) {
-      return (!isInstantiated && !it.isStatic());
-    }
-
     private boolean pruneViaNoninstantiability(boolean isInstantiated,
-        JMethod it) {
-      return (!isInstantiated && (!it.isStatic() || program.isStaticImpl(it)));
+        CanBeStatic it) {
+      return (!isInstantiated && !it.isStatic());
     }
   }