Preserve itf bit in outliner
Change-Id: I7cc094a799d0da9abf409ff4a14f54db67a0b5bf
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
index ee3fc44..6c0e779 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
@@ -115,7 +115,7 @@
* {@link OutlineOptions#threshold}). Each selected method is then converted back to IR and
* passed to {@link OutlinerImpl#identifyOutlineSites(IRCode)}, which then stores concrete
* outlining candidates in {@link OutlinerImpl#outlineSites}.
- * <li>Third, {@link OutlinerImpl#buildOutlineMethods()} is called to construct the <em>outline
+ * <li>Third, {@link OutlinerImpl#buildOutlineMethods} is called to construct the <em>outline
* support classes</em> containing a static helper method for each outline candidate that
* occurs frequently enough. Each selected method is then converted to IR, passed to {@link
* OutlinerImpl#applyOutliningCandidate(IRCode)} to perform the outlining, and converted back
@@ -133,7 +133,7 @@
/** Result of second step (see {@link OutlinerImpl#selectMethodsForOutlining()}. */
private final Map<Outline, List<ProgramMethod>> outlineSites = new HashMap<>();
- /** Result of third step (see {@link OutlinerImpl#buildOutlineMethods()}. */
+ /** Result of third step (see {@link OutlinerImpl#buildOutlineMethods}. */
private final Map<Outline, DexMethod> generatedOutlines = new HashMap<>();
static final int MAX_IN_SIZE = 5; // Avoid using ranged calls for outlined code.
@@ -142,7 +142,7 @@
private final DexItemFactory dexItemFactory;
private final InliningConstraints inliningConstraints;
- private abstract static class OutlineInstruction {
+ private abstract static class OutlineInstruction implements Comparable<OutlineInstruction> {
// Value signaling that this is the one allowed temporary register for an outline.
private static final int OUTLINE_TEMP = -1;
@@ -182,12 +182,6 @@
}
}
- protected final OutlineInstructionType type;
-
- protected OutlineInstruction(OutlineInstructionType type) {
- this.type = type;
- }
-
static OutlineInstruction fromInstruction(Instruction instruction) {
if (instruction.isBinop()) {
return BinOpOutlineInstruction.fromInstruction(instruction.asBinop());
@@ -200,14 +194,7 @@
}
@Override
- public int hashCode() {
- return type.ordinal();
- }
-
- @SuppressWarnings("MissingImplementsComparable")
- public int compareTo(OutlineInstruction other) {
- return type.compareTo(other.type);
- }
+ public abstract int hashCode();
@Override
public abstract boolean equals(Object other);
@@ -216,6 +203,8 @@
public abstract String getInstructionName();
+ public abstract OutlineInstructionType getOutlineInstructionType();
+
public abstract boolean hasOutValue();
public abstract int numberOfInputs();
@@ -227,10 +216,11 @@
private static class BinOpOutlineInstruction extends OutlineInstruction {
+ private final OutlineInstructionType type;
private final NumericType numericType;
private BinOpOutlineInstruction(OutlineInstructionType type, NumericType numericType) {
- super(type);
+ this.type = type;
this.numericType = numericType;
}
@@ -241,22 +231,25 @@
@Override
public int hashCode() {
- return super.hashCode() * 7 + numericType.ordinal();
+ return Objects.hash(type, numericType);
}
@Override
public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
if (!(other instanceof BinOpOutlineInstruction)) {
return false;
}
BinOpOutlineInstruction o = (BinOpOutlineInstruction) other;
- return o.type.equals(type) && o.numericType.equals(numericType);
+ return type.equals(o.type) && numericType.equals(o.numericType);
}
@Override
public int compareTo(OutlineInstruction other) {
if (!(other instanceof BinOpOutlineInstruction)) {
- return super.compareTo(other);
+ return type.compareTo(other.getOutlineInstructionType());
}
BinOpOutlineInstruction o = (BinOpOutlineInstruction) other;
int result = type.compareTo(o.type);
@@ -277,6 +270,11 @@
}
@Override
+ public OutlineInstructionType getOutlineInstructionType() {
+ return type;
+ }
+
+ @Override
public boolean hasOutValue() {
return true;
}
@@ -336,30 +334,30 @@
private final DexType clazz;
NewInstanceOutlineInstruction(DexType clazz) {
- super(OutlineInstructionType.NEW);
this.clazz = clazz;
}
@Override
- @SuppressWarnings("ReferenceEquality")
public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
if (!(other instanceof NewInstanceOutlineInstruction)) {
return false;
}
NewInstanceOutlineInstruction o = (NewInstanceOutlineInstruction) other;
- boolean result = clazz == o.clazz;
- return result;
+ return clazz.isIdenticalTo(o.clazz);
}
@Override
public int hashCode() {
- return super.hashCode() * 7 + clazz.hashCode();
+ return Objects.hash(getOutlineInstructionType(), clazz.hashCode());
}
@Override
public int compareTo(OutlineInstruction other) {
if (!(other instanceof NewInstanceOutlineInstruction)) {
- return super.compareTo(other);
+ return getOutlineInstructionType().compareTo(other.getOutlineInstructionType());
}
NewInstanceOutlineInstruction o = (NewInstanceOutlineInstruction) other;
return clazz.compareTo(o.clazz);
@@ -372,7 +370,12 @@
@Override
public String getInstructionName() {
- return type.name();
+ return getOutlineInstructionType().name();
+ }
+
+ @Override
+ public OutlineInstructionType getOutlineInstructionType() {
+ return OutlineInstructionType.NEW;
}
@Override
@@ -397,9 +400,8 @@
}
@Override
- @SuppressWarnings("ReferenceEquality")
public boolean needsLensRewriting(GraphLens currentGraphLens) {
- return currentGraphLens.lookupType(clazz) != clazz;
+ return !currentGraphLens.lookupType(clazz).isIdenticalTo(clazz);
}
}
@@ -409,20 +411,22 @@
private final boolean hasOutValue;
private final DexProto proto;
private final boolean hasReceiver;
+ private final boolean itf;
private InvokeOutlineInstruction(
DexMethod method,
InvokeType type,
boolean hasOutValue,
ValueType[] inputTypes,
- DexProto proto) {
- super(OutlineInstructionType.INVOKE);
+ DexProto proto,
+ boolean itf) {
hasReceiver = inputTypes.length != method.proto.parameters.values.length;
assert !hasReceiver || inputTypes[0].isObject();
this.method = method;
this.invokeType = type;
this.hasOutValue = hasOutValue;
this.proto = proto;
+ this.itf = itf;
}
static InvokeOutlineInstruction fromInstruction(InvokeMethod invoke) {
@@ -436,35 +440,35 @@
invoke.getType(),
invoke.outValue() != null,
inputTypes,
- invoke.isInvokePolymorphic() ? invoke.asInvokePolymorphic().getProto() : null);
+ invoke.isInvokePolymorphic() ? invoke.asInvokePolymorphic().getProto() : null,
+ invoke.getInterfaceBit());
}
@Override
public int hashCode() {
- return super.hashCode() * 7
- + method.hashCode() * 13
- + invokeType.hashCode()
- + Boolean.hashCode(hasOutValue)
- + Objects.hashCode(proto);
+ return Objects.hash(getOutlineInstructionType(), method, invokeType, hasOutValue, proto, itf);
}
@Override
- @SuppressWarnings("ReferenceEquality")
public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
if (!(other instanceof InvokeOutlineInstruction)) {
return false;
}
InvokeOutlineInstruction o = (InvokeOutlineInstruction) other;
- return method == o.method
+ return method.isIdenticalTo(o.method)
&& invokeType == o.invokeType
&& hasOutValue == o.hasOutValue
- && Objects.equals(proto, o.proto);
+ && DexProto.identical(proto, o.proto)
+ && itf == o.itf;
}
@Override
public int compareTo(OutlineInstruction other) {
if (!(other instanceof InvokeOutlineInstruction)) {
- return super.compareTo(other);
+ return getOutlineInstructionType().compareTo(other.getOutlineInstructionType());
}
InvokeOutlineInstruction o = (InvokeOutlineInstruction) other;
int result = method.compareTo(o.method);
@@ -485,7 +489,11 @@
return result;
}
}
- assert this.equals(other);
+ result = Boolean.compare(itf, o.itf);
+ if (result != 0) {
+ return result;
+ }
+ assert equals(other);
return 0;
}
@@ -496,7 +504,12 @@
@Override
public String getInstructionName() {
- return type.name() + "-" + invokeType.name();
+ return getOutlineInstructionType().name() + "-" + invokeType.name();
+ }
+
+ @Override
+ public OutlineInstructionType getOutlineInstructionType() {
+ return OutlineInstructionType.INVOKE;
}
@Override
@@ -536,15 +549,15 @@
builder.writeRegister(outline.argumentCount(), latticeElement, ThrowingInfo.CAN_THROW);
}
- Instruction newInstruction = Invoke.create(invokeType, method, proto, outValue, inValues);
+ Instruction newInstruction =
+ Invoke.create(invokeType, method, proto, outValue, inValues, itf);
builder.add(newInstruction);
return argumentMapIndex;
}
@Override
- @SuppressWarnings("ReferenceEquality")
public boolean needsLensRewriting(GraphLens currentGraphLens) {
- return currentGraphLens.getRenamedMethodSignature(method) != method;
+ return !currentGraphLens.getRenamedMethodSignature(method).isIdenticalTo(method);
}
}