Convert all methods to LIR when entering LIR phase
Bug: b/225838009
Change-Id: I5cc38417deb3dd184b72b936003a0a86731d8d01
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 2ebb574..94109ba 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -506,7 +506,7 @@
.notifyHorizontalClassMergerFinished(HorizontalClassMerger.Mode.INITIAL);
// TODO(b/225838009): Horizontal merging currently assumes pre-phase CF conversion.
- appView.testing().enterLirSupportedPhase();
+ appView.testing().enterLirSupportedPhase(appView, executorService);
new ProtoNormalizer(appViewWithLiveness).run(executorService, timing);
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index d49b405..41c295f 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -57,6 +57,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
import com.android.tools.r8.graph.classmerging.VerticallyMergedClasses;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger;
import com.android.tools.r8.horizontalclassmerging.HorizontallyMergedClasses;
@@ -65,6 +66,7 @@
import com.android.tools.r8.ir.analysis.proto.ProtoReferences;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.conversion.MethodConversionOptions;
import com.android.tools.r8.ir.desugar.TypeRewriter;
import com.android.tools.r8.ir.desugar.TypeRewriter.MachineTypeRewriter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
@@ -73,6 +75,9 @@
import com.android.tools.r8.ir.optimize.Inliner;
import com.android.tools.r8.ir.optimize.Inliner.Reason;
import com.android.tools.r8.ir.optimize.enums.EnumDataMap;
+import com.android.tools.r8.lightir.IR2LirConverter;
+import com.android.tools.r8.lightir.LirCode;
+import com.android.tools.r8.lightir.LirStrategy;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.MapConsumer;
import com.android.tools.r8.naming.MapVersion;
@@ -119,6 +124,8 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -2104,6 +2111,7 @@
public boolean roundtripThroughLir = false;
private boolean useLir = System.getProperty("com.android.tools.r8.nolir") == null;
+ private boolean convertLir = System.getProperty("com.android.tools.r8.convertlir") == null;
public void enableLir() {
useLir = true;
@@ -2127,9 +2135,42 @@
private LirPhase currentPhase = LirPhase.PRE;
- public void enterLirSupportedPhase() {
+ public void enterLirSupportedPhase(AppView<?> appView, ExecutorService executorService)
+ throws ExecutionException {
assert isPreLirPhase();
currentPhase = LirPhase.SUPPORTED;
+ if (!canUseLir(appView) || !convertLir) {
+ return;
+ }
+ // Convert code objects to LIR.
+ ThreadUtils.processItems(
+ appView.appInfo().classes(),
+ clazz -> {
+ // TODO(b/225838009): Also convert instance initializers to LIR, by adding support for
+ // computing the inlining constraint for LIR and using that in the class mergers, and
+ // class initializers, by updating the concatenation of clinits in horizontal class
+ // merging.
+ clazz.forEachProgramMethodMatching(
+ method ->
+ method.hasCode()
+ && !method.isInitializer()
+ && !appView.isCfByteCodePassThrough(method),
+ method -> {
+ IRCode code =
+ method.buildIR(appView, MethodConversionOptions.forLirPhase(appView));
+ LirCode<Integer> lirCode =
+ IR2LirConverter.translate(
+ code,
+ BytecodeMetadataProvider.empty(),
+ LirStrategy.getDefaultStrategy().getEncodingStrategy(),
+ appView.options());
+ method.setCode(lirCode, appView);
+ });
+ },
+ executorService);
+ // Conversion to LIR via IR will allocate type elements.
+ // They are not needed after construction so remove them again.
+ appView.dexItemFactory().clearTypeElementsCache();
}
public void exitLirSupportedPhase() {
@@ -2137,6 +2178,11 @@
currentPhase = LirPhase.POST;
}
+ public void skipLirPhasesForTestingFinalOutput() {
+ assert currentPhase == LirPhase.PRE;
+ currentPhase = LirPhase.POST;
+ }
+
public boolean isPreLirPhase() {
return currentPhase == LirPhase.PRE;
}
diff --git a/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java b/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
index 7d095bd..d835003 100644
--- a/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
@@ -75,8 +75,7 @@
this.application = appView.appInfo().app();
this.appView = appView;
this.method = method.getMethod();
- appView.testing().enterLirSupportedPhase();
- appView.testing().exitLirSupportedPhase();
+ appView.testing().skipLirPhasesForTestingFinalOutput();
this.code =
method
.getProgramMethod()