Make Redundant field elimination a CodeRewriterPass

Bug: b/284304606
Change-Id: I4245feee8d6d69ec89fe6c99dc65c989554327be
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 119e852..5b22d0e 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
@@ -767,11 +767,7 @@
     }
     new SplitBranch(appView).run(code, timing);
     new RedundantConstNumberRemover(appView).run(code, timing);
-    if (RedundantFieldLoadAndStoreElimination.shouldRun(appView, code)) {
-      timing.begin("Remove field loads");
-      new RedundantFieldLoadAndStoreElimination(appView, code).run();
-      timing.end();
-    }
+    new RedundantFieldLoadAndStoreElimination(appView, code).run(code, timing);
     new BinopRewriter(appView).run(code, timing);
 
     timing.begin("Optimize class initializers");
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
index 1ea3e94..5b45fd5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
@@ -8,6 +8,7 @@
 import static com.android.tools.r8.utils.PredicateUtils.not;
 
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClassAndField;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -41,6 +42,8 @@
 import com.android.tools.r8.ir.code.StaticGet;
 import com.android.tools.r8.ir.code.StaticPut;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.passes.CodeRewriterPass;
+import com.android.tools.r8.ir.conversion.passes.result.CodeRewriterResult;
 import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
 import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -63,12 +66,11 @@
  * <p>Simple algorithm that goes through all blocks in one pass in topological order and propagates
  * active field sets across control-flow edges where the target has only one predecessor.
  */
-public class RedundantFieldLoadAndStoreElimination {
+public class RedundantFieldLoadAndStoreElimination extends CodeRewriterPass<AppInfo> {
 
   private static final int MAX_CAPACITY = 10000;
   private static final int MIN_CAPACITY_PER_BLOCK = 50;
 
-  private final AppView<?> appView;
   private final ProgramMethod method;
   private final IRCode code;
   private final int maxCapacityPerBlock;
@@ -87,20 +89,32 @@
   private final Map<BasicBlock, Set<Instruction>> instructionsToRemove = new IdentityHashMap<>();
 
   public RedundantFieldLoadAndStoreElimination(AppView<?> appView, IRCode code) {
-    this.appView = appView;
+    super(appView);
     this.method = code.context();
     this.code = code;
     this.maxCapacityPerBlock = Math.max(MIN_CAPACITY_PER_BLOCK, MAX_CAPACITY / code.blocks.size());
     this.release = !appView.options().debug;
   }
 
-  public static boolean shouldRun(AppView<?> appView, IRCode code) {
+  @Override
+  protected String getTimingId() {
+    return "RedundantFieldLoadAndStoreElimination";
+  }
+
+  @Override
+  protected boolean shouldRewriteCode(IRCode code) {
     return appView.options().enableRedundantFieldLoadElimination
         && (code.metadata().mayHaveArrayGet()
             || code.metadata().mayHaveFieldInstruction()
             || code.metadata().mayHaveInitClass());
   }
 
+  @Override
+  protected CodeRewriterResult rewriteCode(IRCode code) {
+    run();
+    return CodeRewriterResult.NONE;
+  }
+
   private interface FieldValue {
 
     default ExistingValue asExistingValue() {