Move context in TypeAnalysis from constructor to method

The context is only used when building IR.

Change-Id: I10d19f013781ab17cbbae417ddef5f4d7c3e7078
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
index 5dbb300..f5b3098 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
@@ -36,18 +36,15 @@
   private Mode mode = Mode.UNSET;
 
   private final AppView<?> appView;
-  private final DexEncodedMethod context;
 
   private final Deque<Value> worklist = new ArrayDeque<>();
 
-  public TypeAnalysis(AppView<?> appView, DexEncodedMethod encodedMethod) {
-    this(appView, encodedMethod, false);
+  public TypeAnalysis(AppView<?> appView) {
+    this(appView, false);
   }
 
-  public TypeAnalysis(
-      AppView<?> appView, DexEncodedMethod encodedMethod, boolean mayHaveImpreciseTypes) {
+  public TypeAnalysis(AppView<?> appView, boolean mayHaveImpreciseTypes) {
     this.appView = appView;
-    this.context = encodedMethod;
     this.mayHaveImpreciseTypes = mayHaveImpreciseTypes;
   }
 
@@ -57,10 +54,10 @@
     }
   }
 
-  public void widening(DexEncodedMethod encodedMethod, IRCode code) {
+  public void widening(DexEncodedMethod context, DexEncodedMethod encodedMethod, IRCode code) {
     mode = Mode.WIDENING;
     assert worklist.isEmpty();
-    code.topologicallySortedBlocks().forEach(b -> analyzeBasicBlock(encodedMethod, b));
+    code.topologicallySortedBlocks().forEach(b -> analyzeBasicBlock(context, encodedMethod, b));
     analyze();
   }
 
@@ -89,7 +86,8 @@
     }
   }
 
-  public void analyzeBasicBlock(DexEncodedMethod encodedMethod, BasicBlock block) {
+  public void analyzeBasicBlock(
+      DexEncodedMethod context, DexEncodedMethod encodedMethod, BasicBlock block) {
     int argumentsSeen = encodedMethod.accessFlags.isStatic() ? 0 : -1;
     for (Instruction instruction : block.getInstructions()) {
       Value outValue = instruction.outValue();
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
index d4529ea..b33b894 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
@@ -506,7 +506,7 @@
     assert entryBlock.getInstructions().stream().noneMatch(Instruction::isArgument);
 
     // Actual arguments are flown to the inlinee.
-    new TypeAnalysis(appView, inlinee.method).narrowing(argumentUsers);
+    new TypeAnalysis(appView).narrowing(argumentUsers);
 
     // The inline entry is the first block now the argument instructions are gone.
     BasicBlock inlineEntry = inlinee.entryBlock();
@@ -525,7 +525,7 @@
         Return returnInstruction = inlineeIterator.peekNext().asReturn();
         invoke.outValue().replaceUsers(returnInstruction.returnValue());
         // The return type is flown to the original context.
-        new TypeAnalysis(appView, code.method)
+        new TypeAnalysis(appView)
             .narrowing(
                 Iterables.concat(
                     ImmutableList.of(returnInstruction.returnValue()), affectedValues));
@@ -636,7 +636,7 @@
                 null,
                 RegisterReadType.NORMAL);
         phi.addOperands(operands);
-        new TypeAnalysis(appView, code.method).widening(ImmutableSet.of(phi));
+        new TypeAnalysis(appView).widening(ImmutableSet.of(phi));
         value = phi;
       }
       newReturn = new Return(value);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 484f0aa..b287d0a 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -613,7 +613,7 @@
       assert source instanceof DexSourceCode;
       new TypeConstraintResolver(appView, this).resolve(impreciseInstructions, ir, method, context);
     } else {
-      new TypeAnalysis(appView, context).widening(method, ir);
+      new TypeAnalysis(appView).widening(context, method, ir);
     }
 
     assert ir.isConsistentSSA();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index 772c70c..a8596b0 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -407,7 +407,7 @@
       code.removeUnreachableBlocks();
     }
     if (!newSSAValues.isEmpty()) {
-      new TypeAnalysis(appView, method).widening(newSSAValues);
+      new TypeAnalysis(appView).widening(newSSAValues);
     }
     assert code.isConsistentSSA();
     assert code.hasNoVerticallyMergedClasses(appView);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java b/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
index 8020323..6f01dd7 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
@@ -101,7 +101,7 @@
     List<Value> remainingImpreciseValues = resolveRoundOne(code);
     // Round two will resolve any remaining single and wide types. These can depend on the types
     // of array instructions, thus we need to complete the type fixed point prior to resolving.
-    new TypeAnalysis(appView, context, true).widening(method, code);
+    new TypeAnalysis(appView, true).widening(context, method, code);
     // Round two resolves any remaining imprecision and finally selects a final precise type for
     // any unconstrained imprecise type.
     resolveRoundTwo(code, impreciseInstructions, remainingImpreciseValues);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/AssumeDynamicTypeRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/AssumeDynamicTypeRemover.java
index f53b81a..0c1ffad 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/AssumeDynamicTypeRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/AssumeDynamicTypeRemover.java
@@ -103,7 +103,7 @@
 
   public void finish() {
     if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView, code.method).narrowing(affectedValues);
+      new TypeAnalysis(appView).narrowing(affectedValues);
     }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 63acc0a..0ae4af9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -219,7 +219,7 @@
     }
 
     if (!valuesThatRequireWidening.isEmpty()) {
-      new TypeAnalysis(appView, code.method).widening(valuesThatRequireWidening);
+      new TypeAnalysis(appView).widening(valuesThatRequireWidening);
     }
 
     assert Streams.stream(code.instructions()).noneMatch(Instruction::isAssume);
@@ -1814,7 +1814,7 @@
       code.removeAllTrivialPhis();
     }
     if (!needToWidenValues.isEmpty() || !needToNarrowValues.isEmpty()) {
-      TypeAnalysis analysis = new TypeAnalysis(appView, code.method);
+      TypeAnalysis analysis = new TypeAnalysis(appView);
       // If out value of invoke < argument (e.g., losing non-null info), widen users type.
       if (!needToWidenValues.isEmpty()) {
         analysis.widening(needToWidenValues);
@@ -2008,7 +2008,7 @@
     // CheckCast at line 4 unless we update v7 with the most precise information by narrowing the
     // affected values of v5. We therefore have to run the type analysis after each CheckCast
     // removal.
-    TypeAnalysis typeAnalysis = new TypeAnalysis(appView, code.method);
+    TypeAnalysis typeAnalysis = new TypeAnalysis(appView);
     Set<Value> affectedValues = Sets.newIdentityHashSet();
     InstructionIterator it = code.instructionIterator();
     boolean needToRemoveTrivialPhis = false;
@@ -3135,7 +3135,7 @@
     }
     Set<Value> affectedValues = code.removeUnreachableBlocks();
     if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView, code.method).narrowing(affectedValues);
+      new TypeAnalysis(appView).narrowing(affectedValues);
     }
     assert code.isConsistentSSA();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 817e00a..998de0d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -222,7 +222,7 @@
       }
     }
     if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView, code.method).narrowing(affectedValues);
+      new TypeAnalysis(appView).narrowing(affectedValues);
     }
     assert code.isConsistentSSA();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index b9d0990..758a0b7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -486,7 +486,7 @@
       }
     }
     if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView, code.method).narrowing(affectedValues);
+      new TypeAnalysis(appView).narrowing(affectedValues);
     }
     assert code.isConsistentSSA();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
index 098cd04..a47dfe0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
@@ -214,7 +214,7 @@
       }
     }
     if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView, code.method).narrowing(affectedValues);
+      new TypeAnalysis(appView).narrowing(affectedValues);
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 65b20fa..54fdfb9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -497,7 +497,7 @@
         fieldValueHelper.replaceValue(value, newValue);
       }
       assert value.numberOfAllUsers() == 0;
-      new TypeAnalysis(appView, code.method).widening(code.method, code);
+      new TypeAnalysis(appView).widening(code.method, code.method, code);
     }
     removeInstruction(fieldRead);
   }
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
index 4b8f0dfb..03031f8 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
@@ -53,8 +53,8 @@
     DexEncodedMethod foo = codeInspector.clazz(mainClass.getName()).method(signature).getMethod();
     IRCode irCode = fooSubject.buildIR();
     new NonNullTracker(appView).addNonNull(irCode);
-    TypeAnalysis analysis = new TypeAnalysis(appView, foo);
-    analysis.widening(foo, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(foo, foo, irCode);
     inspector.accept(appView, irCode);
     verifyLastInvoke(irCode, npeCaught);
   }
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
index 085b933..38ddb85 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
@@ -142,8 +142,8 @@
                 new MethodSignature("subtractConstants8bitRegisters", "int", ImmutableList.of()));
     DexEncodedMethod subtract = subtractSubject.getMethod();
     IRCode irCode = subtractSubject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, subtract);
-    analysis.widening(subtract, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(subtract, subtract, irCode);
     forEachOutValue(irCode, (v, l) -> {
       // v9 <- 9 (INT_OR_FLOAT), which is never used later, hence imprecise.
       assertEither(l, SINGLE, INT, NULL);
@@ -158,8 +158,8 @@
             .method(new MethodSignature("fibonacci", "int", ImmutableList.of("int")));
     DexEncodedMethod fib = fibSubject.getMethod();
     IRCode irCode = fibSubject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, fib);
-    analysis.widening(fib, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(fib, fib, irCode);
     forEachOutValue(irCode, (v, l) -> assertEither(l, INT, NULL));
   }
 
@@ -169,8 +169,8 @@
         inspector.clazz("Test").method(new MethodSignature("test1", "int[]", ImmutableList.of()));
     DexEncodedMethod test1 = test1Subject.getMethod();
     IRCode irCode = test1Subject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, test1);
-    analysis.widening(test1, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(test1, test1, irCode);
     Value array = null;
     InstructionIterator iterator = irCode.instructionIterator();
     while (iterator.hasNext()) {
@@ -199,8 +199,8 @@
         inspector.clazz("Test").method(new MethodSignature("test4", "int[]", ImmutableList.of()));
     DexEncodedMethod test4 = test4Subject.getMethod();
     IRCode irCode = test4Subject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, test4);
-    analysis.widening(test4, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(test4, test4, irCode);
     Value array = null;
     InstructionIterator iterator = irCode.instructionIterator();
     while (iterator.hasNext()) {
@@ -229,8 +229,8 @@
         inspector.clazz("Test").method(new MethodSignature("loop2", "void", ImmutableList.of()));
     DexEncodedMethod loop2 = loop2Subject.getMethod();
     IRCode irCode = loop2Subject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, loop2);
-    analysis.widening(loop2, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(loop2, loop2, irCode);
     forEachOutValue(irCode, (v, l) -> {
       if (l.isClassType()) {
         ClassTypeLatticeElement lattice = l.asClassTypeLatticeElement();
@@ -249,8 +249,8 @@
             .method(new MethodSignature("test2_throw", "int", ImmutableList.of()));
     DexEncodedMethod test2 = test2Subject.getMethod();
     IRCode irCode = test2Subject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, test2);
-    analysis.widening(test2, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(test2, test2, irCode);
     forEachOutValue(irCode, (v, l) -> {
       if (l.isClassType()) {
         ClassTypeLatticeElement lattice = l.asClassTypeLatticeElement();
@@ -276,8 +276,8 @@
             CheckCast.class, TypeLatticeElement.fromDexType(test, maybeNull(), appView),
             NewInstance.class, TypeLatticeElement.fromDexType(test, definitelyNotNull(), appView));
     IRCode irCode = methodSubject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, method);
-    analysis.widening(method, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(method, method, irCode);
     forEachOutValue(irCode, (v, l) -> {
       verifyTypeEnvironment(expectedLattices, v, l);
       // There are double-to-int, long-to-int, and int-to-long conversions in this example.
@@ -306,8 +306,8 @@
             InstanceOf.class, INT,
             StaticGet.class, TypeLatticeElement.fromDexType(test, maybeNull(), appView));
     IRCode irCode = methodSubject.buildIR();
-    TypeAnalysis analysis = new TypeAnalysis(appView, method);
-    analysis.widening(method, irCode);
+    TypeAnalysis analysis = new TypeAnalysis(appView);
+    analysis.widening(method, method, irCode);
     forEachOutValue(irCode, (v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
   }