Move code synthesized in lir phase to lir

Change-Id: I228ede41bf5efe80dfdea3fc4566aef865868bad
diff --git a/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java b/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java
index 665a472..f43f02e 100644
--- a/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java
@@ -19,17 +19,24 @@
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.graph.lens.MethodLookupResult;
 import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
+import com.android.tools.r8.ir.analysis.type.Nullability;
+import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.IRMetadata;
 import com.android.tools.r8.ir.code.InvokeDirect;
 import com.android.tools.r8.ir.code.NumberGenerator;
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.Position.SyntheticPosition;
+import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.ValueType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
 import com.android.tools.r8.ir.conversion.MethodConversionOptions;
 import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
 import com.android.tools.r8.ir.conversion.SyntheticStraightLineSourceCode;
+import com.android.tools.r8.lightir.LirCode;
+import com.android.tools.r8.lightir.LirEncodingStrategy;
+import com.android.tools.r8.lightir.LirStrategy;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.IteratorUtils;
@@ -85,7 +92,12 @@
       AppView<?> appView, ProgramMethod method, DexType superType) {
     DexEncodedMethod definition = method.getDefinition();
     assert definition.getCode().isDefaultInstanceInitializerCode();
-    method.setCode(get().toCfCode(method, appView.dexItemFactory(), superType), appView);
+    if (appView.testing().isSupportedLirPhase()) {
+      method.setCode(get().toLirCode(appView, method), appView);
+    } else {
+      assert appView.testing().isPreLirPhase();
+      method.setCode(get().toCfCode(method, appView.dexItemFactory(), superType), appView);
+    }
   }
 
   @Override
@@ -370,6 +382,27 @@
     return new CfCode(method.getHolderType(), getMaxStack(), getMaxLocals(method), instructions);
   }
 
+  public LirCode<?> toLirCode(AppView<?> appView, ProgramMethod method) {
+    TypeElement receiverType =
+        method.getHolder().getType().toTypeElement(appView, Nullability.definitelyNotNull());
+    Value receiver = new Value(0, receiverType, null);
+    DexMethod invokedMethod =
+        appView.dexItemFactory().createInstanceInitializer(method.getHolder().getSuperType());
+    LirEncodingStrategy<Value, Integer> strategy =
+        LirStrategy.getDefaultStrategy().getEncodingStrategy();
+    strategy.defineValue(receiver, 0);
+    return LirCode.builder(
+            method.getReference(),
+            method.getDefinition().isD8R8Synthesized(),
+            strategy,
+            appView.options())
+        .setMetadata(IRMetadata.unknown())
+        .addArgument(0, false)
+        .addInvokeDirect(invokedMethod, ImmutableList.of(receiver), false)
+        .addReturnVoid()
+        .build();
+  }
+
   @Override
   public void writeCf(
       ProgramMethod method,
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 7465b0a..10d4010 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -10,6 +10,7 @@
 import static com.android.tools.r8.graph.DexEncodedMethod.CompilationState.PROCESSED_INLINING_CANDIDATE_SUBCLASS;
 import static com.android.tools.r8.graph.DexEncodedMethod.CompilationState.PROCESSED_NOT_INLINING_CANDIDATE;
 import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
+import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
 import static com.android.tools.r8.kotlin.KotlinMetadataUtils.getNoKotlinInfo;
 import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
 import static java.util.Objects.requireNonNull;
@@ -30,18 +31,15 @@
 import com.android.tools.r8.cf.code.CfStore;
 import com.android.tools.r8.cf.code.CfThrow;
 import com.android.tools.r8.dex.MixedSectionCollection;
-import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexInstruction;
-import com.android.tools.r8.dex.code.DexInvokeDirect;
-import com.android.tools.r8.dex.code.DexInvokeStatic;
-import com.android.tools.r8.dex.code.DexNewInstance;
-import com.android.tools.r8.dex.code.DexThrow;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexAnnotation.AnnotatedKind;
 import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.graph.proto.ArgumentInfoCollection;
+import com.android.tools.r8.ir.analysis.type.TypeElement;
+import com.android.tools.r8.ir.code.IRMetadata;
 import com.android.tools.r8.ir.code.NumericType;
+import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.ValueType;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.NestUtils;
@@ -52,6 +50,10 @@
 import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
 import com.android.tools.r8.ir.synthetic.ForwardMethodBuilder;
 import com.android.tools.r8.kotlin.KotlinMethodLevelInfo;
+import com.android.tools.r8.lightir.LirBuilder;
+import com.android.tools.r8.lightir.LirCode;
+import com.android.tools.r8.lightir.LirEncodingStrategy;
+import com.android.tools.r8.lightir.LirStrategy;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import com.android.tools.r8.naming.MemberNaming.Signature;
 import com.android.tools.r8.naming.NamingLens;
@@ -911,28 +913,6 @@
     return getReference().toSourceString();
   }
 
-  /** Generates a {@link DexCode} object for the given instructions. */
-  private DexCode generateCodeFromTemplate(
-      int numberOfRegisters, int outRegisters, DexInstruction... instructions) {
-    int offset = 0;
-    for (DexInstruction instruction : instructions) {
-      instruction.setOffset(offset);
-      offset += instruction.getSize();
-    }
-    int requiredArgRegisters = accessFlags.isStatic() ? 0 : 1;
-    for (DexType type : getReference().proto.parameters.values) {
-      requiredArgRegisters += ValueType.fromDexType(type).requiredRegisters();
-    }
-    return new DexCode(
-        Math.max(numberOfRegisters, requiredArgRegisters),
-        requiredArgRegisters,
-        outRegisters,
-        instructions,
-        new DexCode.Try[0],
-        new DexCode.TryHandler[0],
-        null);
-  }
-
   public CfCode buildInstanceOfCfCode(DexType type, boolean negate) {
     CfInstruction[] instructions = new CfInstruction[3 + BooleanUtils.intValue(negate) * 2];
     int i = 0;
@@ -950,13 +930,15 @@
         Arrays.asList(instructions));
   }
 
-  public DexEncodedMethod toMethodThatLogsError(AppView<?> appView) {
+  public DexEncodedMethod toMethodThatLogsError(
+      AppView<? extends AppInfoWithClassHierarchy> appView) {
+    assert appView.testing().isPreLirPhase() || appView.testing().isSupportedLirPhase();
     Builder builder =
         builder(this)
             .setCode(
-                appView.options().isGeneratingClassFiles()
+                appView.testing().isPreLirPhase()
                     ? toCfCodeThatLogsError(appView.dexItemFactory())
-                    : toDexCodeThatLogsError(appView.dexItemFactory()))
+                    : toLirCodeThatLogsError(appView))
             .setIsLibraryMethodOverrideIf(
                 belongsToVirtualPool() && !isLibraryMethodOverride().isUnknown(),
                 isLibraryMethodOverride())
@@ -979,50 +961,86 @@
     }
   }
 
-  public static void setDebugInfoWithExtraParameters(
-      Code code, int arity, int extraParameters, AppView<?> appView) {
-    if (code.isDexCode()) {
-      DexCode dexCode = code.asDexCode();
-      DexDebugInfo newDebugInfo =
-          dexCode.debugInfoWithExtraParameters(appView.dexItemFactory(), extraParameters);
-      assert (newDebugInfo == null) || (arity == newDebugInfo.getParameterCount());
-      dexCode.setDebugInfo(newDebugInfo);
-    } else {
-      assert code.isCfCode();
-      // We don't have anything to do for Cf.
-    }
-  }
-
-  private DexCode toDexCodeThatLogsError(DexItemFactory itemFactory) {
+  private LirCode<?> toLirCodeThatLogsError(AppView<? extends AppInfoWithClassHierarchy> appView) {
     checkIfObsolete();
+    DexItemFactory factory = appView.dexItemFactory();
     Signature signature = MethodSignature.fromDexMethod(getReference());
     DexString message =
-        itemFactory.createString(
+        factory.createString(
             CONFIGURATION_DEBUGGING_PREFIX
                 + getReference().holder.toSourceString()
                 + ": "
                 + signature);
-    DexString tag = itemFactory.createString("[R8]");
-    DexType[] args = {itemFactory.stringType, itemFactory.stringType};
-    DexProto proto = itemFactory.createProto(itemFactory.intType, args);
-    DexMethod logMethod =
-        itemFactory.createMethod(
-            itemFactory.androidUtilLogType, proto, itemFactory.createString("e"));
-    DexType exceptionType = itemFactory.runtimeExceptionType;
+    DexString tag = factory.createString("[R8]");
+    DexType logger = factory.javaUtilLoggingLoggerType;
+    DexMethod getLogger =
+        factory.createMethod(
+            logger,
+            factory.createProto(logger, factory.stringType),
+            factory.createString("getLogger"));
+    DexMethod severe =
+        factory.createMethod(
+            logger,
+            factory.createProto(factory.voidType, factory.stringType),
+            factory.createString("severe"));
+    DexType exceptionType = factory.runtimeExceptionType;
     DexMethod exceptionInitMethod =
-        itemFactory.createMethod(
+        factory.createMethod(
             exceptionType,
-            itemFactory.createProto(itemFactory.voidType, itemFactory.stringType),
-            itemFactory.constructorMethodName);
-    return generateCodeFromTemplate(
-        2,
-        2,
-        new DexConstString(0, tag),
-        new DexConstString(1, message),
-        new DexInvokeStatic(2, logMethod, 0, 1, 0, 0, 0),
-        new DexNewInstance(0, exceptionType),
-        new DexInvokeDirect(2, exceptionInitMethod, 0, 1, 0, 0, 0),
-        new DexThrow(0));
+            factory.createProto(factory.voidType, factory.stringType),
+            factory.constructorMethodName);
+
+    TypeElement stringValueType = TypeElement.stringClassType(appView, definitelyNotNull());
+    TypeElement loggerValueType = logger.toTypeElement(appView);
+    TypeElement exceptionValueType = exceptionType.toTypeElement(appView, definitelyNotNull());
+
+    LirEncodingStrategy<Value, Integer> strategy =
+        LirStrategy.getDefaultStrategy().getEncodingStrategy();
+    LirBuilder<Value, Integer> lirBuilder =
+        LirCode.builder(getReference(), isD8R8Synthesized(), strategy, appView.options())
+            .setMetadata(IRMetadata.unknown());
+    int instructionIndex = 0;
+    for (; instructionIndex < getNumberOfArguments(); instructionIndex++) {
+      DexType argumentType = getArgumentType(instructionIndex);
+      lirBuilder.addArgument(instructionIndex, argumentType.isBooleanType());
+    }
+
+    // Load tag.
+    Value tagValue = new Value(instructionIndex, stringValueType, null);
+    strategy.defineValue(tagValue, tagValue.getNumber());
+    lirBuilder.addConstString(tag);
+    instructionIndex++;
+
+    // Get logger.
+    Value loggerValue = new Value(instructionIndex, loggerValueType, null);
+    strategy.defineValue(loggerValue, loggerValue.getNumber());
+    lirBuilder.addInvokeStatic(getLogger, ImmutableList.of(tagValue), false);
+    instructionIndex++;
+
+    // Load message.
+    Value messageValue = new Value(instructionIndex, stringValueType, null);
+    strategy.defineValue(messageValue, messageValue.getNumber());
+    lirBuilder.addConstString(message);
+    instructionIndex++;
+
+    // Call logger.
+    lirBuilder.addInvokeVirtual(severe, ImmutableList.of(loggerValue, messageValue));
+    instructionIndex++;
+
+    // Instantiate exception.
+    Value exceptionValue = new Value(instructionIndex, exceptionValueType, null);
+    strategy.defineValue(exceptionValue, exceptionValue.getNumber());
+    lirBuilder
+        .addNewInstance(exceptionType)
+        .addInvokeDirect(
+            exceptionInitMethod, ImmutableList.of(exceptionValue, messageValue), false);
+    instructionIndex += 2;
+
+    // Throw exception.
+    lirBuilder.addThrow(exceptionValue);
+    instructionIndex++;
+
+    return lirBuilder.build();
   }
 
   private CfCode toCfCodeThatLogsError(DexItemFactory itemFactory) {