Add LirToLirDesugaredLibraryRetargeter
This adds support for running the DesugaredLibraryRetargeter cf-to-cf and lir-to-lir.
This only implements lir-to-lir retargeting for fields. It remains to implement lir-to-lir retargeting for methods.
Bug: b/391572031
Change-Id: I16357caecd01c0f45c9abf404f5d602752682bb4
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 8370d23..1ff5fe1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -67,7 +67,7 @@
import com.android.tools.r8.ir.desugar.backports.TypedArrayMethodRewrites;
import com.android.tools.r8.ir.desugar.desugaredlibrary.LibraryDesugaringOptions;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.AutoCloseableRetargeterHelper;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeter;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterHelper;
import com.android.tools.r8.position.MethodPosition;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.synthesis.SyntheticNaming;
@@ -220,7 +220,7 @@
BackportedMethodRewriter.RewritableMethods rewritableMethods =
new BackportedMethodRewriter.RewritableMethods(appView);
rewritableMethods.visit(methods);
- new DesugaredLibraryRetargeter(appView).visit(methods);
+ new DesugaredLibraryRetargeterHelper(appView).visit(methods);
new AutoCloseableRetargeterHelper(options.getMinApiLevel(), options.dexItemFactory())
.visit(methods);
rewritableMethods.visitFields(fields);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
index b66ceee..06c814d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.disabledesugarer.DesugaredLibraryDisableDesugarer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.AutoCloseableRetargeter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.CfToCfDesugaredLibraryLibRewriter;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.CfToCfDesugaredLibraryRetargeter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryLibRewriter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeter;
import com.android.tools.r8.ir.desugar.icce.AlwaysThrowingInstructionDesugaring;
@@ -65,7 +66,7 @@
private final List<CfInstructionDesugaring> yieldingDesugarings = new ArrayList<>();
private final NestBasedAccessDesugaring nestBasedAccessDesugaring;
- private final DesugaredLibraryRetargeter desugaredLibraryRetargeter;
+ private final CfToCfDesugaredLibraryRetargeter desugaredLibraryRetargeter;
private final InterfaceMethodRewriter interfaceMethodRewriter;
private final CfToCfDesugaredLibraryApiConverter desugaredLibraryAPIConverter;
private final DesugaredLibraryDisableDesugarer disableDesugarer;
@@ -112,14 +113,7 @@
if (desugaredLibRewriter != null) {
desugarings.add(desugaredLibRewriter);
}
- desugaredLibraryRetargeter =
- appView
- .options()
- .getLibraryDesugaringOptions()
- .getMachineDesugaredLibrarySpecification()
- .hasRetargeting()
- ? new DesugaredLibraryRetargeter(appView)
- : null;
+ desugaredLibraryRetargeter = DesugaredLibraryRetargeter.createCfToCf(appView);
if (desugaredLibraryRetargeter != null) {
desugarings.add(desugaredLibraryRetargeter);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaring.java
index d59d1cb..b3904bf 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaring.java
@@ -22,6 +22,7 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.LirToLirDesugaredLibraryApiConverter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryLibRewriter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.LirToLirDesugaredLibraryLibRewriter;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.LirToLirDesugaredLibraryRetargeter;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
import com.android.tools.r8.ir.optimize.DeadCodeRemover;
@@ -97,6 +98,8 @@
appView, profileCollectionAdditions);
LirToLirDesugaredLibraryLibRewriter desugaredLibraryLibRewriter =
DesugaredLibraryLibRewriter.createLirToLir(appView, eventConsumer);
+ LirToLirDesugaredLibraryRetargeter desugaredLibraryRetargeter =
+ LirToLirDesugaredLibraryRetargeter.createLirToLir(appView);
// TODO(b/391572031): Implement lir-to-lir interface method rewriting.
InterfaceMethodRewriter interfaceMethodRewriter = null;
LirToLirDesugaredLibraryApiConverter desugaredLibraryAPIConverter =
@@ -117,6 +120,7 @@
appView,
desugaredLibraryAPIConverter,
desugaredLibraryLibRewriter,
+ desugaredLibraryRetargeter,
interfaceMethodRewriter,
eventConsumer,
method,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaringGraphLens.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaringGraphLens.java
index 867641b..1c3e14a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaringGraphLens.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/R8LibraryDesugaringGraphLens.java
@@ -34,6 +34,7 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryConversionCfProvider;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.LirToLirDesugaredLibraryApiConverter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.LirToLirDesugaredLibraryLibRewriter;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.LirToLirDesugaredLibraryRetargeter;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
import com.android.tools.r8.ir.optimize.CustomLensCodeRewriter;
import java.util.ArrayList;
@@ -45,6 +46,7 @@
private final LirToLirDesugaredLibraryApiConverter desugaredLibraryAPIConverter;
private final LirToLirDesugaredLibraryLibRewriter desugaredLibraryLibRewriter;
+ private final LirToLirDesugaredLibraryRetargeter desugaredLibraryRetargeter;
@SuppressWarnings("UnusedVariable")
private final InterfaceMethodRewriter interfaceMethodRewriter;
@@ -62,6 +64,7 @@
AppView<? extends AppInfoWithClassHierarchy> appView,
LirToLirDesugaredLibraryApiConverter desugaredLibraryAPIConverter,
LirToLirDesugaredLibraryLibRewriter desugaredLibraryLibRewriter,
+ LirToLirDesugaredLibraryRetargeter desugaredLibraryRetargeter,
InterfaceMethodRewriter interfaceMethodRewriter,
CfInstructionDesugaringEventConsumer eventConsumer,
ProgramMethod method,
@@ -69,6 +72,7 @@
super(appView);
this.desugaredLibraryAPIConverter = desugaredLibraryAPIConverter;
this.desugaredLibraryLibRewriter = desugaredLibraryLibRewriter;
+ this.desugaredLibraryRetargeter = desugaredLibraryRetargeter;
this.interfaceMethodRewriter = interfaceMethodRewriter;
this.eventConsumer = eventConsumer;
this.method = method;
@@ -87,7 +91,9 @@
@Override
protected FieldLookupResult internalDescribeLookupField(FieldLookupResult previous) {
- // TODO(b/391572031): Implement field access desugaring.
+ if (desugaredLibraryRetargeter != null) {
+ return desugaredLibraryRetargeter.lookupField(previous, method, this);
+ }
return previous;
}
@@ -105,6 +111,14 @@
}
}
+ if (desugaredLibraryRetargeter != null) {
+ MethodLookupResult result =
+ desugaredLibraryRetargeter.lookupMethod(previous, method, methodProcessingContext, this);
+ if (result != previous) {
+ return result;
+ }
+ }
+
if (desugaredLibraryAPIConverter != null) {
return desugaredLibraryAPIConverter.lookupMethod(
previous, method, methodProcessingContext, this);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/CfToCfDesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/CfToCfDesugaredLibraryRetargeter.java
new file mode 100644
index 0000000..aed15b8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/CfToCfDesugaredLibraryRetargeter.java
@@ -0,0 +1,160 @@
+// Copyright (c) 2025, 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.desugar.desugaredlibrary.retargeter;
+
+import com.android.tools.r8.cf.code.CfFieldInstruction;
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfInvoke;
+import com.android.tools.r8.cf.code.CfOpcodeUtils;
+import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.MethodResolutionResult;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
+import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.DesugarDescription;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
+import java.util.Collections;
+import java.util.function.BiFunction;
+import java.util.function.IntConsumer;
+import org.objectweb.asm.Opcodes;
+
+public class CfToCfDesugaredLibraryRetargeter extends DesugaredLibraryRetargeter
+ implements CfInstructionDesugaring {
+
+ CfToCfDesugaredLibraryRetargeter(AppView<?> appView) {
+ super(appView);
+ }
+
+ @Override
+ public void acceptRelevantAsmOpcodes(IntConsumer consumer) {
+ CfOpcodeUtils.acceptCfInvokeOpcodes(consumer);
+ consumer.accept(Opcodes.GETSTATIC);
+ }
+
+ @Override
+ public DesugarDescription compute(CfInstruction instruction, ProgramMethod context) {
+ if (instruction.isInvoke()) {
+ return computeInvokeDescription(instruction, context);
+ } else if (instruction.isStaticFieldGet()) {
+ return computeStaticFieldGetDescription(instruction, context);
+ } else {
+ return DesugarDescription.nothing();
+ }
+ }
+
+ private DesugarDescription computeInvokeDescription(
+ CfInstruction instruction, ProgramMethod context) {
+ if (appView.dexItemFactory().multiDexTypes.contains(context.getContextType())) {
+ return DesugarDescription.nothing();
+ }
+ CfInvoke cfInvoke = instruction.asInvoke();
+ DexMethod invokedMethod = cfInvoke.getMethod();
+ AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
+ MethodResolutionResult resolutionResult =
+ appInfo.resolveMethodLegacy(invokedMethod, cfInvoke.isInterface());
+ if (!resolutionResult.isSingleResolution()) {
+ return DesugarDescription.nothing();
+ }
+ assert resolutionResult.getSingleTarget() != null;
+ DexMethod singleTarget = resolutionResult.getSingleTarget().getReference();
+ if (cfInvoke.isInvokeStatic()) {
+ DexMethod retarget = staticRetarget.get(singleTarget);
+ return ensureInvokeRetargetingResult(retarget);
+ }
+ DesugarDescription retarget = computeNonStaticRetarget(singleTarget, false);
+ if (!retarget.needsDesugaring()) {
+ return DesugarDescription.nothing();
+ }
+ if (cfInvoke.isInvokeSuper(context.getHolderType())) {
+ DexClassAndMethod superTarget =
+ appInfo.lookupSuperTarget(invokedMethod, context, appView, appInfo);
+ if (superTarget != null) {
+ assert !superTarget.getDefinition().isStatic();
+ return computeNonStaticRetarget(superTarget.getReference(), true);
+ }
+ }
+ return retarget;
+ }
+
+ private DesugarDescription computeNonStaticRetarget(DexMethod singleTarget, boolean superInvoke) {
+ EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(singleTarget);
+ if (descriptor != null) {
+ return createWithTarget(
+ (eventConsumer, methodProcessingContext) ->
+ superInvoke
+ ? syntheticHelper.ensureForwardingMethod(descriptor, eventConsumer)
+ : syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
+ }
+ if (covariantRetarget.containsKey(singleTarget)) {
+ return createWithTarget(
+ (eventConsumer, methodProcessingContext) ->
+ syntheticHelper.ensureCovariantRetargetMethod(
+ singleTarget,
+ covariantRetarget.get(singleTarget),
+ eventConsumer,
+ methodProcessingContext));
+ }
+ return ensureInvokeRetargetingResult(nonEmulatedVirtualRetarget.get(singleTarget));
+ }
+
+ private DesugarDescription computeStaticFieldGetDescription(
+ CfInstruction instruction, ProgramMethod context) {
+ CfFieldInstruction fieldInstruction = instruction.asFieldInstruction();
+ DexField retargetField = getRetargetField(fieldInstruction.getField(), context);
+ if (retargetField == null) {
+ return DesugarDescription.nothing();
+ }
+ return DesugarDescription.builder()
+ .setDesugarRewrite(
+ (position,
+ freshLocalProvider,
+ localStackAllocator,
+ desugaringInfo,
+ eventConsumer,
+ context1,
+ methodProcessingContext,
+ desugarings,
+ dexItemFactory) ->
+ Collections.singletonList(fieldInstruction.createWithField(retargetField)))
+ .build();
+ }
+
+ DesugarDescription ensureInvokeRetargetingResult(DexMethod retarget) {
+ if (retarget == null) {
+ return DesugarDescription.nothing();
+ }
+ return createWithTarget(
+ (eventConsumer, methodProcessingContext) ->
+ syntheticHelper.ensureRetargetMethod(retarget, eventConsumer));
+ }
+
+ private DesugarDescription createWithTarget(
+ BiFunction<CfInstructionDesugaringEventConsumer, MethodProcessingContext, DexMethod>
+ methodProvider) {
+ return DesugarDescription.builder()
+ .setDesugarRewrite(
+ (position,
+ freshLocalProvider,
+ localStackAllocator,
+ desugaringInfo,
+ eventConsumer,
+ context,
+ methodProcessingContext,
+ desugarings,
+ dexItemFactory) -> {
+ DexMethod newInvokeTarget =
+ methodProvider.apply(eventConsumer, methodProcessingContext);
+ assert appView.definitionFor(newInvokeTarget.getHolderType()) != null;
+ assert !appView.definitionFor(newInvokeTarget.getHolderType()).isInterface();
+ return Collections.singletonList(
+ new CfInvoke(Opcodes.INVOKESTATIC, newInvokeTarget, false));
+ })
+ .build();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
index ac1766d..d340582 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
@@ -1,44 +1,28 @@
// Copyright (c) 2021, 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.desugar.desugaredlibrary.retargeter;
-import com.android.tools.r8.cf.code.CfFieldInstruction;
-import com.android.tools.r8.cf.code.CfInstruction;
-import com.android.tools.r8.cf.code.CfInvoke;
-import com.android.tools.r8.cf.code.CfOpcodeUtils;
-import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
-import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.MethodResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.DesugarDescription;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.LibraryDesugaringOptions;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
-import java.util.Collections;
import java.util.Map;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.IntConsumer;
-import org.objectweb.asm.Opcodes;
-public class DesugaredLibraryRetargeter implements CfInstructionDesugaring {
+public abstract class DesugaredLibraryRetargeter {
- private final AppView<?> appView;
- private final DesugaredLibraryRetargeterSyntheticHelper syntheticHelper;
+ final AppView<?> appView;
+ final DesugaredLibraryRetargeterSyntheticHelper syntheticHelper;
private final Map<DexField, DexField> staticFieldRetarget;
- private final Map<DexMethod, DexMethod> covariantRetarget;
- private final Map<DexMethod, DexMethod> staticRetarget;
- private final Map<DexMethod, DexMethod> nonEmulatedVirtualRetarget;
- private final Map<DexMethod, EmulatedDispatchMethodDescriptor> emulatedVirtualRetarget;
+ final Map<DexMethod, DexMethod> covariantRetarget;
+ final Map<DexMethod, DexMethod> staticRetarget;
+ final Map<DexMethod, DexMethod> nonEmulatedVirtualRetarget;
+ final Map<DexMethod, EmulatedDispatchMethodDescriptor> emulatedVirtualRetarget;
public DesugaredLibraryRetargeter(AppView<?> appView) {
this.appView = appView;
@@ -52,116 +36,29 @@
emulatedVirtualRetarget = specification.getEmulatedVirtualRetarget();
}
- // Used by the ListOfBackportedMethods utility.
- public void visit(Consumer<DexMethod> consumer) {
- staticRetarget.keySet().forEach(consumer);
- nonEmulatedVirtualRetarget.keySet().forEach(consumer);
- emulatedVirtualRetarget.keySet().forEach(consumer);
+ public static CfToCfDesugaredLibraryRetargeter createCfToCf(AppView<?> appView) {
+ LibraryDesugaringOptions libraryDesugaringOptions =
+ appView.options().getLibraryDesugaringOptions();
+ if (libraryDesugaringOptions.isCfToCfLibraryDesugaringEnabled()
+ && libraryDesugaringOptions.getMachineDesugaredLibrarySpecification().hasRetargeting()) {
+ return new CfToCfDesugaredLibraryRetargeter(appView);
+ }
+ return null;
}
- @Override
- public void acceptRelevantAsmOpcodes(IntConsumer consumer) {
- CfOpcodeUtils.acceptCfInvokeOpcodes(consumer);
- consumer.accept(Opcodes.GETSTATIC);
+ public static LirToLirDesugaredLibraryRetargeter createLirToLir(AppView<?> appView) {
+ LibraryDesugaringOptions libraryDesugaringOptions =
+ appView.options().getLibraryDesugaringOptions();
+ if (libraryDesugaringOptions.isLirToLirLibraryDesugaringEnabled()
+ && libraryDesugaringOptions.getMachineDesugaredLibrarySpecification().hasRetargeting()) {
+ return new LirToLirDesugaredLibraryRetargeter(appView);
+ }
+ return null;
}
- @Override
- public DesugarDescription compute(CfInstruction instruction, ProgramMethod context) {
- if (instruction.isStaticFieldGet()) {
- return computeStaticFieldGetDescription(instruction, context);
- }
- if (instruction.isInvoke()) {
- return computeInvokeDescription(instruction, context);
- }
- return DesugarDescription.nothing();
- }
-
- private DesugarDescription computeInvokeDescription(
- CfInstruction instruction, ProgramMethod context) {
- if (appView.dexItemFactory().multiDexTypes.contains(context.getContextType())) {
- return DesugarDescription.nothing();
- }
- CfInvoke cfInvoke = instruction.asInvoke();
- DexMethod invokedMethod = cfInvoke.getMethod();
- AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
- MethodResolutionResult resolutionResult =
- appInfo.resolveMethodLegacy(invokedMethod, cfInvoke.isInterface());
- if (!resolutionResult.isSingleResolution()) {
- return DesugarDescription.nothing();
- }
- assert resolutionResult.getSingleTarget() != null;
- DexMethod singleTarget = resolutionResult.getSingleTarget().getReference();
- if (cfInvoke.isInvokeStatic()) {
- DexMethod retarget = staticRetarget.get(singleTarget);
- return ensureInvokeRetargetingResult(retarget);
- }
- DesugarDescription retarget = computeNonStaticRetarget(singleTarget, false);
- if (!retarget.needsDesugaring()) {
- return DesugarDescription.nothing();
- }
- if (cfInvoke.isInvokeSuper(context.getHolderType())) {
- DexClassAndMethod superTarget =
- appInfo.lookupSuperTarget(invokedMethod, context, appView, appInfo);
- if (superTarget != null) {
- assert !superTarget.getDefinition().isStatic();
- return computeNonStaticRetarget(superTarget.getReference(), true);
- }
- }
- return retarget;
- }
-
- private DesugarDescription createWithTarget(
- BiFunction<CfInstructionDesugaringEventConsumer, MethodProcessingContext, DexMethod>
- methodProvider) {
- return DesugarDescription.builder()
- .setDesugarRewrite(
- (position,
- freshLocalProvider,
- localStackAllocator,
- desugaringInfo,
- eventConsumer,
- context,
- methodProcessingContext,
- desugarings,
- dexItemFactory) -> {
- DexMethod newInvokeTarget =
- methodProvider.apply(eventConsumer, methodProcessingContext);
- assert appView.definitionFor(newInvokeTarget.getHolderType()) != null;
- assert !appView.definitionFor(newInvokeTarget.getHolderType()).isInterface();
- return Collections.singletonList(
- new CfInvoke(Opcodes.INVOKESTATIC, newInvokeTarget, false));
- })
- .build();
- }
-
- private DesugarDescription computeStaticFieldGetDescription(
- CfInstruction instruction, ProgramMethod context) {
- CfFieldInstruction fieldInstruction = instruction.asFieldInstruction();
- DexField fieldRetarget = fieldRetarget(fieldInstruction, context);
- if (fieldRetarget == null) {
- return DesugarDescription.nothing();
- }
- return DesugarDescription.builder()
- .setDesugarRewrite(
- (position,
- freshLocalProvider,
- localStackAllocator,
- desugaringInfo,
- eventConsumer,
- context1,
- methodProcessingContext,
- desugarings,
- dexItemFactory) ->
- Collections.singletonList(fieldInstruction.createWithField(fieldRetarget)))
- .build();
- }
-
- private DexField fieldRetarget(CfFieldInstruction fieldInstruction, ProgramMethod context) {
+ DexField getRetargetField(DexField field, ProgramMethod context) {
DexEncodedField resolvedField =
- appView
- .appInfoForDesugaring()
- .resolveField(fieldInstruction.getField(), context)
- .getResolvedField();
+ appView.appInfoForDesugaring().resolveField(field, context).getResolvedField();
if (resolvedField != null) {
assert resolvedField.isStatic()
|| !staticFieldRetarget.containsKey(resolvedField.getReference());
@@ -169,34 +66,4 @@
}
return null;
}
-
- DesugarDescription ensureInvokeRetargetingResult(DexMethod retarget) {
- if (retarget == null) {
- return DesugarDescription.nothing();
- }
- return createWithTarget(
- (eventConsumer, methodProcessingContext) ->
- syntheticHelper.ensureRetargetMethod(retarget, eventConsumer));
- }
-
- private DesugarDescription computeNonStaticRetarget(DexMethod singleTarget, boolean superInvoke) {
- EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(singleTarget);
- if (descriptor != null) {
- return createWithTarget(
- (eventConsumer, methodProcessingContext) ->
- superInvoke
- ? syntheticHelper.ensureForwardingMethod(descriptor, eventConsumer)
- : syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
- }
- if (covariantRetarget.containsKey(singleTarget)) {
- return createWithTarget(
- (eventConsumer, methodProcessingContext) ->
- syntheticHelper.ensureCovariantRetargetMethod(
- singleTarget,
- covariantRetarget.get(singleTarget),
- eventConsumer,
- methodProcessingContext));
- }
- return ensureInvokeRetargetingResult(nonEmulatedVirtualRetarget.get(singleTarget));
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterHelper.java
new file mode 100644
index 0000000..4f7b732
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterHelper.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2025, 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.desugar.desugaredlibrary.retargeter;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexMethod;
+import java.util.function.Consumer;
+
+// Used by the ListOfBackportedMethods utility.
+public class DesugaredLibraryRetargeterHelper extends DesugaredLibraryRetargeter {
+
+ public DesugaredLibraryRetargeterHelper(AppView<?> appView) {
+ super(appView);
+ }
+
+ public void visit(Consumer<DexMethod> consumer) {
+ staticRetarget.keySet().forEach(consumer);
+ nonEmulatedVirtualRetarget.keySet().forEach(consumer);
+ emulatedVirtualRetarget.keySet().forEach(consumer);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/LirToLirDesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/LirToLirDesugaredLibraryRetargeter.java
new file mode 100644
index 0000000..0d23fbb
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/LirToLirDesugaredLibraryRetargeter.java
@@ -0,0 +1,42 @@
+// Copyright (c) 2025, 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.desugar.desugaredlibrary.retargeter;
+
+import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.lens.FieldLookupResult;
+import com.android.tools.r8.graph.lens.MethodLookupResult;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.R8LibraryDesugaringGraphLens;
+
+public class LirToLirDesugaredLibraryRetargeter extends DesugaredLibraryRetargeter {
+
+ LirToLirDesugaredLibraryRetargeter(AppView<?> appView) {
+ super(appView);
+ }
+
+ public FieldLookupResult lookupField(
+ FieldLookupResult previous, ProgramMethod context, R8LibraryDesugaringGraphLens lens) {
+ DexField retargetField = getRetargetField(previous.getReference(), context);
+ if (retargetField != null) {
+ assert !previous.hasReadCastType();
+ assert !previous.hasWriteCastType();
+ return FieldLookupResult.builder(lens)
+ .setReference(retargetField)
+ .setReboundReference(retargetField)
+ .build();
+ }
+ return previous;
+ }
+
+ public MethodLookupResult lookupMethod(
+ MethodLookupResult previous,
+ ProgramMethod context,
+ MethodProcessingContext methodProcessingContext,
+ R8LibraryDesugaringGraphLens lens) {
+ // TODO(b/391572031): Implement.
+ return previous;
+ }
+}