Implement toString on computation trees

Change-Id: I89c8dd87db092b7a394a116eaa1c151d6aa8a2c8
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
index 6350b1e..8ccdaf1 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
@@ -35,6 +35,11 @@
     return null;
   }
 
+  @Override
+  public final boolean isComputationLeaf() {
+    return true;
+  }
+
   public abstract boolean isNonTrivial();
 
   public boolean isSingleBoolean() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/IfType.java b/src/main/java/com/android/tools/r8/ir/code/IfType.java
index 5babdae..3380e11 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IfType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IfType.java
@@ -15,6 +15,11 @@
         SingleNumberValue operand, AbstractValueFactory abstractValueFactory) {
       return abstractValueFactory.createSingleBooleanValue(operand.getValue() == 0);
     }
+
+    @Override
+    public String getSymbol() {
+      return "==";
+    }
   },
   GE {
     @Override
@@ -22,6 +27,11 @@
         SingleNumberValue operand, AbstractValueFactory abstractValueFactory) {
       return abstractValueFactory.createSingleBooleanValue(operand.getValue() >= 0);
     }
+
+    @Override
+    public String getSymbol() {
+      return ">=";
+    }
   },
   GT {
     @Override
@@ -29,6 +39,11 @@
         SingleNumberValue operand, AbstractValueFactory abstractValueFactory) {
       return abstractValueFactory.createSingleBooleanValue(operand.getValue() > 0);
     }
+
+    @Override
+    public String getSymbol() {
+      return ">";
+    }
   },
   LE {
     @Override
@@ -36,6 +51,11 @@
         SingleNumberValue operand, AbstractValueFactory abstractValueFactory) {
       return abstractValueFactory.createSingleBooleanValue(operand.getValue() <= 0);
     }
+
+    @Override
+    public String getSymbol() {
+      return "<=";
+    }
   },
   LT {
     @Override
@@ -43,6 +63,11 @@
         SingleNumberValue operand, AbstractValueFactory abstractValueFactory) {
       return abstractValueFactory.createSingleBooleanValue(operand.getValue() < 0);
     }
+
+    @Override
+    public String getSymbol() {
+      return "<";
+    }
   },
   NE {
     @Override
@@ -50,6 +75,11 @@
         SingleNumberValue operand, AbstractValueFactory abstractValueFactory) {
       return abstractValueFactory.createSingleBooleanValue(operand.getValue() != 0);
     }
+
+    @Override
+    public String getSymbol() {
+      return "!=";
+    }
   };
 
   public AbstractValue evaluate(AbstractValue operand, AbstractValueFactory abstractValueFactory) {
@@ -103,4 +133,6 @@
         throw new Unreachable("Unknown if condition type.");
     }
   }
+
+  public abstract String getSymbol();
 }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/MethodParameter.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/MethodParameter.java
index ed49cea..34c9e36 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/MethodParameter.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/MethodParameter.java
@@ -78,6 +78,11 @@
   }
 
   @Override
+  public boolean isComputationLeaf() {
+    return true;
+  }
+
+  @Override
   public boolean isMethodParameter() {
     return true;
   }
@@ -93,13 +98,16 @@
   }
 
   @Override
-  @SuppressWarnings({"EqualsGetClass", "ReferenceEquality"})
+  @SuppressWarnings("EqualsGetClass")
   public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
     if (obj == null || getClass() != obj.getClass()) {
       return false;
     }
     MethodParameter methodParameter = (MethodParameter) obj;
-    return method == methodParameter.method && index == methodParameter.index;
+    return method.isIdenticalTo(methodParameter.method) && index == methodParameter.index;
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeBaseNode.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeBaseNode.java
index 2228c3e..44aac0d 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeBaseNode.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeBaseNode.java
@@ -9,8 +9,16 @@
 abstract class ComputationTreeBaseNode implements ComputationTreeNode {
 
   @Override
+  public final boolean isComputationLeaf() {
+    return false;
+  }
+
+  @Override
   public abstract boolean equals(Object obj);
 
   @Override
   public abstract int hashCode();
+
+  @Override
+  public abstract String toString();
 }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeLogicalBinopAndNode.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeLogicalBinopAndNode.java
index f18f081..83ab680 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeLogicalBinopAndNode.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeLogicalBinopAndNode.java
@@ -47,4 +47,9 @@
   public int hashCode() {
     return Objects.hash(getClass(), left, right);
   }
+
+  @Override
+  public String toString() {
+    return left.toStringWithParenthesis() + " & " + right.toStringWithParenthesis();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeNode.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeNode.java
index 54cf0b1..4afd73c 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeNode.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeNode.java
@@ -23,7 +23,17 @@
     return false;
   }
 
+  boolean isComputationLeaf();
+
   default boolean isUnknown() {
     return false;
   }
+
+  default String toStringWithParenthesis() {
+    if (isComputationLeaf()) {
+      return toString();
+    } else {
+      return "(" + this + ")";
+    }
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeUnopCompareNode.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeUnopCompareNode.java
index 62455d4..2a12e72 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeUnopCompareNode.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/computation/ComputationTreeUnopCompareNode.java
@@ -64,4 +64,9 @@
   public int hashCode() {
     return Objects.hash(getClass(), operand, type);
   }
+
+  @Override
+  public String toString() {
+    return operand.toStringWithParenthesis() + " " + type.getSymbol() + " 0";
+  }
 }