Gather metadata about IR and simplify maintenance
Bug: 122257895
Change-Id: I6e45613f5ae887e93fcd9550490f1760ad8fe18f
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java
index dbd95ae..118ea7a 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java
@@ -120,7 +120,8 @@
IRCode code, Value infoValue, ProtoMessageInfo protoMessageInfo) {
infoValue.definition.replace(
new ConstString(
- code.createValue(stringType), encoder.encodeInfo(protoMessageInfo), throwingInfo));
+ code.createValue(stringType), encoder.encodeInfo(protoMessageInfo), throwingInfo),
+ code.metadata());
}
private void rewriteObjectsArgumentToNewMessageInfo(
@@ -130,7 +131,8 @@
ProtoMessageInfo protoMessageInfo) {
// Position iterator immediately before the call to newMessageInfo().
BasicBlock block = newMessageInfoInvoke.getBlock();
- InstructionListIterator instructionIterator = block.listIterator(newMessageInfoInvoke);
+ InstructionListIterator instructionIterator =
+ block.listIterator(newMessageInfoInvoke).recordChangesToMetadata(code);
Instruction previous = instructionIterator.previous();
instructionIterator.setInsertionPosition(newMessageInfoInvoke.getPosition());
assert previous == newMessageInfoInvoke;
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 698592d..5ebbc17 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
@@ -26,13 +26,15 @@
import java.util.ListIterator;
import java.util.Set;
-public class BasicBlockInstructionIterator implements InstructionIterator, InstructionListIterator {
+public class BasicBlockInstructionIterator implements InstructionListIterator {
protected final BasicBlock block;
protected final ListIterator<Instruction> listIterator;
protected Instruction current;
protected Position position = null;
+ private UpdatableIRMetadata metadata;
+
BasicBlockInstructionIterator(BasicBlock block) {
this.block = block;
this.listIterator = block.getInstructions().listIterator();
@@ -49,6 +51,16 @@
}
@Override
+ public BasicBlockInstructionIterator recordChangesToMetadata(IRMetadata metadata) {
+ if (metadata.isUpdatableIRMetadata()) {
+ this.metadata = metadata.asUpdatableIRMetadata();
+ } else {
+ assert metadata.isUnknownIRMetadata();
+ }
+ return this;
+ }
+
+ @Override
public boolean hasNext() {
return listIterator.hasNext();
}
@@ -101,6 +113,9 @@
instruction.setPosition(position);
}
listIterator.add(instruction);
+ if (metadata != null) {
+ metadata.record(instruction);
+ }
}
/**
@@ -182,6 +197,9 @@
listIterator.remove();
listIterator.add(newInstruction);
current.clearBlock();
+ if (metadata != null) {
+ metadata.record(newInstruction);
+ }
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index e6b352e..a07e11b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -105,12 +105,7 @@
// If this is the case, which holds for javac code, then we want to ensure that it remains so.
private boolean allThrowingInstructionsHavePositions;
- // TODO(b/122257895): Update OptimizationInfo to capture instruction kinds of interest.
- public final boolean mayHaveDebugPositions;
- public boolean mayHaveConstString;
- public boolean mayHaveStringSwitch;
- public final boolean mayHaveMonitorInstruction;
-
+ private final IRMetadata metadata;
private final InternalOptions options;
public final Origin origin;
@@ -120,27 +115,27 @@
DexEncodedMethod method,
LinkedList<BasicBlock> blocks,
ValueNumberGenerator valueNumberGenerator,
- boolean mayHaveDebugPositions,
- boolean mayHaveMonitorInstruction,
- boolean mayHaveConstString,
+ IRMetadata metadata,
Origin origin) {
+ assert metadata != null;
assert options != null;
this.options = options;
this.method = method;
this.blocks = blocks;
this.valueNumberGenerator = valueNumberGenerator;
- this.mayHaveDebugPositions = mayHaveDebugPositions;
- this.mayHaveMonitorInstruction = mayHaveMonitorInstruction;
- this.mayHaveConstString = mayHaveConstString;
+ this.metadata = metadata;
this.origin = origin;
// TODO(zerny): Remove or update this property now that all instructions have positions.
allThrowingInstructionsHavePositions = computeAllThrowingInstructionsHavePositions();
}
+ public IRMetadata metadata() {
+ return metadata;
+ }
+
public void mergeMetadataFromInlinee(IRCode inlinee) {
- assert !inlinee.mayHaveMonitorInstruction;
- this.mayHaveConstString |= inlinee.mayHaveConstString;
- this.mayHaveStringSwitch |= inlinee.mayHaveStringSwitch;
+ assert !inlinee.metadata.mayHaveMonitorInstruction();
+ this.metadata.merge(inlinee.metadata);
}
public BasicBlock entryBlock() {
@@ -719,13 +714,20 @@
private boolean consistentMetadata() {
for (Instruction instruction : instructions()) {
if (instruction.isConstString()) {
- assert mayHaveConstString : "IR metadata should indicate that code has a const-string";
+ assert metadata.mayHaveConstString()
+ : "IR metadata should indicate that code has a const-string";
} else if (instruction.isDebugPosition()) {
- assert mayHaveDebugPositions : "IR metadata should indicate that code has a debug position";
+ assert metadata.mayHaveDebugPosition()
+ : "IR metadata should indicate that code has a debug position";
+ } else if (instruction.isDexItemBasedConstString()) {
+ assert metadata.mayHaveDexItemBasedConstString()
+ : "IR metadata should indicate that code has a dex-item-based-const-string";
} else if (instruction.isMonitor()) {
- assert mayHaveMonitorInstruction : "IR metadata should indicate that code has a monitor";
+ assert metadata.mayHaveMonitorInstruction()
+ : "IR metadata should indicate that code has a monitor instruction";
} else if (instruction.isStringSwitch()) {
- assert mayHaveStringSwitch : "IR metadata should indicate that code has a string-switch";
+ assert metadata.mayHaveStringSwitch()
+ : "IR metadata should indicate that code has a string-switch";
}
}
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCodeInstructionsIterator.java b/src/main/java/com/android/tools/r8/ir/code/IRCodeInstructionsIterator.java
index 03dd1fa..d2bd712 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCodeInstructionsIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCodeInstructionsIterator.java
@@ -12,12 +12,24 @@
private final ListIterator<BasicBlock> blockIterator;
private InstructionListIterator instructionIterator;
+ private IRMetadata metadata;
+
public IRCodeInstructionsIterator(IRCode code) {
blockIterator = code.listIterator();
instructionIterator = blockIterator.next().listIterator();
}
@Override
+ public IRCodeInstructionsIterator recordChangesToMetadata(IRMetadata metadata) {
+ if (metadata.isUpdatableIRMetadata()) {
+ this.metadata = metadata.asUpdatableIRMetadata();
+ } else {
+ assert metadata.isUnknownIRMetadata();
+ }
+ return this;
+ }
+
+ @Override
public boolean hasNext() {
return instructionIterator.hasNext() || blockIterator.hasNext();
}
@@ -67,6 +79,9 @@
@Override
public void add(Instruction instruction) {
instructionIterator.add(instruction);
+ if (metadata != null) {
+ metadata.record(instruction);
+ }
}
@Override
@@ -77,11 +92,17 @@
@Override
public void set(Instruction instruction) {
instructionIterator.set(instruction);
+ if (metadata != null) {
+ metadata.record(instruction);
+ }
}
@Override
public void replaceCurrentInstruction(Instruction newInstruction) {
instructionIterator.replaceCurrentInstruction(newInstruction);
+ if (metadata != null) {
+ metadata.record(newInstruction);
+ }
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRMetadata.java b/src/main/java/com/android/tools/r8/ir/code/IRMetadata.java
new file mode 100644
index 0000000..a79d45d
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/code/IRMetadata.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, 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;
+
+public abstract class IRMetadata {
+
+ public static IRMetadata unknown() {
+ return UnknownIRMetadata.getInstance();
+ }
+
+ public boolean isUpdatableIRMetadata() {
+ return false;
+ }
+
+ public UpdatableIRMetadata asUpdatableIRMetadata() {
+ return null;
+ }
+
+ public boolean isUnknownIRMetadata() {
+ return false;
+ }
+
+ public abstract void record(Instruction instruction);
+
+ public abstract void merge(IRMetadata metadata);
+
+ public abstract boolean mayHaveConstString();
+
+ public abstract boolean mayHaveDebugPosition();
+
+ public abstract boolean mayHaveDexItemBasedConstString();
+
+ public abstract boolean mayHaveMonitorInstruction();
+
+ public abstract boolean mayHaveStringSwitch();
+}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 8e11152..95e8ca6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -272,8 +272,11 @@
getBlock().listIterator(this).removeOrReplaceByDebugLocalRead();
}
- public void replace(Instruction newInstruction) {
- getBlock().listIterator(this).replaceCurrentInstruction(newInstruction);
+ public void replace(Instruction newInstruction, IRMetadata metadata) {
+ getBlock()
+ .listIterator(this)
+ .recordChangesToMetadata(metadata)
+ .replaceCurrentInstruction(newInstruction);
}
/**
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java b/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java
index 72aa3ee..d957147 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java
@@ -4,10 +4,21 @@
package com.android.tools.r8.ir.code;
+import com.android.tools.r8.errors.Unreachable;
import java.util.ListIterator;
public interface InstructionIterator
extends ListIterator<Instruction>, NextUntilIterator<Instruction> {
+
+ default InstructionIterator recordChangesToMetadata(IRCode code) {
+ return recordChangesToMetadata(code.metadata());
+ }
+
+ default InstructionIterator recordChangesToMetadata(IRMetadata metadata) {
+ throw new Unreachable(
+ "Method recordChangesToMetadata(IRMetadata) not implemented for "
+ + getClass().getTypeName());
+ }
/**
* Replace the current instruction (aka the {@link Instruction} returned by the previous call to
* {@link #next} with the passed in <code>newInstruction</code>.
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
index 59a77a1..773bc13 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.code;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
@@ -45,6 +46,18 @@
return next;
}
+ @Override
+ default InstructionListIterator recordChangesToMetadata(IRCode code) {
+ return recordChangesToMetadata(code.metadata());
+ }
+
+ @Override
+ default InstructionListIterator recordChangesToMetadata(IRMetadata metadata) {
+ throw new Unreachable(
+ "Method recordChangesToMetadata(IRMetadata) not implemented for "
+ + getClass().getTypeName());
+ }
+
default void setInsertionPosition(Position position) {
// Intentionally empty.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/UnknownIRMetadata.java b/src/main/java/com/android/tools/r8/ir/code/UnknownIRMetadata.java
new file mode 100644
index 0000000..8730fb5
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/code/UnknownIRMetadata.java
@@ -0,0 +1,56 @@
+// Copyright (c) 2019, 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;
+
+public class UnknownIRMetadata extends IRMetadata {
+
+ private static UnknownIRMetadata INSTANCE = new UnknownIRMetadata();
+
+ private UnknownIRMetadata() {}
+
+ static UnknownIRMetadata getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public boolean isUnknownIRMetadata() {
+ return true;
+ }
+
+ @Override
+ public void record(Instruction instruction) {
+ // Nothing to do.
+ }
+
+ @Override
+ public void merge(IRMetadata metadata) {
+ // Nothing to do.
+ }
+
+ @Override
+ public boolean mayHaveConstString() {
+ return true;
+ }
+
+ @Override
+ public boolean mayHaveDebugPosition() {
+ return true;
+ }
+
+ @Override
+ public boolean mayHaveDexItemBasedConstString() {
+ return true;
+ }
+
+ @Override
+ public boolean mayHaveMonitorInstruction() {
+ return true;
+ }
+
+ @Override
+ public boolean mayHaveStringSwitch() {
+ return true;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/code/UpdatableIRMetadata.java b/src/main/java/com/android/tools/r8/ir/code/UpdatableIRMetadata.java
new file mode 100644
index 0000000..bcceb5b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/code/UpdatableIRMetadata.java
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, 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;
+
+public class UpdatableIRMetadata extends IRMetadata {
+
+ // TODO(b/122257895): change to bit vector based representation.
+ private boolean mayHaveConstString;
+ private boolean mayHaveDebugPosition;
+ private boolean mayHaveDexItemBasedConstString;
+ private boolean mayHaveMonitorInstruction;
+ private boolean mayHaveStringSwitch;
+
+ @Override
+ public boolean isUpdatableIRMetadata() {
+ return true;
+ }
+
+ @Override
+ public UpdatableIRMetadata asUpdatableIRMetadata() {
+ return this;
+ }
+
+ @Override
+ public void record(Instruction instruction) {
+ mayHaveConstString |= instruction.isConstString();
+ mayHaveDebugPosition |= instruction.isDebugPosition();
+ mayHaveDexItemBasedConstString |= instruction.isDexItemBasedConstString();
+ mayHaveMonitorInstruction |= instruction.isMonitor();
+ mayHaveStringSwitch |= instruction.isStringSwitch();
+ }
+
+ @Override
+ public void merge(IRMetadata metadata) {
+ this.mayHaveConstString |= metadata.mayHaveConstString();
+ this.mayHaveDebugPosition |= metadata.mayHaveDebugPosition();
+ this.mayHaveDexItemBasedConstString |= metadata.mayHaveDexItemBasedConstString();
+ this.mayHaveMonitorInstruction |= metadata.mayHaveMonitorInstruction();
+ this.mayHaveStringSwitch |= metadata.mayHaveStringSwitch();
+ }
+
+ @Override
+ public boolean mayHaveConstString() {
+ return mayHaveConstString;
+ }
+
+ @Override
+ public boolean mayHaveDebugPosition() {
+ return mayHaveDebugPosition;
+ }
+
+ @Override
+ public boolean mayHaveDexItemBasedConstString() {
+ return mayHaveDexItemBasedConstString;
+ }
+
+ @Override
+ public boolean mayHaveMonitorInstruction() {
+ return mayHaveMonitorInstruction;
+ }
+
+ @Override
+ public boolean mayHaveStringSwitch() {
+ return mayHaveStringSwitch;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
index 77b3058..ba9a714 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
@@ -334,7 +334,7 @@
// After this pass all remaining debug positions mark places where we must ensure a materializing
// instruction, eg, for two successive lines without intermediate instructions.
public static void removeRedundantDebugPositions(IRCode code) {
- if (!code.mayHaveDebugPositions) {
+ if (!code.metadata().mayHaveDebugPosition()) {
return;
}
// Current position known to have a materializing instruction associated with it.
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 ef6f3eb..ace2187 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
@@ -92,6 +92,7 @@
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Sub;
import com.android.tools.r8.ir.code.Throw;
+import com.android.tools.r8.ir.code.UpdatableIRMetadata;
import com.android.tools.r8.ir.code.Ushr;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.code.ValueNumberGenerator;
@@ -414,10 +415,9 @@
private boolean hasImpreciseValues = false;
// Flag indicating if a const string is ever loaded.
- private boolean hasConstString = false;
// Flag indicating if the code has a monitor instruction.
- private boolean hasMonitorInstruction = false;
+ private final UpdatableIRMetadata metadata = new UpdatableIRMetadata();
public IRBuilder(DexEncodedMethod method, AppView<?> appView, SourceCode source, Origin origin) {
this(method, appView, source, origin, new ValueNumberGenerator());
@@ -553,7 +553,7 @@
assert verifyFilledPredecessors();
// Insert debug positions so all position changes are marked by an explicit instruction.
- boolean hasDebugPositions = insertDebugPositions();
+ insertDebugPositions();
// Insert definitions for all uninitialized local values.
if (uninitializedDebugLocalValues != null) {
@@ -584,15 +584,7 @@
// Package up the IR code.
IRCode ir =
- new IRCode(
- appView.options(),
- method,
- blocks,
- valueNumberGenerator,
- hasDebugPositions,
- hasMonitorInstruction,
- hasConstString,
- origin);
+ new IRCode(appView.options(), method, blocks, valueNumberGenerator, metadata, origin);
// Verify critical edges are split so we have a place to insert phi moves if necessary.
assert ir.verifySplitCriticalEdges();
@@ -636,10 +628,9 @@
impreciseInstructions.add(instruction);
}
- private boolean insertDebugPositions() {
- boolean hasDebugPositions = false;
+ private void insertDebugPositions() {
if (!isDebugMode()) {
- return hasDebugPositions;
+ return;
}
for (BasicBlock block : blocks) {
InstructionListIterator it = block.listIterator();
@@ -650,13 +641,12 @@
if (instruction.isMoveException()) {
assert current == null;
current = position;
- hasDebugPositions = hasDebugPositions || position.isSome();
} else if (instruction.isDebugPosition()) {
if (position.equals(current)) {
it.removeOrReplaceByDebugLocalRead();
} else {
current = position;
- hasDebugPositions = true;
+ metadata.record(instruction);
}
} else if (position.isSome() && !position.synthetic && !position.equals(current)) {
DebugPosition positionChange = new DebugPosition();
@@ -665,11 +655,10 @@
it.add(positionChange);
it.next();
current = position;
- hasDebugPositions = true;
+ metadata.record(positionChange);
}
}
}
- return hasDebugPositions;
}
private boolean verifyFilledPredecessors() {
@@ -833,8 +822,8 @@
*/
public void add(Instruction ir) {
assert !ir.isJumpInstruction();
- hasConstString |= ir.isConstString() || ir.isDexItemBasedConstString();
addInstruction(ir);
+ metadata.record(ir);
}
private RemovedArgumentInfo getRemovedArgumentInfo() {
@@ -1168,7 +1157,6 @@
Value in = readRegister(monitor, ValueTypeConstraint.OBJECT);
Monitor monitorEnter = new Monitor(type, in);
add(monitorEnter);
- hasMonitorInstruction = true;
return monitorEnter;
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java
index e208ec3..f1396b8 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java
@@ -108,12 +108,11 @@
if (rewritingCandidates != null) {
boolean changed = false;
for (BasicBlock block : rewritingCandidates) {
- if (convertRewritingCandidateToStringSwitchInstruction(block, dexItemFactory)) {
+ if (convertRewritingCandidateToStringSwitchInstruction(code, block, dexItemFactory)) {
changed = true;
}
}
if (changed) {
- code.mayHaveStringSwitch = true;
code.removeAllTrivialPhis();
code.removeUnreachableBlocks();
}
@@ -172,10 +171,10 @@
}
private static boolean convertRewritingCandidateToStringSwitchInstruction(
- BasicBlock block, DexItemFactory dexItemFactory) {
+ IRCode code, BasicBlock block, DexItemFactory dexItemFactory) {
StringSwitchBuilderInfo info = StringSwitchBuilderInfo.builder(dexItemFactory).build(block);
if (info != null) {
- info.createAndInsertStringSwitch();
+ info.createAndInsertStringSwitch(code);
return true;
}
return false;
@@ -269,7 +268,7 @@
return new Builder(dexItemFactory);
}
- void createAndInsertStringSwitch() {
+ void createAndInsertStringSwitch(IRCode code) {
// Remove outgoing control flow edges from `insertionBlock`.
for (BasicBlock successor : insertionBlock.getNormalSuccessors()) {
successor.removePredecessor(insertionBlock, null);
@@ -288,9 +287,10 @@
i++;
}
insertionBlock.link(fallthroughBlock);
- insertionBlock
- .exit()
- .replace(new StringSwitch(value, keys, targetBlockIndices, i + numberOfCatchHandlers));
+ JumpInstruction exit = insertionBlock.exit();
+ exit.replace(
+ new StringSwitch(value, keys, targetBlockIndices, i + numberOfCatchHandlers),
+ code.metadata());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java
index 9efba14..4cf5299 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java
@@ -47,7 +47,7 @@
}
void run(DexEncodedMethod method, IRCode code) {
- if (!code.mayHaveStringSwitch) {
+ if (!code.metadata().mayHaveStringSwitch()) {
assert Streams.stream(code.instructions()).noneMatch(Instruction::isStringSwitch);
return;
}
@@ -112,7 +112,7 @@
if (previous == null) {
// Replace the string-switch instruction by a goto instruction.
- block.exit().replace(new Goto(newBlock));
+ block.exit().replace(new Goto(newBlock), code.metadata());
block.link(newBlock);
} else {
// Set the fallthrough block for the previously added if-instruction.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java
index f68f740..785799d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/StringConcatRewriter.java
@@ -117,7 +117,7 @@
ListIterator<BasicBlock> blocks = code.listIterator();
while (blocks.hasNext()) {
BasicBlock block = blocks.next();
- InstructionListIterator instructions = block.listIterator();
+ InstructionListIterator instructions = block.listIterator().recordChangesToMetadata(code);
while (instructions.hasNext()) {
Instruction instruction = instructions.next();
if (!instruction.isInvokeCustom()) {
@@ -447,7 +447,6 @@
value,
factory.createString(str),
ThrowingInfo.defaultForConstString(appView.options())));
- code.mayHaveConstString = true;
return value;
}
}
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 862c82d..4bfb703 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
@@ -1090,7 +1090,7 @@
targets,
switchInsn.getFallthroughBlockIndex());
// Replace the switch itself.
- exit.replace(newSwitch);
+ exit.replace(newSwitch, code.metadata());
// If the original input to the switch is now unused, remove it too. It is not dead
// as it might have side-effects but we ignore these here.
Instruction arrayGet = info.arrayGet;
@@ -3652,7 +3652,7 @@
}
public void rewriteConstantEnumMethodCalls(IRCode code) {
- InstructionIterator iterator = code.instructionIterator();
+ InstructionIterator iterator = code.instructionIterator().recordChangesToMetadata(code);
while (iterator.hasNext()) {
Instruction current = iterator.next();
@@ -3699,7 +3699,6 @@
} else if (isNameInvoke) {
iterator.replaceCurrentInstruction(
new ConstString(outValue, enumField.name, ThrowingInfo.NO_THROW));
- code.mayHaveConstString = true;
} else {
assert isToStringInvoke;
DexClass enumClazz = appView.appInfo().definitionFor(enumField.type);
@@ -3713,7 +3712,6 @@
}
iterator.replaceCurrentInstruction(
new ConstString(outValue, enumField.name, ThrowingInfo.NO_THROW));
- code.mayHaveConstString = true;
}
}
@@ -4103,7 +4101,6 @@
}
// When we fall out of the loop the iterator is in the last eol block.
iterator.add(new InvokeVirtual(printLn, null, ImmutableList.of(out, empty)));
- code.mayHaveConstString = true;
}
public static void ensureDirectStringNewToInit(IRCode code, DexItemFactory dexItemFactory) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
index 0f6bddd..00b4540 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
@@ -120,7 +120,7 @@
// That could lead to unbalanced locking and could lead to situations where OOM exceptions
// could leave a synchronized method without unlocking the monitor.
if ((current.isConstString() || current.isDexItemBasedConstString())
- && code.mayHaveMonitorInstruction) {
+ && code.metadata().mayHaveMonitorInstruction()) {
continue;
}
// Constants with local info must not be canonicalized and must be filtered.
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 f8b0eae..2326b45 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
@@ -233,12 +233,11 @@
}
replacement.setPosition(current.getPosition());
if (current.getBlock().hasCatchHandlers()) {
- iterator.split(code, blocks).listIterator().add(replacement);
+ iterator.split(code, blocks).listIterator().recordChangesToMetadata(code).add(replacement);
} else {
iterator.add(replacement);
}
}
- code.mayHaveConstString |= replacement.isConstString();
return true;
}
@@ -308,7 +307,6 @@
replacement =
createConstStringReplacement(
code, constant, current.outValue().getTypeLattice(), current.getLocalInfo());
- code.mayHaveConstString = true;
}
affectedValues.addAll(current.outValue().affectedValues());
@@ -317,7 +315,7 @@
replacement.setPosition(current.getPosition());
current.moveDebugValues(replacement);
if (current.getBlock().hasCatchHandlers()) {
- iterator.split(code, blocks).listIterator().add(replacement);
+ iterator.split(code, blocks).listIterator().recordChangesToMetadata(code).add(replacement);
} else {
iterator.add(replacement);
}
@@ -370,7 +368,6 @@
if (replacement != null) {
affectedValues.addAll(current.outValue().affectedValues());
iterator.replaceCurrentInstruction(replacement);
- code.mayHaveConstString |= replacement.isConstString();
if (replacement.isDexItemBasedConstString()) {
code.method.getMutableOptimizationInfo().markUseIdentifierNameString();
}
@@ -434,7 +431,6 @@
if (replacement != null) {
affectedValues.add(replacement.outValue());
iterator.replaceCurrentInstruction(replacement);
- code.mayHaveConstString |= replacement.isConstString();
if (replacement.isDexItemBasedConstString()) {
code.method.getMutableOptimizationInfo().markUseIdentifierNameString();
}
@@ -461,7 +457,7 @@
nonNullValue, knownToBeNonNullValue, current, appView);
nonNull.setPosition(appView.options().debug ? current.getPosition() : Position.none());
if (current.getBlock().hasCatchHandlers()) {
- iterator.split(code, blocks).listIterator().add(nonNull);
+ iterator.split(code, blocks).listIterator().recordChangesToMetadata(code).add(nonNull);
} else {
iterator.add(nonNull);
}
@@ -479,7 +475,7 @@
ListIterator<BasicBlock> blocks = code.listIterator();
while (blocks.hasNext()) {
BasicBlock block = blocks.next();
- InstructionListIterator iterator = block.listIterator();
+ InstructionListIterator iterator = block.listIterator().recordChangesToMetadata(code);
while (iterator.hasNext()) {
Instruction current = iterator.next();
if (current.isInvokeMethod()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index cf4d14b..60c34a1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -488,8 +488,9 @@
}
}
List<Value> args = invoke.inValues();
- invoke.replace(new InvokeStatic(
- invoke.getInvokedMethod(), newValue, args.subList(1, args.size())));
+ invoke.replace(
+ new InvokeStatic(invoke.getInvokedMethod(), newValue, args.subList(1, args.size())),
+ code.metadata());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
index 6a6a05e..3adb9d4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
@@ -63,7 +63,7 @@
// String String#substring(int)
// String String#substring(int, int)
public void computeTrivialOperationsOnConstString(IRCode code) {
- if (!code.mayHaveConstString) {
+ if (!code.metadata().mayHaveConstString()) {
return;
}
InstructionIterator it = code.instructionIterator();
@@ -207,7 +207,7 @@
return;
}
boolean markUseIdentifierNameString = false;
- InstructionIterator it = code.instructionIterator();
+ InstructionIterator it = code.instructionIterator().recordChangesToMetadata(code);
while (it.hasNext()) {
Instruction instr = it.next();
if (!instr.isInvokeVirtual()) {
@@ -339,7 +339,6 @@
invoke.getLocalInfo());
ConstString constString = new ConstString(stringValue, name, throwingInfo);
it.replaceCurrentInstruction(constString);
- code.mayHaveConstString = true;
} else if (deferred != null) {
it.replaceCurrentInstruction(deferred);
markUseIdentifierNameString = true;
@@ -354,7 +353,7 @@
// String#valueOf(String s) -> s
// str.toString() -> str
public void removeTrivialConversions(IRCode code) {
- InstructionIterator it = code.instructionIterator();
+ InstructionIterator it = code.instructionIterator().recordChangesToMetadata(code);
while (it.hasNext()) {
Instruction instr = it.next();
if (instr.isInvokeStatic()) {
@@ -377,7 +376,6 @@
ConstString nullString =
new ConstString(nullStringValue, factory.createString("null"), throwingInfo);
it.replaceCurrentInstruction(nullString);
- code.mayHaveConstString = true;
} else if (inType.nullability().isDefinitelyNotNull()
&& inType.isClassType()
&& inType.asClassTypeLatticeElement().getClassType().equals(factory.stringType)) {
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
index 4ce71a9..c007b7b 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
@@ -92,7 +92,7 @@
public void decoupleIdentifierNameStringsInBlocks(
DexEncodedMethod method, IRCode code, Set<BasicBlock> blocks) {
- if (!code.mayHaveConstString) {
+ if (!code.metadata().mayHaveConstString()) {
return;
}
ListIterator<BasicBlock> blockIterator = code.listIterator();
@@ -101,7 +101,7 @@
if (blocks != null && !blocks.contains(block)) {
continue;
}
- InstructionListIterator iterator = block.listIterator();
+ InstructionListIterator iterator = block.listIterator().recordChangesToMetadata(code);
while (iterator.hasNext()) {
Instruction instruction = iterator.next();
// v_n <- "x.y.z" // in.definition
@@ -171,7 +171,7 @@
iterator = block.listIterator(block.getInstructions().size() - 1);
iterator.add(decoupled);
// Restore the cursor and block.
- iterator = blockWithFieldInstruction.listIterator();
+ iterator = blockWithFieldInstruction.listIterator().recordChangesToMetadata(code);
assert iterator.peekNext() == fieldPut;
iterator.next();
} else {
@@ -239,7 +239,7 @@
iterator.replaceCurrentInstruction(decoupled);
iterator.nextUntil(instruction -> instruction == invoke);
} else {
- in.definition.replace(decoupled);
+ in.definition.replace(decoupled, code.metadata());
}
} else {
decoupled.setPosition(invoke.getPosition());
@@ -255,11 +255,12 @@
block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
if (blockWithInvoke != block) {
// If we split, add const-string at the end of the currently visiting block.
- iterator = block.listIterator(block.getInstructions().size());
+ iterator =
+ block.listIterator(block.getInstructions().size()).recordChangesToMetadata(code);
iterator.previous();
iterator.add(decoupled);
// Restore the cursor and block.
- iterator = blockWithInvoke.listIterator();
+ iterator = blockWithInvoke.listIterator().recordChangesToMetadata(code);
assert iterator.peekNext() == invoke;
iterator.next();
} else {
@@ -303,11 +304,12 @@
block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
if (blockWithInvoke != block) {
// If we split, add const-string at the end of the currently visiting block.
- iterator = block.listIterator(block.getInstructions().size());
+ iterator =
+ block.listIterator(block.getInstructions().size()).recordChangesToMetadata(code);
iterator.previous();
iterator.add(decoupled);
// Restore the cursor and block.
- iterator = blockWithInvoke.listIterator();
+ iterator = blockWithInvoke.listIterator().recordChangesToMetadata(code);
assert iterator.peekNext() == invoke;
iterator.next();
} else {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
index d32606d..92c8013 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Return;
+import com.android.tools.r8.ir.code.UpdatableIRMetadata;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
@@ -138,9 +139,7 @@
null,
blocks,
new ValueNumberGenerator(),
- false,
- false,
- false,
+ UpdatableIRMetadata.unknown(),
Origin.unknown());
PeepholeOptimizer.optimize(code, new MockLinearScanRegisterAllocator(appView, code));
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
index 184dce2..1007ea6 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.Goto;
import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.IRMetadata;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.If.Type;
import com.android.tools.r8.ir.code.Instruction;
@@ -78,9 +79,7 @@
null,
blocks,
new ValueNumberGenerator(),
- false,
- false,
- false,
+ IRMetadata.unknown(),
Origin.unknown());
CodeRewriter.collapseTrivialGotos(code);
assertTrue(code.entryBlock().isTrivialGoto());
@@ -165,9 +164,7 @@
null,
blocks,
new ValueNumberGenerator(),
- false,
- false,
- false,
+ IRMetadata.unknown(),
Origin.unknown());
CodeRewriter.collapseTrivialGotos(code);
assertTrue(block0.getInstructions().get(1).isIf());