Extend companion instance initializer shrinking to cf backend

Fixes: 216265203
Change-Id: I4ada888399b926bf2103a7c2c49632c01a612d54
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 07ebb29..67eedde 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -19,11 +19,14 @@
 import com.android.tools.r8.cf.code.CfReturnVoid;
 import com.android.tools.r8.cf.code.CfTryCatch;
 import com.android.tools.r8.code.Base5Format;
+import com.android.tools.r8.code.CfOrDexInstruction;
 import com.android.tools.r8.errors.InvalidDebugInfoException;
 import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.bytecodemetadata.BytecodeInstructionMetadata;
+import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadata;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.code.NumberGenerator;
@@ -150,6 +153,7 @@
   private final List<LocalVariableInfo> localVariables;
   private StackMapStatus stackMapStatus = StackMapStatus.NOT_VERIFIED;
   private final com.android.tools.r8.position.Position diagnosticPosition;
+  private final BytecodeMetadata<CfInstruction> metadata;
 
   public CfCode(
       DexType originalHolder, int maxStack, int maxLocals, List<CfInstruction> instructions) {
@@ -187,6 +191,26 @@
       List<CfTryCatch> tryCatchRanges,
       List<LocalVariableInfo> localVariables,
       com.android.tools.r8.position.Position diagnosticPosition) {
+    this(
+        originalHolder,
+        maxStack,
+        maxLocals,
+        instructions,
+        tryCatchRanges,
+        localVariables,
+        diagnosticPosition,
+        BytecodeMetadata.empty());
+  }
+
+  public CfCode(
+      DexType originalHolder,
+      int maxStack,
+      int maxLocals,
+      List<CfInstruction> instructions,
+      List<CfTryCatch> tryCatchRanges,
+      List<LocalVariableInfo> localVariables,
+      com.android.tools.r8.position.Position diagnosticPosition,
+      BytecodeMetadata<CfInstruction> metadata) {
     this.originalHolder = originalHolder;
     this.maxStack = maxStack;
     this.maxLocals = maxLocals;
@@ -194,6 +218,7 @@
     this.tryCatchRanges = tryCatchRanges;
     this.localVariables = localVariables;
     this.diagnosticPosition = diagnosticPosition;
+    this.metadata = metadata;
   }
 
   @Override
@@ -207,6 +232,15 @@
   }
 
   @Override
+  public BytecodeInstructionMetadata getMetadata(CfOrDexInstruction instruction) {
+    return getMetadata(instruction.asCfInstruction());
+  }
+
+  public BytecodeInstructionMetadata getMetadata(CfInstruction instruction) {
+    return metadata.getMetadata(instruction);
+  }
+
+  @Override
   public StructuralMapping<CfCode> getStructuralMapping() {
     throw new Unreachable();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index 347ca58..0bc0830 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -200,7 +200,7 @@
 
   @Override
   public void buildCf(CfBuilder builder) {
-    builder.add(new CfInstanceFieldRead(getField(), builder.resolveField(getField())));
+    builder.add(new CfInstanceFieldRead(getField(), builder.resolveField(getField())), this);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
index c7e076c..c4413d0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
@@ -214,7 +214,7 @@
 
   @Override
   public void buildCf(CfBuilder builder) {
-    builder.add(new CfStaticFieldRead(getField(), builder.resolveField(getField())));
+    builder.add(new CfStaticFieldRead(getField(), builder.resolveField(getField())), this);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index 34142c2..da6c3bf 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -29,6 +29,8 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadata;
+import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.Argument;
 import com.android.tools.r8.ir.code.BasicBlock;
@@ -102,6 +104,9 @@
   private List<InvokeDirect> thisInitializers;
   private Map<NewInstance, CfLabel> newInstanceLabels;
 
+  // Extra information that should be attached to the bytecode instructions.
+  private final BytecodeMetadata.Builder<CfInstruction> bytecodeMetadataBuilder;
+
   // Internal structure maintaining the stack height.
   private static class StackHeightTracker {
     int maxHeight = 0;
@@ -128,10 +133,15 @@
     }
   }
 
-  public CfBuilder(AppView<?> appView, DexEncodedMethod method, IRCode code) {
+  public CfBuilder(
+      AppView<?> appView,
+      DexEncodedMethod method,
+      IRCode code,
+      BytecodeMetadataProvider bytecodeMetadataProvider) {
     this.appView = appView;
     this.method = method;
     this.code = code;
+    this.bytecodeMetadataBuilder = BytecodeMetadata.builder(bytecodeMetadataProvider);
   }
 
   public CfCode build(DeadCodeRemover deadCodeRemover, MethodConversionOptions conversionOptions) {
@@ -383,7 +393,8 @@
         instructions,
         tryCatchRanges,
         localVariablesTable,
-        diagnosticPosition);
+        diagnosticPosition,
+        bytecodeMetadataBuilder.build());
   }
 
   private static boolean isNopInstruction(Instruction instruction, BasicBlock nextBlock) {
@@ -688,6 +699,11 @@
     instructions.add(instruction);
   }
 
+  public void add(CfInstruction instruction, Instruction origin) {
+    bytecodeMetadataBuilder.setMetadata(origin, instruction);
+    add(instruction);
+  }
+
   public void addArgument(Argument argument) {
     // Nothing so far.
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index c19a35b..07fb168 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1594,7 +1594,7 @@
       Timing timing) {
     code.traceBlocks();
     if (options.isGeneratingClassFiles()) {
-      finalizeToCf(code, feedback, conversionOptions);
+      finalizeToCf(code, feedback, conversionOptions, bytecodeMetadataProvider);
     } else {
       assert options.isGeneratingDex();
       finalizeToDex(code, feedback, conversionOptions, bytecodeMetadataProvider, timing);
@@ -1602,10 +1602,13 @@
   }
 
   private void finalizeToCf(
-      IRCode code, OptimizationFeedback feedback, MethodConversionOptions conversionOptions) {
+      IRCode code,
+      OptimizationFeedback feedback,
+      MethodConversionOptions conversionOptions,
+      BytecodeMetadataProvider bytecodeMetadataProvider) {
     DexEncodedMethod method = code.method();
     assert !method.getCode().isDexCode();
-    CfBuilder builder = new CfBuilder(appView, method, code);
+    CfBuilder builder = new CfBuilder(appView, method, code, bytecodeMetadataProvider);
     CfCode result = builder.build(deadCodeRemover, conversionOptions);
     method.setCode(result, appView);
     markProcessed(code, feedback);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/FieldReadForWriteTest.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/FieldReadForWriteTest.java
index 0c4e336..c0d3be4 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/FieldReadForWriteTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/FieldReadForWriteTest.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.ir.optimize.membervaluepropagation;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.NoHorizontalClassMerging;
@@ -13,7 +12,6 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ir.optimize.membervaluepropagation.FieldReadForWriteTest.R.anim;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.HorizontallyMergedClassesInspector;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -42,16 +40,7 @@
         .enableNoHorizontalClassMergingAnnotations()
         .setMinApi(parameters.getApiLevel())
         .compile()
-        .inspect(
-            inspector -> {
-              ClassSubject animClassSubject = inspector.clazz(anim.class);
-              if (parameters.isCfRuntime()) {
-                assertThat(animClassSubject, isPresent());
-                assertThat(animClassSubject.uniqueFieldWithName("abc_fade_in"), isPresent());
-              } else {
-                assertThat(animClassSubject, isAbsent());
-              }
-            });
+        .inspect(inspector -> assertThat(inspector.clazz(anim.class), isAbsent()));
   }
 
   static class Main {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
index 7e12a9f..ad4f8a2 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
@@ -5,6 +5,7 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_5_0;
 import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionProperty;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
@@ -248,11 +249,14 @@
     KmPropertySubject familyName = kmClass.kmPropertyWithUniqueName("familyName");
     assertThat(familyName, not(isPresent()));
 
+    FieldSubject ageField = person.uniqueFieldWithName("age");
+    assertThat(ageField, isAbsent());
+
     KmPropertySubject age = kmClass.kmPropertyWithUniqueName("age");
     assertThat(age, isPresent());
     assertThat(age, not(isExtensionProperty()));
-    assertEquals(age.fieldSignature().asString(), "a:I");
-    assertEquals(age.getterSignature().asString(), "getAge()I");
-    assertEquals(age.setterSignature().asString(), "setAge(I)V");
+    assertEquals("age:I", age.fieldSignature().asString());
+    assertEquals("getAge()I", age.getterSignature().asString());
+    assertEquals("setAge(I)V", age.setterSignature().asString());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/optimize/argumentpropagation/CompanionConstructorShakingTest.java b/src/test/java/com/android/tools/r8/optimize/argumentpropagation/CompanionConstructorShakingTest.java
index 828a4b5..a728f8c 100644
--- a/src/test/java/com/android/tools/r8/optimize/argumentpropagation/CompanionConstructorShakingTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/argumentpropagation/CompanionConstructorShakingTest.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.optimize.argumentpropagation;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isStatic;
-import static com.android.tools.r8.utils.codeinspector.Matchers.onlyIf;
 import static junit.framework.TestCase.assertEquals;
 import static org.hamcrest.MatcherAssert.assertThat;
 
@@ -16,7 +16,6 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import org.junit.Test;
@@ -48,19 +47,16 @@
         .compile()
         .inspect(
             inspector -> {
-              boolean isCf = parameters.isCfRuntime();
-
               ClassSubject hostClassSubject = inspector.clazz(Host.class);
               assertThat(hostClassSubject, isPresent());
-              assertEquals(1 + BooleanUtils.intValue(isCf), hostClassSubject.allMethods().size());
-              assertThat(hostClassSubject.clinit(), onlyIf(isCf, isPresent()));
+              assertEquals(1, hostClassSubject.allMethods().size());
+              assertThat(hostClassSubject.clinit(), isAbsent());
               assertThat(hostClassSubject.uniqueMethodWithName("keepHost"), isPresent());
 
               ClassSubject companionClassSubject = inspector.clazz(Host.Companion.class);
               assertThat(companionClassSubject, isPresent());
-              assertEquals(
-                  1 + BooleanUtils.intValue(isCf), companionClassSubject.allMethods().size());
-              assertThat(companionClassSubject.init(), onlyIf(isCf, isPresent()));
+              assertEquals(1, companionClassSubject.allMethods().size());
+              assertThat(companionClassSubject.init(), isAbsent());
 
               MethodSubject greetMethodSubject =
                   companionClassSubject.uniqueMethodWithName("greet");