Revert "Solve effectively unused argument constraints"
This reverts commit c0bed33b81a610b111b776dfa1718054de53a8e0.
Reason for revert: app failures.
Change-Id: I0394fa87de36b94ffe5b03728565521b945048bd
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index ff6f7f5..a52190d 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -1004,18 +1004,11 @@
assert lookup.getType().isStatic();
- Value receiver = invoke.asInvokeMethodWithReceiver().getReceiver();
- TypeElement receiverType = receiver.getType();
+ TypeElement receiverType = invoke.asInvokeMethodWithReceiver().getReceiver().getType();
if (receiverType.isDefinitelyNotNull()) {
return iterator;
}
- // A parameter with users is only subject to effectively unused argument removal if it is
- // guaranteed to be non-null.
- if (receiver.isDefinedByInstructionSatisfying(Instruction::isUnusedArgument)) {
- return iterator;
- }
-
iterator.previous();
Position nullCheckPosition =
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java
index 4adcf5f..0702fc4 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java
@@ -236,4 +236,8 @@
DexMethodHandle newHandle = rewriteDexMethodHandle(oldHandle, use, context);
return newHandle != oldHandle ? new DexValueMethodHandle(newHandle) : methodHandle;
}
+
+ public boolean hasGraphLens(GraphLens graphLens, GraphLens codeLens) {
+ return this.graphLens == graphLens && this.codeLens == codeLens;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
index 96b68f3..cad4712 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
@@ -225,7 +225,7 @@
timing.end();
timing.begin("Compute unused arguments");
- effectivelyUnusedArgumentsAnalysis.computeEffectivelyUnusedArguments(codeScannerResult);
+ // TODO(b/215690172): Solve effectively unused argument constraints.
effectivelyUnusedArgumentsAnalysis = null;
timing.end();
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsAnalysis.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsAnalysis.java
index 7b7f6af..d40bf28 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsAnalysis.java
@@ -16,11 +16,9 @@
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodParameter;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodStateCollectionByReference;
import com.android.tools.r8.optimize.argumentpropagation.utils.ParameterRemovalUtils;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ListUtils;
-import com.android.tools.r8.utils.WorkList;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -173,40 +171,6 @@
return effectivelyUnusedConstraints;
}
- public void computeEffectivelyUnusedArguments(MethodStateCollectionByReference methodStates) {
- // Build a graph where nodes are method parameters and there is an edge from method parameter p0
- // to method parameter p1 if the removal of p0 depends on the removal of p1.
- EffectivelyUnusedArgumentsGraph dependenceGraph =
- EffectivelyUnusedArgumentsGraph.create(appView, constraints, methodStates);
-
- // Remove all unoptimizable method parameters from the graph, as well as all nodes that depend
- // on a node that is unoptimable.
- dependenceGraph.removeUnoptimizableNodes();
-
- // Repeatedly mark method parameters with no outgoing edges (i.e., no dependencies) as being
- // unused.
- WorkList<EffectivelyUnusedArgumentsGraphNode> worklist =
- WorkList.newIdentityWorkList(dependenceGraph.getNodes());
- while (!worklist.isEmpty()) {
- while (!worklist.isEmpty()) {
- EffectivelyUnusedArgumentsGraphNode node = worklist.removeSeen();
- assert dependenceGraph.verifyContains(node);
- node.removeUnusedSuccessors();
- if (node.getSuccessors().isEmpty()) {
- node.setUnused();
- node.getPredecessors().forEach(worklist::addIfNotSeen);
- node.cleanForRemoval();
- dependenceGraph.remove(node);
- }
- }
-
- // Handle mutually recursive methods. If there is a cycle p0 -> p1 -> ... -> pn -> p0 and each
- // of the method parameters p0 ... pn has a unique successor, then remove the edge pn -> p0
- // from the graph.
- dependenceGraph.removeClosedCycles(worklist::addIfNotSeen);
- }
- }
-
private boolean isUnoptimizable(ProgramMethod method) {
if (method.getDefinition().belongsToDirectPool()) {
return !ParameterRemovalUtils.canRemoveUnusedParametersFrom(appView, method);
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsGraph.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsGraph.java
deleted file mode 100644
index fdc01bc..0000000
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsGraph.java
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.optimize.argumentpropagation.unusedarguments;
-
-import static com.android.tools.r8.graph.DexClassAndMethod.asProgramMethodOrNull;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodParameter;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodStateCollectionByReference;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.WorkList;
-import com.android.tools.r8.utils.dfs.DFSStack;
-import com.android.tools.r8.utils.dfs.DFSWorklistItem;
-import com.android.tools.r8.utils.dfs.DFSWorklistItem.NewlyVisitedDFSWorklistItem;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import java.util.ArrayDeque;
-import java.util.Collection;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Consumer;
-
-class EffectivelyUnusedArgumentsGraph {
-
- private final AppView<AppInfoWithLiveness> appView;
-
- private final Map<MethodParameter, EffectivelyUnusedArgumentsGraphNode> nodes = new HashMap<>();
-
- private EffectivelyUnusedArgumentsGraph(AppView<AppInfoWithLiveness> appView) {
- this.appView = appView;
- }
-
- public static EffectivelyUnusedArgumentsGraph create(
- AppView<AppInfoWithLiveness> appView,
- Map<MethodParameter, Set<MethodParameter>> constraints,
- MethodStateCollectionByReference methodStates) {
- EffectivelyUnusedArgumentsGraph graph = new EffectivelyUnusedArgumentsGraph(appView);
- constraints.forEach(
- (methodParameter, constraintsForMethodParameter) -> {
- EffectivelyUnusedArgumentsGraphNode node = graph.getOrCreateNode(methodParameter);
- for (MethodParameter constraint : constraintsForMethodParameter) {
- graph.addConstraintEdge(node, constraint, constraints, methodStates);
- }
- });
- return graph;
- }
-
- void addConstraintEdge(
- EffectivelyUnusedArgumentsGraphNode node,
- MethodParameter constraint,
- Map<MethodParameter, Set<MethodParameter>> constraints,
- MethodStateCollectionByReference methodStates) {
- ProgramMethod dependencyMethod =
- asProgramMethodOrNull(appView.definitionFor(constraint.getMethod()));
- if (dependencyMethod == null) {
- assert false;
- node.setUnoptimizable();
- return;
- }
-
- // A nullable method parameter cannot be effectively unused if it is used as the receiver in an
- // invoke (or we cannot preserve NPE semantics).
- if (dependencyMethod.getDefinition().isInstance()
- && constraint.getIndex() == 0
- && node.isNullable(methodStates)) {
- node.setUnoptimizable();
- return;
- }
-
- // If the successor parameter does not have any constraints, then the successor is not subject
- // to effectively unused argument removal. In this case, the successor can only be removed if it
- // is truly unused.
- if (!constraints.containsKey(constraint)) {
- MethodOptimizationInfo optimizationInfo = dependencyMethod.getOptimizationInfo();
- if (!optimizationInfo.hasUnusedArguments()
- || !optimizationInfo.getUnusedArguments().get(constraint.getIndex())) {
- node.setUnoptimizable();
- }
- return;
- }
-
- EffectivelyUnusedArgumentsGraphNode successor = getOrCreateNode(constraint, dependencyMethod);
- if (node != successor) {
- node.addSuccessor(successor);
- }
- }
-
- Collection<EffectivelyUnusedArgumentsGraphNode> getNodes() {
- return nodes.values();
- }
-
- EffectivelyUnusedArgumentsGraphNode getOrCreateNode(MethodParameter parameter) {
- ProgramMethod method = asProgramMethodOrNull(appView.definitionFor(parameter.getMethod()));
- return method != null ? getOrCreateNode(parameter, method) : null;
- }
-
- EffectivelyUnusedArgumentsGraphNode getOrCreateNode(
- MethodParameter parameter, ProgramMethod method) {
- return nodes.computeIfAbsent(
- parameter, p -> new EffectivelyUnusedArgumentsGraphNode(method, p.getIndex()));
- }
-
- void remove(EffectivelyUnusedArgumentsGraphNode node) {
- assert node.getSuccessors().isEmpty();
- assert node.getPredecessors().isEmpty();
- MethodParameter methodParameter =
- new MethodParameter(node.getMethod().getReference(), node.getArgumentIndex());
- EffectivelyUnusedArgumentsGraphNode removed = nodes.remove(methodParameter);
- assert removed == node;
- }
-
- void removeClosedCycles(Consumer<EffectivelyUnusedArgumentsGraphNode> reprocess) {
- Set<EffectivelyUnusedArgumentsGraphNode> seen = Sets.newIdentityHashSet();
- for (EffectivelyUnusedArgumentsGraphNode root : getNodes()) {
- if (seen.contains(root)) {
- continue;
- }
- DFSStack<EffectivelyUnusedArgumentsGraphNode> stack = DFSStack.createIdentityStack();
- Deque<DFSWorklistItem<EffectivelyUnusedArgumentsGraphNode>> worklist = new ArrayDeque<>();
- worklist.add(new NewlyVisitedDFSWorklistItem<>(root));
- while (!worklist.isEmpty()) {
- DFSWorklistItem<EffectivelyUnusedArgumentsGraphNode> item = worklist.removeLast();
- stack.handle(item);
- if (item.isFullyVisited()) {
- continue;
- }
- EffectivelyUnusedArgumentsGraphNode node = item.getValue();
- seen.add(node);
- worklist.add(item.asNewlyVisited().toFullyVisited());
- node.getSuccessors()
- .removeIf(
- successor -> {
- if (stack.contains(successor)) {
- Deque<EffectivelyUnusedArgumentsGraphNode> cycle =
- stack.getCycleStartingAt(successor);
- boolean isClosedCycle =
- Iterables.all(cycle, member -> member.getSuccessors().size() == 1);
- if (isClosedCycle) {
- // Remove edge and reprocess this node, since it is now eligible for unused
- // argument removal.
- boolean removed = successor.getPredecessors().remove(node);
- assert removed;
- reprocess.accept(node);
- // Return true to remove the successor from the successors of the current
- // node (to prevent ConcurrentModificationException).
- return true;
- }
- } else {
- worklist.add(new NewlyVisitedDFSWorklistItem<>(successor));
- }
- return false;
- });
- }
- }
- }
-
- boolean verifyContains(EffectivelyUnusedArgumentsGraphNode node) {
- MethodParameter methodParameter =
- new MethodParameter(node.getMethod().getReference(), node.getArgumentIndex());
- return nodes.containsKey(methodParameter);
- }
-
- void removeUnoptimizableNodes() {
- WorkList<EffectivelyUnusedArgumentsGraphNode> worklist = WorkList.newIdentityWorkList();
- for (EffectivelyUnusedArgumentsGraphNode node : getNodes()) {
- if (node.isUnoptimizable()) {
- worklist.addIfNotSeen(node);
- }
- }
- while (worklist.hasNext()) {
- EffectivelyUnusedArgumentsGraphNode node = worklist.next();
- worklist.addIfNotSeen(node.getPredecessors());
- node.cleanForRemoval();
- remove(node);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsGraphNode.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsGraphNode.java
deleted file mode 100644
index 2b52686..0000000
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/unusedarguments/EffectivelyUnusedArgumentsGraphNode.java
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.optimize.argumentpropagation.unusedarguments;
-
-import static com.android.tools.r8.ir.optimize.info.OptimizationFeedback.getSimpleFeedback;
-
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteMonomorphicMethodState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodStateCollectionByReference;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ParameterState;
-import com.google.common.collect.Sets;
-import java.util.BitSet;
-import java.util.Set;
-
-class EffectivelyUnusedArgumentsGraphNode {
-
- private final ProgramMethod method;
- private final int argumentIndex;
-
- private final Set<EffectivelyUnusedArgumentsGraphNode> predecessors = Sets.newIdentityHashSet();
- private final Set<EffectivelyUnusedArgumentsGraphNode> successors = Sets.newIdentityHashSet();
-
- private boolean unoptimizable;
-
- EffectivelyUnusedArgumentsGraphNode(ProgramMethod method, int argumentIndex) {
- this.method = method;
- this.argumentIndex = argumentIndex;
- }
-
- void addSuccessor(EffectivelyUnusedArgumentsGraphNode node) {
- if (successors.add(node)) {
- node.predecessors.add(this);
- } else {
- assert node.predecessors.contains(this);
- }
- }
-
- void cleanForRemoval() {
- clearSuccessors();
- clearPredecessors();
- }
-
- void clearSuccessors() {
- for (EffectivelyUnusedArgumentsGraphNode successor : successors) {
- boolean removed = successor.predecessors.remove(this);
- assert removed;
- }
- successors.clear();
- }
-
- void clearPredecessors() {
- for (EffectivelyUnusedArgumentsGraphNode predecessor : predecessors) {
- boolean removed = predecessor.successors.remove(this);
- assert removed;
- }
- predecessors.clear();
- }
-
- public int getArgumentIndex() {
- return argumentIndex;
- }
-
- public ProgramMethod getMethod() {
- return method;
- }
-
- Set<EffectivelyUnusedArgumentsGraphNode> getPredecessors() {
- return predecessors;
- }
-
- Set<EffectivelyUnusedArgumentsGraphNode> getSuccessors() {
- return successors;
- }
-
- boolean isNullable(MethodStateCollectionByReference methodStates) {
- if (method.getDefinition().isInstance() && argumentIndex == 0) {
- return false;
- }
- MethodState methodState = methodStates.get(method);
- if (methodState.isBottom()) {
- // TODO: this means the method is unreachable? what to do in this case?
- return true;
- }
- assert !methodState.isBottom();
- if (methodState.isUnknown()) {
- return true;
- }
- assert methodState.isMonomorphic();
- ConcreteMonomorphicMethodState monomorphicMethodState = methodState.asMonomorphic();
- ParameterState parameterState = monomorphicMethodState.getParameterState(argumentIndex);
- if (parameterState.isUnknown()) {
- return true;
- }
- assert parameterState.isConcrete();
- assert parameterState.asConcrete().isReferenceParameter();
- return parameterState.asConcrete().asReferenceParameter().getNullability().isMaybeNull();
- }
-
- boolean isUnoptimizable() {
- return unoptimizable;
- }
-
- boolean isUnused() {
- return method.getOptimizationInfo().hasUnusedArguments()
- && method.getOptimizationInfo().getUnusedArguments().get(argumentIndex);
- }
-
- void removeUnusedSuccessors() {
- successors.removeIf(
- successor -> {
- if (successor.isUnused()) {
- boolean removed = successor.predecessors.remove(this);
- assert removed;
- return true;
- }
- return false;
- });
- }
-
- void setUnoptimizable() {
- unoptimizable = true;
- }
-
- void setUnused() {
- if (method.getOptimizationInfo().hasUnusedArguments()) {
- getSimpleFeedback()
- .fixupUnusedArguments(method, unusedArguments -> unusedArguments.set(argumentIndex));
- } else {
- BitSet unusedArguments = new BitSet(method.getDefinition().getNumberOfArguments());
- unusedArguments.set(argumentIndex);
- getSimpleFeedback().setUnusedArguments(method, unusedArguments);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/utils/WorkList.java b/src/main/java/com/android/tools/r8/utils/WorkList.java
index 70faab7..3177689 100644
--- a/src/main/java/com/android/tools/r8/utils/WorkList.java
+++ b/src/main/java/com/android/tools/r8/utils/WorkList.java
@@ -117,12 +117,6 @@
return workingList.removeFirst();
}
- public T removeSeen() {
- T next = next();
- seen.remove(next);
- return next;
- }
-
public Set<T> getSeenSet() {
return Collections.unmodifiableSet(seen);
}
diff --git a/src/main/java/com/android/tools/r8/utils/dfs/DFSStack.java b/src/main/java/com/android/tools/r8/utils/dfs/DFSStack.java
deleted file mode 100644
index 635d9a6..0000000
--- a/src/main/java/com/android/tools/r8/utils/dfs/DFSStack.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.utils.dfs;
-
-import com.google.common.collect.Sets;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.Set;
-
-public class DFSStack<T> {
-
- private final Deque<T> stack;
- private final Set<T> stackSet;
-
- private DFSStack(Deque<T> stack, Set<T> stackSet) {
- this.stack = stack;
- this.stackSet = stackSet;
- }
-
- public static <T> DFSStack<T> createIdentityStack() {
- return new DFSStack<>(new ArrayDeque<>(), Sets.newIdentityHashSet());
- }
-
- public boolean contains(T item) {
- return stackSet.contains(item);
- }
-
- public Deque<T> getCycleStartingAt(T entry) {
- Deque<T> cycle = new ArrayDeque<>();
- do {
- assert !stack.isEmpty();
- cycle.addLast(stack.removeLast());
- } while (cycle.getLast() != entry);
- recoverStack(cycle);
- return cycle;
- }
-
- public void handle(DFSWorklistItem<T> item) {
- if (item.isNewlyVisited()) {
- push(item.getValue());
- } else {
- assert item.isFullyVisited();
- pop(item.getValue());
- }
- }
-
- public void pop(T expectedItem) {
- T popped = stack.removeLast();
- assert popped == expectedItem;
- boolean removed = stackSet.remove(popped);
- assert removed;
- }
-
- public void push(T item) {
- stack.addLast(item);
- boolean added = stackSet.add(item);
- assert added;
- }
-
- private void recoverStack(Deque<T> extractedCycle) {
- Iterator<T> descendingIt = extractedCycle.descendingIterator();
- while (descendingIt.hasNext()) {
- stack.addLast(descendingIt.next());
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/utils/dfs/DFSWorklistItem.java b/src/main/java/com/android/tools/r8/utils/dfs/DFSWorklistItem.java
deleted file mode 100644
index 4020cea..0000000
--- a/src/main/java/com/android/tools/r8/utils/dfs/DFSWorklistItem.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.utils.dfs;
-
-public abstract class DFSWorklistItem<T> {
-
- T value;
-
- public DFSWorklistItem(T value) {
- this.value = value;
- }
-
- public T getValue() {
- return value;
- }
-
- public boolean isFullyVisited() {
- return false;
- }
-
- public boolean isNewlyVisited() {
- return false;
- }
-
- public NewlyVisitedDFSWorklistItem<T> asNewlyVisited() {
- return null;
- }
-
- public static class NewlyVisitedDFSWorklistItem<T> extends DFSWorklistItem<T> {
-
- public NewlyVisitedDFSWorklistItem(T value) {
- super(value);
- }
-
- @Override
- public boolean isNewlyVisited() {
- return true;
- }
-
- @Override
- public NewlyVisitedDFSWorklistItem<T> asNewlyVisited() {
- return this;
- }
-
- public FullyVisitedDFSWorklistItem<T> toFullyVisited() {
- return new FullyVisitedDFSWorklistItem<>(getValue());
- }
- }
-
- public static class FullyVisitedDFSWorklistItem<T> extends DFSWorklistItem<T> {
-
- public FullyVisitedDFSWorklistItem(T value) {
- super(value);
- }
-
- @Override
- public boolean isFullyVisited() {
- return true;
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
index acf29ec..15f68fc 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
@@ -170,8 +170,9 @@
assertEquals(
Lists.newArrayList(
"STATIC: String SimpleWithParams.bar(String)",
- "STATIC: String SimpleWithParams.foo()",
- "STATIC: String TrivialTestClass.next()"),
+ "STATIC: String TrivialTestClass.next()",
+ "SimpleWithParams SimpleWithParams.INSTANCE",
+ "VIRTUAL: String SimpleWithParams.foo()"),
references(clazz, "testSimpleWithParams", "void"));
ClassSubject simpleWithParams = inspector.clazz(SimpleWithParams.class);
@@ -198,18 +199,20 @@
references(clazz, "testSimpleWithGetter", "void"));
ClassSubject simpleWithGetter = inspector.clazz(SimpleWithGetter.class);
- assertEquals(0, instanceMethods(simpleWithGetter).size());
- assertThat(simpleWithGetter.clinit(), isAbsent());
+ assertTrue(instanceMethods(simpleWithGetter).isEmpty());
+ assertThat(simpleWithGetter.clinit(), not(isPresent()));
assertEquals(
Lists.newArrayList(
- "STATIC: String SimpleWithLazyInit.bar$1(String)",
- "STATIC: String SimpleWithLazyInit.foo$1()",
- "STATIC: String TrivialTestClass.next()"),
+ "STATIC: String SimpleWithThrowingGetter.bar(String)",
+ "STATIC: String TrivialTestClass.next()",
+ "SimpleWithThrowingGetter SimpleWithThrowingGetter.INSTANCE",
+ "VIRTUAL: String SimpleWithThrowingGetter.foo()"),
references(clazz, "testSimpleWithThrowingGetter", "void"));
ClassSubject simpleWithThrowingGetter = inspector.clazz(SimpleWithThrowingGetter.class);
- assertThat(simpleWithThrowingGetter, isAbsent());
+ assertFalse(instanceMethods(simpleWithThrowingGetter).isEmpty());
+ assertThat(simpleWithThrowingGetter.clinit(), isPresent());
// TODO(b/143389508): add support for lazy init in singleton instance getter.
assertEquals(
@@ -217,19 +220,19 @@
"DIRECT: void SimpleWithLazyInit.<init>()",
"DIRECT: void SimpleWithLazyInit.<init>()",
"STATIC: String SimpleWithLazyInit.bar(String)",
- "STATIC: String SimpleWithLazyInit.foo()",
"STATIC: String TrivialTestClass.next()",
"SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
"SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
"SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
"SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
"SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
- "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE"),
+ "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
+ "VIRTUAL: String SimpleWithLazyInit.foo()"),
references(clazz, "testSimpleWithLazyInit", "void"));
ClassSubject simpleWithLazyInit = inspector.clazz(SimpleWithLazyInit.class);
assertFalse(instanceMethods(simpleWithLazyInit).isEmpty());
- assertThat(simpleWithLazyInit.clinit(), isPresent());
+ assertThat(simpleWithLazyInit.clinit(), not(isPresent()));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/EffectivelyUnusedNullableArgumentTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/EffectivelyUnusedNullableArgumentTest.java
deleted file mode 100644
index 54d2071..0000000
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/EffectivelyUnusedNullableArgumentTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.optimize.unusedarguments;
-
-import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isStatic;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.MethodSubject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class EffectivelyUnusedNullableArgumentTest extends TestBase {
-
- @Parameter(0)
- public TestParameters parameters;
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
- }
-
- @Test
- public void test() throws Exception {
- testForR8(parameters.getBackend())
- .addInnerClasses(getClass())
- .addKeepMainRule(Main.class)
- .enableInliningAnnotations()
- .enableNeverClassInliningAnnotations()
- // TODO(b/173398086): uniqueMethodWithName() does not work with argument changes.
- .noMinification()
- .setMinApi(parameters.getApiLevel())
- .compile()
- .inspect(
- inspector -> {
- ClassSubject aClassSubject = inspector.clazz(A.class);
-
- MethodSubject fooMethodSubject = aClassSubject.uniqueMethodWithName("foo");
- assertThat(fooMethodSubject, isPresent());
- assertEquals(1, fooMethodSubject.getProgramMethod().getParameters().size());
- assertEquals(
- aClassSubject.getDexProgramClass().getType(),
- fooMethodSubject.getProgramMethod().getParameter(0));
- assertThat(
- fooMethodSubject,
- invokesMethodWithName(
- canUseJavaUtilObjectsRequireNonNull(parameters)
- ? "requireNonNull"
- : "getClass"));
-
- MethodSubject barMethodSubject = aClassSubject.uniqueMethodWithName("bar");
- assertThat(barMethodSubject, isStatic());
- })
- .run(parameters.getRuntime(), Main.class)
- .assertFailureWithErrorThatThrows(NullPointerException.class);
- }
-
- static class Main {
-
- public static void main(String[] args) {
- A a = System.currentTimeMillis() > 0 ? null : new A();
- A.foo(a);
- }
- }
-
- @NeverClassInline
- static class A {
-
- // This parameter cannot be removed, since the program needs to fail at the call to A.bar() when
- // A.foo(null) is called.
- @NeverInline
- static void foo(A a) {
- a.bar();
- }
-
- @NeverInline
- void bar() {
- System.out.println("A.bar()");
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java b/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java
index 10fec23..2200ea7 100644
--- a/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/retraceproguard/RetraceTestBase.java
@@ -6,11 +6,9 @@
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.R8TestBuilder;
-import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.naming.retraceproguard.StackTrace.StackTraceLine;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
@@ -53,14 +51,6 @@
public void runTest(List<String> keepRules, BiConsumer<StackTrace, StackTrace> checker)
throws Exception {
- runTest(keepRules, checker, ThrowableConsumer.empty());
- }
-
- public void runTest(
- List<String> keepRules,
- BiConsumer<StackTrace, StackTrace> checker,
- ThrowableConsumer<R8TestCompileResult> compileResultConsumer)
- throws Exception {
R8TestRunResult result =
(compat ? testForR8Compat(parameters.getBackend()) : testForR8(parameters.getBackend()))
.setMode(mode)
@@ -70,8 +60,6 @@
.addKeepRules(keepRules)
.setMinApi(parameters.getApiLevel())
.apply(this::configure)
- .compile()
- .apply(compileResultConsumer)
.run(parameters.getRuntime(), getMainClass())
.assertFailure();
diff --git a/src/test/java/com/android/tools/r8/naming/retraceproguard/VerticalClassMergingRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retraceproguard/VerticalClassMergingRetraceTest.java
index bb37a8a..5905930 100644
--- a/src/test/java/com/android/tools/r8/naming/retraceproguard/VerticalClassMergingRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retraceproguard/VerticalClassMergingRetraceTest.java
@@ -5,8 +5,6 @@
import static com.android.tools.r8.naming.retraceproguard.StackTrace.isSameExceptForFileName;
import static com.android.tools.r8.naming.retraceproguard.StackTrace.isSameExceptForFileNameAndLineNumber;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.onlyIf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
@@ -14,16 +12,11 @@
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestBuilder;
-import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.naming.retraceproguard.StackTrace.StackTraceLine;
import com.android.tools.r8.utils.BooleanUtils;
-import com.android.tools.r8.utils.Box;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
@@ -82,54 +75,45 @@
return height;
}
- private boolean filterSynthesizedMethod(
- StackTraceLine retracedStackTraceLine, MethodSubject syntheticMethod) {
- if (syntheticMethod.isPresent()) {
- String qualifiedMethodName =
- retracedStackTraceLine.className + "." + retracedStackTraceLine.methodName;
- return !qualifiedMethodName.equals(syntheticMethod.getOriginalName())
- || retracedStackTraceLine.lineNumber > 0;
- }
- return true;
+ private boolean filterSynthesizedMethod(StackTraceLine retracedStackTraceLine) {
+ return retracedStackTraceLine.lineNumber > 0;
}
@Test
public void testSourceFileAndLineNumberTable() throws Exception {
- Box<MethodSubject> syntheticMethod = new Box<>();
runTest(
ImmutableList.of("-keepattributes SourceFile,LineNumberTable"),
(StackTrace actualStackTrace, StackTrace retracedStackTrace) -> {
// Even when SourceFile is present retrace replaces the file name in the stack trace.
StackTrace reprocessedStackTrace =
- retracedStackTrace.filter(
- stackTraceLine -> filterSynthesizedMethod(stackTraceLine, syntheticMethod.get()));
+ mode == CompilationMode.DEBUG
+ ? retracedStackTrace
+ : retracedStackTrace.filter(this::filterSynthesizedMethod);
assertThat(
reprocessedStackTrace.filter(this::isNotDalvikNativeStartMethod),
isSameExceptForFileName(
expectedStackTrace.filter(this::isNotDalvikNativeStartMethod)));
assertEquals(expectedActualStackTraceHeight(), actualStackTrace.size());
- },
- compileResult -> setSyntheticMethod(compileResult, syntheticMethod));
+ });
}
@Test
public void testLineNumberTableOnly() throws Exception {
assumeTrue(compat);
assumeTrue(parameters.isDexRuntime());
- Box<MethodSubject> syntheticMethod = new Box<>();
runTest(
ImmutableList.of("-keepattributes LineNumberTable"),
(StackTrace actualStackTrace, StackTrace retracedStackTrace) -> {
StackTrace reprocessedStackTrace =
- retracedStackTrace.filter(
- stackTraceLine -> filterSynthesizedMethod(stackTraceLine, syntheticMethod.get()));
+ mode == CompilationMode.DEBUG
+ ? retracedStackTrace
+ : retracedStackTrace.filter(this::filterSynthesizedMethod);
assertThat(
reprocessedStackTrace.filter(this::isNotDalvikNativeStartMethod),
isSameExceptForFileName(
expectedStackTrace.filter(this::isNotDalvikNativeStartMethod)));
assertEquals(expectedActualStackTraceHeight(), actualStackTrace.size());
- },
- compileResult -> setSyntheticMethod(compileResult, syntheticMethod));
+ });
}
@Test
@@ -137,32 +121,18 @@
assumeTrue(compat);
assumeTrue(parameters.isDexRuntime());
haveSeenLines.clear();
- Box<MethodSubject> syntheticMethod = new Box<>();
runTest(
ImmutableList.of(),
(StackTrace actualStackTrace, StackTrace retracedStackTrace) -> {
StackTrace reprocessedStackTrace =
- retracedStackTrace.filter(
- stackTraceLine -> filterSynthesizedMethod(stackTraceLine, syntheticMethod.get()));
+ mode == CompilationMode.DEBUG
+ ? retracedStackTrace
+ : retracedStackTrace.filter(this::filterSynthesizedMethod);
assertThat(
reprocessedStackTrace.filter(this::isNotDalvikNativeStartMethod),
isSameExceptForFileNameAndLineNumber(
expectedStackTrace.filter(this::isNotDalvikNativeStartMethod)));
assertEquals(expectedActualStackTraceHeight(), actualStackTrace.size());
- },
- compileResult -> setSyntheticMethod(compileResult, syntheticMethod));
- }
-
- private void setSyntheticMethod(
- R8TestCompileResult compileResult, Box<MethodSubject> syntheticMethod) throws IOException {
- compileResult.inspect(
- inspector -> {
- ClassSubject tintResourcesClassSubject = inspector.clazz(TintResources.class);
- MethodSubject uniqueSyntheticMethod =
- tintResourcesClassSubject.uniqueMethodThatMatches(
- method -> method.getAccessFlags().isSynthetic());
- assertThat(uniqueSyntheticMethod, onlyIf(mode == CompilationMode.RELEASE, isPresent()));
- syntheticMethod.set(uniqueSyntheticMethod);
});
}
}
diff --git a/src/test/java/com/android/tools/r8/optimize/argumentpropagation/EffectivelyFinalCompanionMethodsTest.java b/src/test/java/com/android/tools/r8/optimize/argumentpropagation/EffectivelyFinalCompanionMethodsTest.java
deleted file mode 100644
index ac05de2..0000000
--- a/src/test/java/com/android/tools/r8/optimize/argumentpropagation/EffectivelyFinalCompanionMethodsTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.optimize.argumentpropagation;
-
-import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isStatic;
-import static junit.framework.TestCase.assertEquals;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.NoHorizontalClassMerging;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class EffectivelyFinalCompanionMethodsTest extends TestBase {
-
- @Parameter(0)
- public TestParameters parameters;
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
- }
-
- @Test
- public void test() throws Exception {
- testForR8(parameters.getBackend())
- .addInnerClasses(getClass())
- .addKeepMainRule(Main.class)
- .addOptionsModification(options -> options.enableClassStaticizer = false)
- .enableInliningAnnotations()
- .enableNeverClassInliningAnnotations()
- .enableNoHorizontalClassMergingAnnotations()
- .noMinification()
- .setMinApi(parameters.getApiLevel())
- .compile()
- .inspect(
- inspector -> {
- ClassSubject hostClassSubject = inspector.clazz(Host.class);
- assertThat(hostClassSubject, isAbsent());
-
- ClassSubject companionClassSubject = inspector.clazz(Host.Companion.class);
- assertThat(companionClassSubject, isPresent());
- assertEquals(4, companionClassSubject.allMethods().size());
- assertThat(companionClassSubject.uniqueMethodWithName("foo"), isStatic());
- assertThat(companionClassSubject.uniqueMethodWithName("bar"), isStatic());
- assertThat(companionClassSubject.uniqueMethodWithName("baz"), isStatic());
- assertThat(companionClassSubject.uniqueMethodWithName("qux"), isStatic());
- })
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutputLines("Foo!", "Bar!", "Baz!", "Qux!", "Baz!");
- }
-
- static class Main {
-
- public static void main(String[] args) {
- Host.companion.foo();
- }
- }
-
- static class Host {
-
- static final Companion companion = new Companion();
-
- @NeverClassInline
- @NoHorizontalClassMerging
- static class Companion {
-
- @NeverInline
- void foo() {
- System.out.println("Foo!");
- bar();
- }
-
- @NeverInline
- void bar() {
- System.out.println("Bar!");
- baz(true);
- }
-
- @NeverInline
- void baz(boolean doQux) {
- System.out.println("Baz!");
- if (doQux) {
- qux();
- }
- }
-
- @NeverInline
- void qux() {
- System.out.println("Qux!");
- baz(false);
- }
- }
- }
-}