Implement mayHaveArithmeticOrLogicalBinop()
Bug: 145202413
Change-Id: I08655b15b08243b923f244cdad000da4880522df
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 805aad9..6a130a1 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
@@ -763,7 +763,13 @@
private boolean consistentMetadata() {
for (Instruction instruction : instructions()) {
- if (instruction.isCheckCast()) {
+ if (instruction.isAdd()) {
+ assert metadata.mayHaveAdd() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has an add";
+ } else if (instruction.isAnd()) {
+ assert metadata.mayHaveAnd() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has an and";
+ } else if (instruction.isCheckCast()) {
assert metadata.mayHaveCheckCast()
: "IR metadata should indicate that code has a check-cast";
} else if (instruction.isConstNumber()) {
@@ -778,6 +784,9 @@
} else if (instruction.isDexItemBasedConstString()) {
assert metadata.mayHaveDexItemBasedConstString()
: "IR metadata should indicate that code has a dex-item-based-const-string";
+ } else if (instruction.isDiv()) {
+ assert metadata.mayHaveDiv() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has a div";
} else if (instruction.isInstanceGet()) {
assert metadata.mayHaveInstanceGet()
: "IR metadata should indicate that code has an instance-get";
@@ -808,9 +817,24 @@
} else if (instruction.isInvokeVirtual()) {
assert metadata.mayHaveInvokeVirtual()
: "IR metadata should indicate that code has an invoke-virtual";
+ } else if (instruction.isOr()) {
+ assert metadata.mayHaveOr() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has an or";
} else if (instruction.isMonitor()) {
assert metadata.mayHaveMonitorInstruction()
: "IR metadata should indicate that code has a monitor instruction";
+ } else if (instruction.isMul()) {
+ assert metadata.mayHaveMul() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has a mul";
+ } else if (instruction.isRem()) {
+ assert metadata.mayHaveRem() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has a rem";
+ } else if (instruction.isShl()) {
+ assert metadata.mayHaveShl() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has a shl";
+ } else if (instruction.isShr()) {
+ assert metadata.mayHaveShr() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has a shr";
} else if (instruction.isStaticGet()) {
assert metadata.mayHaveStaticGet()
: "IR metadata should indicate that code has a static-get";
@@ -820,6 +844,15 @@
} else if (instruction.isStringSwitch()) {
assert metadata.mayHaveStringSwitch()
: "IR metadata should indicate that code has a string-switch";
+ } else if (instruction.isSub()) {
+ assert metadata.mayHaveSub() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has a sub";
+ } else if (instruction.isUshr()) {
+ assert metadata.mayHaveUshr() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has an ushr";
+ } else if (instruction.isXor()) {
+ assert metadata.mayHaveXor() && metadata.mayHaveArithmeticOrLogicalBinop()
+ : "IR metadata should indicate that code has an xor";
}
}
return true;
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
index f6054e1..c4d55d8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRMetadata.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRMetadata.java
@@ -57,6 +57,14 @@
second |= metadata.second;
}
+ public boolean mayHaveAdd() {
+ return get(Opcodes.ADD);
+ }
+
+ public boolean mayHaveAnd() {
+ return get(Opcodes.AND);
+ }
+
public boolean mayHaveCheckCast() {
return get(Opcodes.CHECK_CAST);
}
@@ -77,15 +85,19 @@
return get(Opcodes.DEX_ITEM_BASED_CONST_STRING);
}
+ public boolean mayHaveDiv() {
+ return get(Opcodes.DIV);
+ }
+
public boolean mayHaveFieldGet() {
return mayHaveInstanceGet() || mayHaveStaticGet();
}
public boolean mayHaveFieldInstruction() {
- assert Opcodes.INSTANCE_GET <= 64;
- assert Opcodes.INSTANCE_PUT <= 64;
- assert Opcodes.STATIC_GET <= 64;
- assert Opcodes.STATIC_PUT <= 64;
+ assert Opcodes.INSTANCE_GET < 64;
+ assert Opcodes.INSTANCE_PUT < 64;
+ assert Opcodes.STATIC_GET < 64;
+ assert Opcodes.STATIC_PUT < 64;
long mask =
(1L << Opcodes.INSTANCE_GET)
| (1L << Opcodes.INSTANCE_PUT)
@@ -126,12 +138,12 @@
@SuppressWarnings("ConstantConditions")
public boolean mayHaveInvokeMethod() {
- assert Opcodes.INVOKE_DIRECT <= 64;
- assert Opcodes.INVOKE_INTERFACE <= 64;
- assert Opcodes.INVOKE_POLYMORPHIC <= 64;
- assert Opcodes.INVOKE_STATIC <= 64;
- assert Opcodes.INVOKE_SUPER <= 64;
- assert Opcodes.INVOKE_VIRTUAL <= 64;
+ assert Opcodes.INVOKE_DIRECT < 64;
+ assert Opcodes.INVOKE_INTERFACE < 64;
+ assert Opcodes.INVOKE_POLYMORPHIC < 64;
+ assert Opcodes.INVOKE_STATIC < 64;
+ assert Opcodes.INVOKE_SUPER < 64;
+ assert Opcodes.INVOKE_VIRTUAL < 64;
long mask =
(1L << Opcodes.INVOKE_DIRECT)
| (1L << Opcodes.INVOKE_INTERFACE)
@@ -152,10 +164,10 @@
@SuppressWarnings("ConstantConditions")
public boolean mayHaveInvokeMethodWithReceiver() {
- assert Opcodes.INVOKE_DIRECT <= 64;
- assert Opcodes.INVOKE_INTERFACE <= 64;
- assert Opcodes.INVOKE_SUPER <= 64;
- assert Opcodes.INVOKE_VIRTUAL <= 64;
+ assert Opcodes.INVOKE_DIRECT < 64;
+ assert Opcodes.INVOKE_INTERFACE < 64;
+ assert Opcodes.INVOKE_SUPER < 64;
+ assert Opcodes.INVOKE_VIRTUAL < 64;
long mask =
(1L << Opcodes.INVOKE_DIRECT)
| (1L << Opcodes.INVOKE_INTERFACE)
@@ -190,6 +202,26 @@
return get(Opcodes.MONITOR);
}
+ public boolean mayHaveMul() {
+ return get(Opcodes.MUL);
+ }
+
+ public boolean mayHaveOr() {
+ return get(Opcodes.OR);
+ }
+
+ public boolean mayHaveRem() {
+ return get(Opcodes.REM);
+ }
+
+ public boolean mayHaveShl() {
+ return get(Opcodes.SHL);
+ }
+
+ public boolean mayHaveShr() {
+ return get(Opcodes.SHR);
+ }
+
public boolean mayHaveStaticGet() {
return get(Opcodes.STATIC_GET);
}
@@ -202,8 +234,58 @@
return get(Opcodes.STRING_SWITCH);
}
+ public boolean mayHaveSub() {
+ return get(Opcodes.SUB);
+ }
+
+ public boolean mayHaveUshr() {
+ return get(Opcodes.USHR);
+ }
+
+ public boolean mayHaveXor() {
+ return get(Opcodes.XOR);
+ }
+
public boolean mayHaveArithmeticOrLogicalBinop() {
- // TODO(b/7145202413): Implement this.
- return true;
+ // ArithmeticBinop
+ assert Opcodes.ADD < 64;
+ assert Opcodes.DIV < 64;
+ assert Opcodes.MUL < 64;
+ assert Opcodes.REM < 64;
+ assert Opcodes.SUB < 64;
+ // LogicalBinop
+ assert Opcodes.AND < 64;
+ assert Opcodes.OR < 64;
+ assert Opcodes.SHL < 64;
+ assert Opcodes.SHR < 64;
+ assert Opcodes.USHR >= 64;
+ assert Opcodes.XOR >= 64;
+ long mask =
+ (1L << Opcodes.ADD)
+ | (1L << Opcodes.DIV)
+ | (1L << Opcodes.MUL)
+ | (1L << Opcodes.REM)
+ | (1L << Opcodes.SUB)
+ | (1L << Opcodes.AND)
+ | (1L << Opcodes.OR)
+ | (1L << Opcodes.SHL)
+ | (1L << Opcodes.SHR)
+ | (1L << Opcodes.USHR)
+ | (1L << Opcodes.XOR);
+ long other = (1L << (Opcodes.USHR - 64)) | (1L << (Opcodes.XOR - 64));
+ boolean result = isAnySetInFirst(mask) || isAnySetInSecond(other);
+ assert result
+ == (mayHaveAdd()
+ || mayHaveDiv()
+ || mayHaveMul()
+ || mayHaveRem()
+ || mayHaveSub()
+ || mayHaveAnd()
+ || mayHaveOr()
+ || mayHaveShl()
+ || mayHaveShr()
+ || mayHaveUshr()
+ || mayHaveXor());
+ return result;
}
}
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 d48d1f2..326c17b 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
@@ -3019,7 +3019,7 @@
newInstruction.setBlock(phiBlock);
// The xor is replacing a phi so it does not have an actual position.
newInstruction.setPosition(phiPosition);
- phiBlock.getInstructions().add(insertIndex, newInstruction);
+ phiBlock.listIterator(code, insertIndex).add(newInstruction);
deadPhis++;
}
}