Account for un-inlined accessor in proto builder optimization
Change-Id: I8ca2651a4175fca7a29ab198da29ad2571ca0fd4
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java
index ee60f6a..fc7866a 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.InvokeDirect;
+import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.LinearFlowInstructionListIterator;
import com.android.tools.r8.ir.code.NewInstance;
@@ -277,7 +278,23 @@
InvokeDirect constructorInvoke =
instructionIterator.nextUntil(
instruction -> {
- // After constructor inlining we may see a load of the DEFAULT_INSTANCE field.
+ // After constructor inlining we may see a load of the DEFAULT_INSTANCE field. This
+ // can either be read directly using a StaticGet or accessed indirectly via a
+ // synthetic accessor bridge (e.g., due to a -keep,allowshrinking rule).
+ if (instruction.isInvokeStatic()) {
+ InvokeStatic invoke = instruction.asInvokeStatic();
+ if (invoke
+ .getInvokedMethod()
+ .getHolderType()
+ .isIdenticalTo(defaultInstanceField.getHolderType())
+ && invoke
+ .getInvokedMethod()
+ .getReturnType()
+ .isIdenticalTo(defaultInstanceField.getType())) {
+ existingDefaultInstanceValue.set(invoke.outValue());
+ return false;
+ }
+ }
if (instruction.isStaticGet()) {
StaticGet staticGet = instruction.asStaticGet();
if (staticGet.getField() == defaultInstanceField) {