Introducing lattice TOP for constants. Making it starting value.
Review at http://gwt-code-reviews.appspot.com/436801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8045 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java
index 09daf8b..0cd896e 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java
@@ -15,7 +15,6 @@
*/
package com.google.gwt.dev.jjs.impl.gflow.constants;
-import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.impl.gflow.Analysis;
import com.google.gwt.dev.jjs.impl.gflow.AssumptionMap;
import com.google.gwt.dev.jjs.impl.gflow.AssumptionUtil;
@@ -46,18 +45,7 @@
public void setInitialGraphAssumptions(Cfg graph,
AssumptionMap<CfgEdge, ConstantsAssumption> assumptionMap) {
- // Set all parameter assumptions to T
-
- ConstantsAssumption.Updater updater = new ConstantsAssumption.Updater(null);
- for (CfgNode<?> node : graph.getNodes()) {
- Object jnode = node.getJNode();
- if (jnode instanceof JParameterRef) {
- updater.set(((JParameterRef) jnode).getParameter(), null);
- }
- }
- ConstantsAssumption assumptions = updater.unwrap();
-
- AssumptionUtil.setAssumptions(graph.getGraphInEdges(), assumptions,
- assumptionMap);
+ AssumptionUtil.setAssumptions(graph.getGraphInEdges(),
+ ConstantsAssumption.TOP, assumptionMap);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumption.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumption.java
index 19533cf..75a7c55 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumption.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumption.java
@@ -21,14 +21,21 @@
import com.google.gwt.dev.jjs.ast.JValueLiteral;
import com.google.gwt.dev.jjs.ast.JVariable;
import com.google.gwt.dev.jjs.impl.gflow.Assumption;
+import com.google.gwt.dev.util.Preconditions;
import java.util.ArrayList;
-import java.util.IdentityHashMap;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Assumptions for ConstantsAnalysis.
+ *
+ * Is a map from variable into it's constant value. If variable is not present
+ * in the map, then it's not a constant.
+ *
+ * Empty ConstantsAssumption is a top of the lattice, and is not equals to
+ * null assumption (which is the bottom of every lattice).
*/
public class ConstantsAssumption implements Assumption<ConstantsAssumption> {
/**
@@ -59,12 +66,8 @@
}
public ConstantsAssumption unwrap() {
- return assumption;
- }
-
- public ConstantsAssumption unwrapToNotNull() {
- if (assumption == null) {
- return new ConstantsAssumption();
+ if (assumption != null && assumption.isEmpty()) {
+ return TOP;
}
return assumption;
}
@@ -76,114 +79,56 @@
}
}
}
-
- /**
- * Contains individual assumptions about variables. If variable isn't in the
- * map, then variable assumption is _|_ (bottom), if variable's value is
- * null, then variable assumption is T - variable has non-constant value.
- */
- private final Map<JVariable, JValueLiteral> values;
-
- public ConstantsAssumption() {
- values = new IdentityHashMap<JVariable, JValueLiteral>();
- }
-
- public ConstantsAssumption(ConstantsAssumption a) {
- if (a != null) {
- values = new IdentityHashMap<JVariable, JValueLiteral>(a.values);
- } else {
- values = new IdentityHashMap<JVariable, JValueLiteral>();
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj == null) {
- return values.isEmpty();
- }
- ConstantsAssumption other = (ConstantsAssumption) obj;
- return values.equals(other.values);
- }
-
- /**
- * Get variable constant assumption. <code>null</code> if there's no constant
- * assumption for this variable.
- */
- public JValueLiteral get(JVariable variable) {
- return values.get(variable);
- }
/**
- * Check if we have constant (i.e. not top and not bottom) assumption about
- * the variable.
+ * A wrapper around JValueLiteral to give it equals() method.
*/
- public boolean hasAssumption(JVariable variable) {
- return get(variable) != null;
- }
-
- @Override
- public int hashCode() {
- return values.hashCode();
- }
-
- public ConstantsAssumption join(ConstantsAssumption other) {
- if (other == null || other.values.isEmpty()) {
- return this;
+ private static class LiteralWrapper {
+ private final JValueLiteral literal;
+
+ LiteralWrapper(JValueLiteral literal) {
+ Preconditions.checkNotNull(literal);
+ this.literal = literal;
}
-
- if (values.isEmpty()) {
- return other;
- }
-
- ConstantsAssumption result = new ConstantsAssumption(this);
-
- for (JVariable var : other.values.keySet()) {
- if (values.containsKey(var)) {
- // Var is present in both assumptions. Join their values.
- result.values.put(var, join(values.get(var), other.values.get(var)));
- } else {
- result.values.put(var, other.values.get(var));
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
}
- }
-
- return result;
- }
-
- public String toDebugString() {
- StringBuffer result = new StringBuffer();
-
- result.append("{");
- List<JVariable> variables = new ArrayList<JVariable>(values.keySet());
- HasName.Util.sortByName(variables);
- for (JVariable variable : variables) {
- if (result.length() > 1) {
- result.append(", ");
+
+ if (obj == this) {
+ return true;
}
- result.append(variable.getName());
- result.append(" = ");
- if (values.get(variable) == null) {
- result.append("T");
- } else {
- result.append(values.get(variable));
- }
+
+ LiteralWrapper other = (LiteralWrapper) obj;
+ return equal(this.literal, other.literal);
}
- result.append("}");
-
- return result.toString();
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return literal.toString();
+ }
}
- @Override
- public String toString() {
- return toDebugString();
- }
+ /**
+ * A TOP for the lattice. Means that all variables are not constant.
+ */
+ public static ConstantsAssumption TOP = new ConstantsAssumption();
- private boolean equal(JValueLiteral literal1, JValueLiteral literal2) {
+ private static boolean equal(JValueLiteral literal1, JValueLiteral literal2) {
if (literal1 == null || literal2 == null) {
return literal1 == literal2;
}
+
+ if (literal1 == literal2) {
+ return true;
+ }
if (literal1.getClass() != literal2.getClass()) {
// these are different literal types.
@@ -215,7 +160,7 @@
return valueObj1.equals(valueObj2);
}
- private JValueLiteral join(JValueLiteral value1, JValueLiteral value2) {
+ private static JValueLiteral join(JValueLiteral value1, JValueLiteral value2) {
if (!equal(value1, value2)) {
return null;
}
@@ -223,7 +168,136 @@
return value1;
}
- private void set(JVariable variable, JValueLiteral literal) {
- values.put(variable, literal);
+ private static JValueLiteral join(LiteralWrapper wrapper1,
+ LiteralWrapper wrapper2) {
+ if (wrapper1 == null || wrapper2 == null) {
+ return null;
+ }
+
+ return join(wrapper1.literal, wrapper2.literal);
+ }
+
+ /**
+ * Contains individual assumptions about variables. If variable isn't in the
+ * map, then variable assumption is _|_ (bottom), if variable's value is
+ * null, then variable assumption is T - variable has non-constant value.
+ */
+ private final Map<JVariable, LiteralWrapper> values;
+
+ public ConstantsAssumption() {
+ values = new HashMap<JVariable, LiteralWrapper>();
+ }
+
+ public ConstantsAssumption(ConstantsAssumption a) {
+ if (a != null) {
+ values = new HashMap<JVariable, LiteralWrapper>(a.values);
+ } else {
+ values = new HashMap<JVariable, LiteralWrapper>();
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ ConstantsAssumption other = (ConstantsAssumption) obj;
+ return values.equals(other.values);
+ }
+
+ /**
+ * Get variable constant assumption. <code>null</code> if there's no constant
+ * assumption for this variable.
+ */
+ public JValueLiteral get(JVariable variable) {
+ LiteralWrapper wrapper = values.get(variable);
+ return wrapper != null ? wrapper.literal : null;
+ }
+
+ /**
+ * Check if we have constant (i.e. not top and not bottom) assumption about
+ * the variable.
+ */
+ public boolean hasAssumption(JVariable variable) {
+ return get(variable) != null;
+ }
+
+ @Override
+ public int hashCode() {
+ return values.hashCode();
+ }
+
+ public boolean isEmpty() {
+ return values.isEmpty();
+ }
+
+ public ConstantsAssumption join(ConstantsAssumption other) {
+ if (other == null) {
+ return this;
+ }
+
+ if (other == TOP || this == TOP || isEmpty() || other.isEmpty()) {
+ return TOP;
+ }
+
+ ConstantsAssumption result = new ConstantsAssumption();
+
+ for (JVariable var : other.values.keySet()) {
+ if (values.containsKey(var)) {
+ // Var is present in both assumptions. Join their values.
+ JValueLiteral value = join(values.get(var), other.values.get(var));
+ if (value != null) {
+ result.values.put(var, new LiteralWrapper(value));
+ }
+ }
+ }
+
+ if (result.isEmpty()) {
+ return TOP;
+ }
+
+ return result;
+ }
+
+ public String toDebugString() {
+ if (this == TOP || isEmpty()) {
+ return "T";
+ }
+ StringBuffer result = new StringBuffer();
+
+ result.append("{");
+ List<JVariable> variables = new ArrayList<JVariable>(values.keySet());
+ HasName.Util.sortByName(variables);
+ for (JVariable variable : variables) {
+ if (result.length() > 1) {
+ result.append(", ");
+ }
+ result.append(variable.getName());
+ result.append(" = ");
+ if (values.get(variable) == null) {
+ result.append("T");
+ } else {
+ result.append(values.get(variable));
+ }
+ }
+ result.append("}");
+
+ return result.toString();
+ }
+
+ @Override
+ public String toString() {
+ return toDebugString();
+ }
+
+ void set(JVariable variable, JValueLiteral literal) {
+ if (literal != null) {
+ values.put(variable, new LiteralWrapper(literal));
+ } else {
+ values.remove(variable);
+ }
}
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/GflowTests.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/GflowTests.java
index d231147..8dede28 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/GflowTests.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/GflowTests.java
@@ -16,6 +16,7 @@
package com.google.gwt.dev.jjs.impl.gflow;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgBuilderTest;
+import com.google.gwt.dev.jjs.impl.gflow.constants.ConstantsAssumptionTest;
import com.google.gwt.dev.jjs.impl.gflow.constants.ExpressionEvaluatorTest;
import com.google.gwt.dev.jjs.impl.gflow.constants.AssumptionsDeducerTest;
import com.google.gwt.dev.jjs.impl.gflow.constants.ConstantsAnalysisTest;
@@ -36,6 +37,7 @@
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(CfgBuilderTest.class);
+ suite.addTestSuite(ConstantsAssumptionTest.class);
suite.addTestSuite(AssumptionsDeducerTest.class);
suite.addTestSuite(ExpressionEvaluatorTest.class);
suite.addTestSuite(ConstantsAnalysisTest.class);
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/AssumptionsDeducerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/AssumptionsDeducerTest.java
index 69ccd27..15231bc 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/AssumptionsDeducerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/AssumptionsDeducerTest.java
@@ -48,56 +48,56 @@
public void testEq() throws Exception {
from("int i = 0;", "i == 10", true).deduce("{i = 10}");
- from("int i = 0;", "i == 10", false).deduce("{i = T}");
+ from("int i = 0;", "i == 10", false).deduce("T");
}
public void testNeq() throws Exception {
- from("int i = 0;", "i != 10", true).deduce("{i = T}");
+ from("int i = 0;", "i != 10", true).deduce("T");
from("int i = 0;", "i != 10", false).deduce("{i = 10}");
}
public void testInstanceof() throws Exception {
- from("Object o = null;", "o instanceof String", true).deduce("{}");
- from("Object o = null;", "o instanceof String", false).deduce("{}");
+ from("Object o = null;", "o instanceof String", true).deduce("T");
+ from("Object o = null;", "o instanceof String", false).deduce("T");
}
public void testReference() throws Exception {
- from("String s = null;", "s.length() == 0", true).deduce("{}");
- from("String s = null;", "s.length() == 0", false).deduce("{}");
- from("Foo f = null;", "f.o == null", true).deduce("{}");
- from("Foo f = null;", "f.o == null", false).deduce("{}");
+ from("String s = null;", "s.length() == 0", true).deduce("T");
+ from("String s = null;", "s.length() == 0", false).deduce("T");
+ from("Foo f = null;", "f.o == null", true).deduce("T");
+ from("Foo f = null;", "f.o == null", false).deduce("T");
}
public void testAnd() throws Exception {
from("int i = 0; int j = 0;", "i == 10 && j == 11", true).deduce("{i = 10, j = 11}");
- from("int i = 0; int j = 0;", "i == 10 && j == 11", false).deduce("{i = T, j = T}");
+ from("int i = 0; int j = 0;", "i == 10 && j == 11", false).deduce("T");
}
public void testOr() throws Exception {
from("int i = 0; int j = 0;", "i != 10 || j != 11", false).deduce("{i = 10, j = 11}");
- from("int i = 0; int j = 0;", "i != 10 || j != 11", true).deduce("{i = T, j = T}");
+ from("int i = 0; int j = 0;", "i != 10 || j != 11", true).deduce("T");
}
public void testFloatEq() throws Exception {
from("float f = 0;", "f == 1.0", true).deduce("{f = 1.0}");
// There are positive and negative zeros. Do not deduce anything in here
- from("float f = 0;", "f == 0.0", true).deduce("{f = T}");
+ from("float f = 0;", "f == 0.0", true).deduce("T");
}
public void testDoubleEq() throws Exception {
from("double f = 0;", "f == 1.0", true).deduce("{f = 1.0}");
// There are positive and negative zeros. Do not deduce anything in here
- from("double f = 0;", "f == 0.0", true).deduce("{f = T}");
+ from("double f = 0;", "f == 0.0", true).deduce("T");
}
public void testNullNotNull() throws Exception {
from("String s = null;", "s == null", true).deduce("{s = null}");
- from("String s = null;", "s == null", false).deduce("{s = T}");
- from("String s = null;", "s != null", true).deduce("{s = T}");
+ from("String s = null;", "s == null", false).deduce("T");
+ from("String s = null;", "s != null", true).deduce("T");
from("String s = null;", "s != null", false).deduce("{s = null}");
from("String s = null;", "null == s", true).deduce("{s = null}");
- from("String s = null;", "null == s", false).deduce("{s = T}");
- from("String s = null;", "null != s", true).deduce("{s = T}");
+ from("String s = null;", "null == s", false).deduce("T");
+ from("String s = null;", "null != s", true).deduce("T");
from("String s = null;", "null != s", false).deduce("{s = null}");
}
@@ -108,10 +108,10 @@
List<JStatement> statements = block.getStatements();
JIfStatement ifStatement = (JIfStatement) statements.get(statements.size() - 1);
- Updater assumptions = new Updater(null);
+ Updater assumptions = new Updater(ConstantsAssumption.TOP);
AssumptionDeducer.deduceAssumption(ifStatement.getIfExpr(),
JBooleanLiteral.get(b), assumptions);
- return new Result(assumptions.unwrapToNotNull());
+ return new Result(assumptions.unwrap());
}
private class Result {
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java
index 82902bf..8a14d53 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
package com.google.gwt.dev.jjs.impl.gflow.constants;
import com.google.gwt.dev.jjs.impl.gflow.Analysis;
@@ -23,50 +38,50 @@
public void testDeclWithConstInit() throws Exception {
analyze("void", "int i = 1;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(i, 1) -> [* {i = 1}]",
"END");
}
public void testDeclWithConstOps() throws Exception {
analyze("void", "int i = 1 + 1;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(i, 2) -> [* {i = 2}]",
"END");
}
public void testDeclWithNonconstInit() throws Exception {
analyze("void", "int i = foo();").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
- "OPTTHROW(foo()) -> [NOTHROW=*, RE=1]",
- "CALL(foo) -> [*]",
- "WRITE(i, EntryPoint.foo()) -> [* {i = T}]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
+ "OPTTHROW(foo()) -> [NOTHROW=* T, RE=1 T]",
+ "CALL(foo) -> [* T]",
+ "WRITE(i, EntryPoint.foo()) -> [* T]",
"1: END");
}
public void testReassign() throws Exception {
analyze("void", "int i = 1; i = 2;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(i, 1) -> [* {i = 1}]",
"STMT -> [* {i = 1}]",
"WRITE(i, 2) -> [* {i = 2}]",
"END");
analyze("void", "int i; i = 3;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
+ "STMT -> [* T]",
"WRITE(i, 3) -> [* {i = 3}]",
"END");
}
public void test2Vars() throws Exception {
analyze("void", "int i = 1; int j = 2;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(i, 1) -> [* {i = 1}]",
"STMT -> [* {i = 1}]",
"WRITE(j, 2) -> [* {i = 1, j = 2}]",
@@ -75,8 +90,8 @@
public void testSequence() throws Exception {
analyze("void", "int i = 1; int j = i; int k = j; int l = k;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(i, 1) -> [* {i = 1}]",
"STMT -> [* {i = 1}]",
"READ(i) -> [* {i = 1}]",
@@ -92,26 +107,26 @@
public void testIfStatement() throws Exception {
analyze("void", "int i = k; if (i == 1) { int j = i; } else { int j = i; } ").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
- "READ(k) -> [*]",
- "WRITE(i, EntryPoint.k) -> [* {i = T}]",
- "STMT -> [* {i = T}]",
- "READ(i) -> [* {i = T}]",
- "COND (i == 1) -> [THEN=* {i = 1}, ELSE=1 {i = T}]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
+ "READ(k) -> [* T]",
+ "WRITE(i, EntryPoint.k) -> [* T]",
+ "STMT -> [* T]",
+ "READ(i) -> [* T]",
+ "COND (i == 1) -> [THEN=* {i = 1}, ELSE=1 T]",
"BLOCK -> [* {i = 1}]",
"STMT -> [* {i = 1}]",
"READ(i) -> [* {i = 1}]",
"WRITE(j, i) -> [2 {i = 1, j = 1}]",
- "1: BLOCK -> [* {i = T}]",
- "STMT -> [* {i = T}]",
- "READ(i) -> [* {i = T}]",
- "WRITE(j, i) -> [* {i = T, j = T}]",
+ "1: BLOCK -> [* T]",
+ "STMT -> [* T]",
+ "READ(i) -> [* T]",
+ "WRITE(j, i) -> [* T]",
"2: END");
analyze("int", "int j = 0; if (foo() == 1) j = 1; return j;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(j, 0) -> [* {j = 0}]",
"STMT -> [* {j = 0}]",
"OPTTHROW(foo()) -> [NOTHROW=* {j = 0}, RE=2 {j = 0}]",
@@ -119,14 +134,14 @@
"COND (EntryPoint.foo() == 1) -> [THEN=* {j = 0}, ELSE=1 {j = 0}]",
"STMT -> [* {j = 0}]",
"WRITE(j, 1) -> [* {j = 1}]",
- "1: STMT -> [* {j = T}]",
- "READ(j) -> [* {j = T}]",
- "GOTO -> [* {j = T}]",
+ "1: STMT -> [* T]",
+ "READ(j) -> [* T]",
+ "GOTO -> [* T]",
"2: END");
analyze("int", "int j = 0; if (foo() == 1) j = foo(); return j;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(j, 0) -> [* {j = 0}]",
"STMT -> [* {j = 0}]",
"OPTTHROW(foo()) -> [NOTHROW=* {j = 0}, RE=2 {j = 0}]",
@@ -135,30 +150,30 @@
"STMT -> [* {j = 0}]",
"OPTTHROW(foo()) -> [NOTHROW=* {j = 0}, RE=2 {j = 0}]",
"CALL(foo) -> [* {j = 0}]",
- "WRITE(j, EntryPoint.foo()) -> [* {j = T}]",
- "1: STMT -> [* {j = T}]",
- "READ(j) -> [* {j = T}]",
- "GOTO -> [* {j = T}]",
+ "WRITE(j, EntryPoint.foo()) -> [* T]",
+ "1: STMT -> [* T]",
+ "READ(j) -> [* T]",
+ "GOTO -> [* T]",
"2: END");
}
public void testWhileLoop1() throws Exception {
analyze("void", "int j = 1; while (j > 0) ++j;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(j, 1) -> [* {j = 1}]",
"STMT -> [* {j = 1}]",
- "1: READ(j) -> [* {j = T}]",
- "COND (j > 0) -> [THEN=* {j = T}, ELSE=2 {j = T}]",
- "STMT -> [* {j = T}]",
- "READWRITE(j, null) -> [1 {j = T}]",
+ "1: READ(j) -> [* T]",
+ "COND (j > 0) -> [THEN=* T, ELSE=2 T]",
+ "STMT -> [* T]",
+ "READWRITE(j, null) -> [1 T]",
"2: END");
}
public void testWhileLoop2() throws Exception {
analyze("void", "int j = 0; while (j > 0) {};").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(j, 0) -> [* {j = 0}]",
"STMT -> [* {j = 0}]",
"1: READ(j) -> [* {j = 0}]",
@@ -169,8 +184,8 @@
public void testConditionalExpressions() throws Exception {
analyze("void", "boolean b1 = false; boolean b2 = false; if (b1 && (b2 = true)) b1 = true;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(b1, false) -> [* {b1 = false}]",
"STMT -> [* {b1 = false}]",
"WRITE(b2, false) -> [* {b1 = false, b2 = false}]",
@@ -178,9 +193,9 @@
"READ(b1) -> [* {b1 = false, b2 = false}]",
"COND (b1) -> [THEN=* {b1 = false, b2 = false}, ELSE=1 {b1 = false, b2 = false}]",
"WRITE(b2, true) -> [* {b1 = false, b2 = true}]",
- "1: COND (b1 && (b2 = true)) -> [THEN=* {b1 = false, b2 = T}, ELSE=2 {b1 = false, b2 = T}]",
- "STMT -> [* {b1 = false, b2 = T}]",
- "WRITE(b1, true) -> [* {b1 = true, b2 = T}]",
+ "1: COND (b1 && (b2 = true)) -> [THEN=* {b1 = false}, ELSE=2 {b1 = false}]",
+ "STMT -> [* {b1 = false}]",
+ "WRITE(b1, true) -> [* {b1 = true}]",
"2: END");
}
@@ -193,8 +208,8 @@
"if (f != null) if (e == null)" +
" return;" +
"boolean b = e == null;").into(
- "BLOCK -> [*]",
- "STMT -> [*]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
"WRITE(e, null) -> [* {e = null}]",
"STMT -> [* {e = null}]",
"READ(f) -> [* {e = null}]",
@@ -216,18 +231,18 @@
*/
public void testParamNonConstant() throws Exception {
analyzeWithParams("void", "int i, int j", "if (j == 0) { i = 0; } j=i; j=0;").into(
- "BLOCK -> [* {i = T, j = T}]",
- "STMT -> [* {i = T, j = T}]",
- "READ(j) -> [* {i = T, j = T}]",
- "COND (j == 0) -> [THEN=* {i = T, j = 0}, ELSE=1 {i = T, j = T}]",
- "BLOCK -> [* {i = T, j = 0}]",
- "STMT -> [* {i = T, j = 0}]",
+ "BLOCK -> [* T]",
+ "STMT -> [* T]",
+ "READ(j) -> [* T]",
+ "COND (j == 0) -> [THEN=* {j = 0}, ELSE=1 T]",
+ "BLOCK -> [* {j = 0}]",
+ "STMT -> [* {j = 0}]",
"WRITE(i, 0) -> [* {i = 0, j = 0}]",
- "1: STMT -> [* {i = T, j = T}]",
- "READ(i) -> [* {i = T, j = T}]",
- "WRITE(j, i) -> [* {i = T, j = T}]",
- "STMT -> [* {i = T, j = T}]",
- "WRITE(j, 0) -> [* {i = T, j = 0}]",
+ "1: STMT -> [* T]",
+ "READ(i) -> [* T]",
+ "WRITE(j, i) -> [* T]",
+ "STMT -> [* T]",
+ "WRITE(j, 0) -> [* {j = 0}]",
"END"
);
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumptionTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumptionTest.java
new file mode 100644
index 0000000..b0dee1d
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAssumptionTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs.impl.gflow.constants;
+
+import com.google.gwt.dev.jjs.ast.JIntLiteral;
+import com.google.gwt.dev.jjs.ast.JLocal;
+import com.google.gwt.dev.jjs.ast.JMethodBody;
+import com.google.gwt.dev.jjs.ast.JPrimitiveType;
+import com.google.gwt.dev.jjs.ast.JProgram;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for ConstantsAssumption.
+ *
+ * We use toString comparison in this test to make it simpler.
+ */
+public class ConstantsAssumptionTest extends TestCase {
+ private final JIntLiteral zero = newIntLiteral(0);
+ private final JIntLiteral one = newIntLiteral(1);
+ private final JLocal i = newLocal("i", JPrimitiveType.INT);
+ private final JLocal j = newLocal("j", JPrimitiveType.INT);
+
+ public void testEmptyAssumption() {
+ ConstantsAssumption a = new ConstantsAssumption();
+ assertEquals("T", a.toString());
+ }
+
+ public void testSet() {
+ ConstantsAssumption a = new ConstantsAssumption();
+ a.set(i, zero);
+ assertEquals("{i = 0}", a.toString());
+ a.set(j, one);
+ assertEquals("{i = 0, j = 1}", a.toString());
+ a.set(i, null);
+ assertEquals("{j = 1}", a.toString());
+ }
+
+ public void testJoin_SameValues() {
+ ConstantsAssumption a1 = new ConstantsAssumption();
+ a1.set(i, zero);
+ a1.set(j, one);
+
+ ConstantsAssumption a2 = new ConstantsAssumption();
+ a2.set(i, zero);
+ a2.set(j, one);
+
+ assertEquals("{i = 0, j = 1}", a1.join(a2).toString());
+ }
+
+ public void testJoin_WithEmpty() {
+ ConstantsAssumption a1 = new ConstantsAssumption();
+ a1.set(i, zero);
+
+ assertEquals("T", a1.join(new ConstantsAssumption()).toString());
+ assertEquals("T", new ConstantsAssumption().join(a1).toString());
+ assertEquals("T", a1.join(ConstantsAssumption.TOP).toString());
+ assertEquals("T", ConstantsAssumption.TOP.join(a1).toString());
+
+ assertEquals(a1, a1.join(null));
+ }
+
+ public void testJoin_DifferentValues() {
+ ConstantsAssumption a1 = new ConstantsAssumption();
+ a1.set(i, zero);
+ a1.set(j, one);
+
+ ConstantsAssumption a2 = new ConstantsAssumption();
+ a2.set(i, one);
+ a2.set(j, zero);
+
+ assertEquals("T", a1.join(a2).toString());
+ }
+
+ public void testJoin_DifferentKeys() {
+ ConstantsAssumption a1 = new ConstantsAssumption();
+ a1.set(i, zero);
+
+ ConstantsAssumption a2 = new ConstantsAssumption();
+ a2.set(j, zero);
+
+ assertEquals("T", a1.join(a2).toString());
+ }
+
+ public void testEquals_ComparesValues() {
+ ConstantsAssumption a1 = new ConstantsAssumption();
+ a1.set(i, newIntLiteral(0));
+
+ ConstantsAssumption a2 = new ConstantsAssumption();
+ a2.set(i, newIntLiteral(0));
+
+ assertTrue(a1.equals(a2));
+ }
+
+ private JIntLiteral newIntLiteral(int value) {
+ return new JIntLiteral(null, value);
+ }
+
+ private JLocal newLocal(String name, JPrimitiveType type) {
+ return JProgram.createLocal(null, name, type, false, new JMethodBody(null));
+ }
+}