Dynamic upper bound types for phis
Change-Id: I7b29c7a33cdd6a497aa95f5bc0913b3a862058cc
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 2f0911d..16fc789 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InvalidDebugInfoException;
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexMethod;
@@ -16,11 +17,14 @@
import com.android.tools.r8.ir.conversion.TypeConstraintResolver;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.CfgPrinter;
+import com.android.tools.r8.utils.DequeUtils;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.SetUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
+import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -395,4 +399,31 @@
}
return result;
}
+
+ @Override
+ public TypeLatticeElement getDynamicUpperBoundType(
+ AppView<? extends AppInfoWithSubtyping> appView) {
+ Set<Phi> reachablePhis = SetUtils.newIdentityHashSet(this);
+ Deque<Phi> worklist = DequeUtils.newArrayDeque(this);
+ while (!worklist.isEmpty()) {
+ Phi phi = worklist.removeFirst();
+ assert reachablePhis.contains(phi);
+ for (Value operand : phi.getOperands()) {
+ Phi candidate = operand.getAliasedValue().asPhi();
+ if (candidate != null && reachablePhis.add(candidate)) {
+ worklist.addLast(candidate);
+ }
+ }
+ }
+ Set<Value> visitedOperands = Sets.newIdentityHashSet();
+ TypeLatticeElement result = TypeLatticeElement.BOTTOM;
+ for (Phi phi : reachablePhis) {
+ for (Value operand : phi.getOperands()) {
+ if (!operand.getAliasedValue().isPhi() && visitedOperands.add(operand)) {
+ result = result.join(operand.getDynamicUpperBoundType(appView), appView);
+ }
+ }
+ }
+ return result;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 75f5831..d6372b5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -1114,6 +1114,14 @@
public TypeLatticeElement getDynamicUpperBoundType(
AppView<? extends AppInfoWithSubtyping> appView) {
+ Value root = getAliasedValue();
+ if (root.isPhi()) {
+ assert getSpecificAliasedValue(
+ value -> !value.isPhi() && value.definition.isAssumeDynamicType())
+ == null;
+ return root.getDynamicUpperBoundType(appView);
+ }
+
// Try to find an alias of the receiver, which is defined by an instruction of the type
// Assume<DynamicTypeAssumption>.
Value aliasedValue =