Fix to allow SCCP to correctly propagate division and remainer ops.
Also updated expected values for the const collector test.
Change-Id: Iedcf17d776c60cb6174f7a7c9f75be84d2c38020
diff --git a/dx/src/com/android/dx/ssa/SCCP.java b/dx/src/com/android/dx/ssa/SCCP.java
index 14b348f..3e101e3 100644
--- a/dx/src/com/android/dx/ssa/SCCP.java
+++ b/dx/src/com/android/dx/ssa/SCCP.java
@@ -442,7 +442,12 @@
vR = vA >>> vB;
break;
case RegOps.REM:
- vR = vA % vB;
+ if (vB == 0) {
+ skip = true;
+ vR = 0; // just to hide a warning
+ } else {
+ vR = vA % vB;
+ }
break;
default:
throw new RuntimeException("Unexpected op");
@@ -467,31 +472,20 @@
simulateBranch(insn);
}
- if (insn.getResult() == null) {
- return;
+ int opcode = insn.getOpcode().getOpcode();
+ RegisterSpec result = insn.getResult();
+
+ // Find corresponding move-result-pseudo result for div and rem
+ if (opcode == RegOps.DIV || opcode == RegOps.REM) {
+ SsaBasicBlock succ = insn.getBlock().getPrimarySuccessor();
+ result = succ.getInsns().get(0).getResult();
}
- int resultReg = insn.getResult().getReg();
- int resultType = insn.getResult().getBasicType();
+ if (result == null) return;
+
+ int resultReg = result.getReg();
int resultValue = VARYING;
Constant resultConstant = null;
- int opcode = insn.getOpcode().getOpcode();
-
- // TODO: Handle non-int arithmetic.
- /*
- if (resultType != Type.BT_INT) {
- return;
- }
-
- // Find defining instruction for move-result-pseudo instructions
- if (opcode == RegOps.MOVE_RESULT_PSEUDO) {
- int pred = insn.getBlock().getPredecessors().nextSetBit(0);
- ArrayList<SsaInsn> predInsns;
- predInsns = ssaMeth.getBlocks().get(pred).getInsns();
- insn = predInsns.get(predInsns.size()-1);
- opcode = insn.getOpcode().getOpcode();
- }
- */
switch (opcode) {
case RegOps.CONST: {
@@ -508,7 +502,6 @@
}
break;
}
-
case RegOps.ADD:
case RegOps.SUB:
case RegOps.MUL:
@@ -519,16 +512,21 @@
case RegOps.SHL:
case RegOps.SHR:
case RegOps.USHR:
- case RegOps.REM:
-
- resultConstant = simulateMath(insn, resultType);
-
- if (resultConstant == null) {
- resultValue = VARYING;
- } else {
+ case RegOps.REM: {
+ resultConstant = simulateMath(insn, result.getBasicType());
+ if (resultConstant != null) {
resultValue = CONSTANT;
}
- break;
+ break;
+ }
+ case RegOps.MOVE_RESULT_PSEUDO: {
+ if (latticeValues[resultReg] == CONSTANT) {
+ resultValue = latticeValues[resultReg];
+ resultConstant = latticeConstants[resultReg];
+ }
+ break;
+ }
+ // TODO: Handle non-int arithmetic.
// TODO: Eliminate check casts that we can prove the type of.
default: {}
}
diff --git a/dx/tests/091-ssa-const-collector/expected.txt b/dx/tests/091-ssa-const-collector/expected.txt
index a8139f1..1d5a87c 100644
--- a/dx/tests/091-ssa-const-collector/expected.txt
+++ b/dx/tests/091-ssa-const-collector/expected.txt
@@ -407,7 +407,7 @@
@????: mark-local-int . <- v1:"b"I
Blort.java:54@0011: const-int(10) v2:I=10 <- .
@????: mark-local-int . <- v2:"c"I
- Blort.java:56@0018: mul-const-int(10) v3:I <- v3:I
+ Blort.java:56@0018: const-int(100) v3:I=100 <- .
@????: mark-local-int . <- v3:"i"I=100
Blort.java:57@001a: goto . <- .
next 0003