Revert "Add UninitializedThisLocalRead to instance initializer exits"

This reverts commit 22d90164fc238c5340917961b94af9866e265f62.

Reason for revert: Breaking the bots

Change-Id: I226327b78b1265a55b9d9f902074096c6876825c
diff --git a/src/main/java/com/android/tools/r8/ir/code/Opcodes.java b/src/main/java/com/android/tools/r8/ir/code/Opcodes.java
index 51b19d8e..a3dc92b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Opcodes.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Opcodes.java
@@ -73,5 +73,4 @@
   int THROW = 64;
   int USHR = 65;
   int XOR = 66;
-  int UNINITIALIZED_THIS_LOCAL_READ = 67;
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java b/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java
deleted file mode 100644
index e3c3d3d..0000000
--- a/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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.code;
-
-import com.android.tools.r8.cf.LoadStoreHelper;
-import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.conversion.CfBuilder;
-import com.android.tools.r8.ir.conversion.DexBuilder;
-import com.android.tools.r8.ir.optimize.DeadCodeRemover.DeadInstructionResult;
-import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
-import com.android.tools.r8.ir.optimize.InliningConstraints;
-
-/**
- * To preserve stack-map table information regarding uninitializedThis flags the
- * UninitializedThisLocalRead is added to every instance-initializer's exits to fake a "read" of
- * this. For more information, see b/183285081
- */
-public class UninitializedThisLocalRead extends Instruction {
-
-  private static final String ERROR_MESSAGE =
-      "Unexpected attempt to emit/use UninitializedThisLocalRead.";
-
-  public UninitializedThisLocalRead(Value inValue) {
-    super(null, inValue);
-  }
-
-  @Override
-  public int opcode() {
-    return Opcodes.UNINITIALIZED_THIS_LOCAL_READ;
-  }
-
-  @Override
-  public <T> T accept(InstructionVisitor<T> visitor) {
-    return visitor.visit(this);
-  }
-
-  @Override
-  public boolean isUninitializedThisLocalRead() {
-    return true;
-  }
-
-  @Override
-  public UninitializedThisLocalRead asUninitializedThisLocalRead() {
-    return this;
-  }
-
-  @Override
-  public void buildDex(DexBuilder builder) {
-    throw new Unreachable(ERROR_MESSAGE);
-  }
-
-  @Override
-  public void buildCf(CfBuilder builder) {
-    throw new Unreachable(ERROR_MESSAGE);
-  }
-
-  @Override
-  public boolean identicalNonValueNonPositionParts(Instruction other) {
-    return other.isUninitializedThisLocalRead();
-  }
-
-  @Override
-  public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
-    return false;
-  }
-
-  @Override
-  public int maxInValueRegister() {
-    return Constants.U16BIT_MAX;
-  }
-
-  @Override
-  public int maxOutValueRegister() {
-    return Constants.U16BIT_MAX;
-  }
-
-  @Override
-  public ConstraintWithTarget inliningConstraint(
-      InliningConstraints inliningConstraints, ProgramMethod context) {
-    throw new Unreachable(ERROR_MESSAGE);
-  }
-
-  @Override
-  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
-    // Non-materializing so no stack values are needed.
-  }
-
-  @Override
-  public DeadInstructionResult canBeDeadCode(AppView<?> appView, IRCode code) {
-    throw new Unreachable(ERROR_MESSAGE);
-  }
-
-  @Override
-  public boolean hasInvariantOutType() {
-    return true;
-  }
-}
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 7d332f0..682ca02 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
@@ -45,7 +45,6 @@
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.StackValue;
 import com.android.tools.r8.ir.code.StackValues;
-import com.android.tools.r8.ir.code.UninitializedThisLocalRead;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.Xor;
 import com.android.tools.r8.ir.optimize.CodeRewriter;
@@ -53,8 +52,6 @@
 import com.android.tools.r8.ir.optimize.PeepholeOptimizer;
 import com.android.tools.r8.ir.optimize.PhiOptimizations;
 import com.android.tools.r8.ir.optimize.peepholes.BasicBlockMuncher;
-import com.android.tools.r8.utils.WorkList;
-import com.google.common.collect.Sets;
 import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
 import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
 import it.unimi.dsi.fastutil.ints.Int2ReferenceMap.Entry;
@@ -62,11 +59,9 @@
 import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
@@ -153,19 +148,8 @@
       }
     }
     assert code.isConsistentSSA();
-    // Insert reads for uninitialized read blocks to ensure correct stack maps.
-    Set<UninitializedThisLocalRead> uninitializedThisLocalReads =
-        insertUninitializedThisLocalReads();
     registerAllocator = new CfRegisterAllocator(appView, code, typeVerificationHelper);
     registerAllocator.allocateRegisters();
-    // Remove any uninitializedThisLocalRead now that the register allocation will preserve this
-    // for instance initializers.
-    if (!uninitializedThisLocalReads.isEmpty()) {
-      for (UninitializedThisLocalRead uninitializedThisLocalRead : uninitializedThisLocalReads) {
-        uninitializedThisLocalRead.getBlock().removeInstruction(uninitializedThisLocalRead);
-      }
-    }
-
     loadStoreHelper.insertPhiMoves(registerAllocator);
 
     for (int i = 0; i < PEEPHOLE_OPTIMIZATION_PASSES; i++) {
@@ -184,27 +168,6 @@
     return code;
   }
 
-  private Set<UninitializedThisLocalRead> insertUninitializedThisLocalReads() {
-    if (!method.isInstanceInitializer()) {
-      return Collections.emptySet();
-    }
-    // Find all non-normal exit blocks.
-    Set<UninitializedThisLocalRead> uninitializedThisLocalReads = Sets.newIdentityHashSet();
-    for (BasicBlock exitBlock : code.blocks) {
-      if (exitBlock.exit().isThrow() && !exitBlock.hasCatchHandlers()) {
-        LinkedList<Instruction> instructions = exitBlock.getInstructions();
-        Instruction throwing = instructions.removeLast();
-        assert throwing.isThrow();
-        UninitializedThisLocalRead read = new UninitializedThisLocalRead(code.getThis());
-        uninitializedThisLocalReads.add(read);
-        read.setBlock(exitBlock);
-        instructions.addLast(read);
-        instructions.addLast(throwing);
-      }
-    }
-    return uninitializedThisLocalReads;
-  }
-
   private static boolean verifyInvokeInterface(CfCode code, AppView<?> appView) {
     if (appView.options().testing.allowInvokeErrors) {
       return true;
@@ -627,32 +590,31 @@
       throw new Unreachable("Unexpected type info: " + typeInfo);
     }
     BasicBlock definitionBlock = definition.getBlock();
-    assert definitionBlock != liveBlock;
-    Set<BasicBlock> initializerBlocks = new HashSet<>();
+    Set<BasicBlock> visited = new HashSet<>();
+    Deque<BasicBlock> toVisit = new ArrayDeque<>();
     List<InvokeDirect> valueInitializers =
         definition.isArgument() ? thisInitializers : initializers.get(definition.asNewInstance());
     for (InvokeDirect initializer : valueInitializers) {
       BasicBlock initializerBlock = initializer.getBlock();
       if (initializerBlock == liveBlock) {
-        // We assume that we are not initializing an object twice.
         return res;
       }
-      initializerBlocks.add(initializerBlock);
-    }
-    // If the live-block has a predecessor that is an initializer-block the value is initialized,
-    // otherwise it is not.
-    WorkList<BasicBlock> findInitWorkList =
-        WorkList.newEqualityWorkList(liveBlock.getPredecessors());
-    while (findInitWorkList.hasNext()) {
-      BasicBlock predecessor = findInitWorkList.next();
-      if (initializerBlocks.contains(predecessor)) {
-        return null;
-      }
-      if (predecessor != definitionBlock) {
-        findInitWorkList.addIfNotSeen(predecessor.getPredecessors());
+      if (initializerBlock != definitionBlock && visited.add(initializerBlock)) {
+        toVisit.addLast(initializerBlock);
       }
     }
-    return res;
+    while (!toVisit.isEmpty()) {
+      BasicBlock block = toVisit.removeLast();
+      for (BasicBlock predecessor : block.getPredecessors()) {
+        if (predecessor == liveBlock) {
+          return res;
+        }
+        if (predecessor != definitionBlock && visited.add(predecessor)) {
+          toVisit.addLast(predecessor);
+        }
+      }
+    }
+    return null;
   }
 
   private void emitLabel(CfLabel label) {
diff --git a/src/test/java/com/android/tools/r8/cf/StackMapFlagThisUninitTest.java b/src/test/java/com/android/tools/r8/cf/StackMapFlagThisUninitTest.java
index 977d7c6..b3f7fe4 100644
--- a/src/test/java/com/android/tools/r8/cf/StackMapFlagThisUninitTest.java
+++ b/src/test/java/com/android/tools/r8/cf/StackMapFlagThisUninitTest.java
@@ -51,7 +51,11 @@
         .addProgramClassFileData(ADump.dump())
         .addKeepAllClassesRule()
         .run(parameters.getRuntime(), Main.class)
-        .assertSuccessWithOutputLines("foo");
+        // TODO(b/166738818): We should generate the correct stack map entry.
+        .assertFailureWithErrorThatMatches(
+            containsString(
+                "Exception in thread \"main\" java.lang.VerifyError: Inconsistent stackmap frames"
+                    + " at branch target 22"));
   }
 
   public static class Main {
diff --git a/src/test/java/com/android/tools/r8/cf/StackMapForThrowingInitializerTest.java b/src/test/java/com/android/tools/r8/cf/StackMapForThrowingInitializerTest.java
index e7a8f4f..bea206e 100644
--- a/src/test/java/com/android/tools/r8/cf/StackMapForThrowingInitializerTest.java
+++ b/src/test/java/com/android/tools/r8/cf/StackMapForThrowingInitializerTest.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.cf;
 
+import static org.hamcrest.CoreMatchers.containsString;
+
 import com.android.tools.r8.NeverClassInline;
 import com.android.tools.r8.NeverInline;
 import com.android.tools.r8.TestBase;
@@ -63,7 +65,9 @@
         .enableNeverClassInliningAnnotations()
         .setMinApi(parameters.getApiLevel())
         .run(parameters.getRuntime(), Main.class, EXPECTED)
-        .assertSuccessWithOutputLines(EXPECTED);
+        // TODO(b/183285081): Should not have verification errors.
+        .assertFailureWithErrorThatMatches(
+            containsString("java.lang.VerifyError: Inconsistent stackmap frames at branch target"));
   }
 
   @NeverClassInline