Track int parameters with bitwise AND operations
Bug: b/196017578
Change-Id: Ib6c820cce0c3069c7d3a49113182caf1535c9b95
diff --git a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java
index 6a72244..a897bd0 100644
--- a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java
+++ b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java
@@ -149,12 +149,12 @@
}
/**
- * Function for rewriting the unused arguments on a piece of method optimization info after
- * prototype changes were made.
+ * Function for rewriting a BitSet that stores a bit per argument on a piece of method
+ * optimization info after prototype changes were made.
*/
@Override
- public BitSet fixupUnusedArguments(BitSet unusedArguments) {
- return fixupArgumentInfo(unusedArguments);
+ public BitSet fixupArguments(BitSet arguments) {
+ return fixupArgumentInfo(arguments);
}
private BitSet fixupArgumentInfo(BitSet bitSet) {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
index c1a7b55..7327760 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
@@ -75,6 +75,9 @@
void classInitializerMayBePostponed(DexEncodedMethod method);
+ void setParametersWithBitwiseOperations(
+ ProgramMethod method, BitSet parametersWithBitwiseOperations);
+
void setUnusedArguments(ProgramMethod method, BitSet unusedArguments);
// Unset methods.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
index b1e1a69..f596d2a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
@@ -148,6 +148,16 @@
}
@Override
+ public boolean hasParametersWithBitwiseOperations() {
+ return false;
+ }
+
+ @Override
+ public BitSet getParametersWithBitwiseOperations() {
+ return null;
+ }
+
+ @Override
public BitSet getUnusedArguments() {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
index 0d42b62..31775ae 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
@@ -80,6 +80,10 @@
public abstract SimpleInliningConstraint getSimpleInliningConstraint();
+ public abstract boolean hasParametersWithBitwiseOperations();
+
+ public abstract BitSet getParametersWithBitwiseOperations();
+
public final boolean hasUnusedArguments() {
assert getUnusedArguments() == null || !getUnusedArguments().isEmpty();
return getUnusedArguments() != null;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index ba4ba64..892f856 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -101,6 +101,7 @@
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.kotlin.Kotlin.Intrinsics;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.Sets;
@@ -156,6 +157,7 @@
computeReturnValueOnlyDependsOnArguments(feedback, definition, code, timing);
BitSet nonNullParamOrThrow = computeNonNullParamOrThrow(feedback, definition, code, timing);
computeNonNullParamOnNormalExits(feedback, code, nonNullParamOrThrow, timing);
+ computeParametersWithBitwiseOperations(method, code, feedback, timing);
computeUnusedArguments(method, code, feedback, timing);
}
@@ -1173,6 +1175,36 @@
return true;
}
+ private void computeParametersWithBitwiseOperations(
+ ProgramMethod method, IRCode code, OptimizationFeedback feedback, Timing timing) {
+ timing.begin("Compute parameters with bitwise operations");
+ computeParametersWithBitwiseOperations(method, code, feedback);
+ timing.end();
+ }
+
+ private void computeParametersWithBitwiseOperations(
+ ProgramMethod method, IRCode code, OptimizationFeedback feedback) {
+ BitSet parametersWithBitwiseOperations = new BitSet(method.getParameters().size());
+ InstructionIterator instructionIterator = code.entryBlock().iterator();
+ Argument argument = instructionIterator.next().asArgument();
+ while (argument != null) {
+ if (hasBitwiseOperation(argument)) {
+ int parameterIndex =
+ argument.getIndex() - BooleanUtils.intValue(method.getDefinition().isInstance());
+ parametersWithBitwiseOperations.set(parameterIndex);
+ }
+ argument = instructionIterator.next().asArgument();
+ }
+ if (!parametersWithBitwiseOperations.isEmpty()) {
+ feedback.setParametersWithBitwiseOperations(method, parametersWithBitwiseOperations);
+ }
+ }
+
+ private boolean hasBitwiseOperation(Argument argument) {
+ return argument.getOutType().isInt()
+ && argument.outValue().hasUserThatMatches(Instruction::isAnd);
+ }
+
private void computeUnusedArguments(
ProgramMethod method, IRCode code, OptimizationFeedback feedback, Timing timing) {
timing.begin("Compute unused arguments");
@@ -1191,6 +1223,8 @@
}
argument = instructionIterator.next().asArgument();
}
- feedback.setUnusedArguments(method, unusedArguments);
+ if (!unusedArguments.isEmpty()) {
+ feedback.setUnusedArguments(method, unusedArguments);
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
index 0044499..4279b3c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
@@ -43,5 +43,5 @@
SimpleInliningConstraint constraint,
SimpleInliningConstraintFactory factory);
- public abstract BitSet fixupUnusedArguments(BitSet unusedArguments);
+ public abstract BitSet fixupArguments(BitSet arguments);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
index 7dcb035..555bd6f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
@@ -79,6 +79,7 @@
NeverSimpleInliningConstraint.getInstance();
private int maxRemovedAndroidLogLevel = MaximumRemovedAndroidLogLevelRule.NOT_SET;
+ private BitSet parametersWithBitwiseOperations = null;
private BitSet unusedArguments = null;
// To reduce the memory footprint of UpdatableMethodOptimizationInfo, all the boolean fields are
@@ -159,6 +160,7 @@
.fixupNonNullParamOnNormalExits(fixer)
.fixupNonNullParamOrThrow(fixer)
.fixupReturnedArgumentIndex(fixer)
+ .fixupParametersWithBitwiseOperations(fixer)
.fixupSimpleInliningConstraint(appView, fixer)
.fixupUnusedArguments(fixer);
}
@@ -435,13 +437,41 @@
}
@Override
+ public boolean hasParametersWithBitwiseOperations() {
+ return parametersWithBitwiseOperations != null;
+ }
+
+ @Override
+ public BitSet getParametersWithBitwiseOperations() {
+ return parametersWithBitwiseOperations;
+ }
+
+ public void setParametersWithBitwiseOperations(BitSet parametersWithBitwiseOperations) {
+ if (parametersWithBitwiseOperations != null && !parametersWithBitwiseOperations.isEmpty()) {
+ this.parametersWithBitwiseOperations = parametersWithBitwiseOperations;
+ } else {
+ this.parametersWithBitwiseOperations = null;
+ }
+ }
+
+ public MutableMethodOptimizationInfo fixupParametersWithBitwiseOperations(
+ MethodOptimizationInfoFixer fixer) {
+ return fixupParametersWithBitwiseOperations(fixer.fixupArguments(unusedArguments));
+ }
+
+ public MutableMethodOptimizationInfo fixupParametersWithBitwiseOperations(
+ BitSet parametersWithBitwiseOperations) {
+ setParametersWithBitwiseOperations(parametersWithBitwiseOperations);
+ return this;
+ }
+
+ @Override
public BitSet getUnusedArguments() {
return unusedArguments;
}
public MutableMethodOptimizationInfo fixupUnusedArguments(MethodOptimizationInfoFixer fixer) {
- fixupUnusedArguments(fixer.fixupUnusedArguments(unusedArguments));
- return this;
+ return fixupUnusedArguments(fixer.fixupArguments(unusedArguments));
}
public MutableMethodOptimizationInfo fixupUnusedArguments(BitSet unusedArguments) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
index 2148519..bbb1cec 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
@@ -277,6 +277,13 @@
}
@Override
+ public void setParametersWithBitwiseOperations(
+ ProgramMethod method, BitSet parametersWithBitwiseOperations) {
+ getMethodOptimizationInfoForUpdating(method)
+ .setParametersWithBitwiseOperations(parametersWithBitwiseOperations);
+ }
+
+ @Override
public synchronized void setUnusedArguments(ProgramMethod method, BitSet unusedArguments) {
getMethodOptimizationInfoForUpdating(method).setUnusedArguments(unusedArguments);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
index 3f46ce1..c3ff56a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
@@ -126,6 +126,10 @@
public void classInitializerMayBePostponed(DexEncodedMethod method) {}
@Override
+ public void setParametersWithBitwiseOperations(
+ ProgramMethod method, BitSet parametersWithBitwiseOperations) {}
+
+ @Override
public void setUnusedArguments(ProgramMethod method, BitSet unusedArguments) {}
// Unset methods.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
index a0c9863..51c5bb6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
@@ -213,6 +213,15 @@
}
@Override
+ public void setParametersWithBitwiseOperations(
+ ProgramMethod method, BitSet parametersWithBitwiseOperations) {
+ method
+ .getDefinition()
+ .getMutableOptimizationInfo()
+ .setParametersWithBitwiseOperations(parametersWithBitwiseOperations);
+ }
+
+ @Override
public void setUnusedArguments(ProgramMethod method, BitSet unusedArguments) {
method.getDefinition().getMutableOptimizationInfo().setUnusedArguments(unusedArguments);
}