JIT: Add new compare-immed-and-branch primative & drop useless clrex
This allows better use of cbz/cbnz on Thumb2 targets. Also, removed
the clrex from the inline monitor enter code (not necessary).
Change-Id: I3bfa90bcdf34f6ef3e2447c9c6f1b49a98a89e58
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 86c2e29..54d3b8e 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -31,8 +31,7 @@
{
int regCardBase = dvmCompilerAllocTemp(cUnit);
int regCardNo = dvmCompilerAllocTemp(cUnit);
- opRegImm(cUnit, kOpCmp, valReg, 0); /* storing null? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondEq);
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondEq, valReg, 0);
loadWordDisp(cUnit, rGLUE, offsetof(InterpState, cardTable),
regCardBase);
opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
@@ -541,8 +540,7 @@
LOAD_FUNC_ADDR(cUnit, r2, (int)dvmCanPutArrayElement);
/* Are we storing null? If so, avoid check */
- opRegImm(cUnit, kOpCmp, r0, 0);
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondEq);
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
/* Make sure the types are compatible */
loadWordDisp(cUnit, regArray, offsetof(Object, clazz), r1);
@@ -1175,9 +1173,7 @@
loadWordDisp(cUnit, r7, methodIndex * 4, r0);
/* Check if rechain limit is reached */
- opRegImm(cUnit, kOpCmp, r1, 0);
-
- ArmLIR *bypassRechaining = opCondBranch(cUnit, kArmCondGt);
+ ArmLIR *bypassRechaining = genCmpImmBranch(cUnit, kArmCondGt, r1, 0);
loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
jitToInterpEntries.dvmJitToPatchPredictedChain), r7);
@@ -1291,8 +1287,8 @@
LOAD_FUNC_ADDR(cUnit, r2, (int)dvmUnlockObject);
/* Do the call */
opReg(cUnit, kOpBlx, r2);
- opRegImm(cUnit, kOpCmp, r0, 0); /* Did we throw? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ /* Did we throw? */
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
loadConstant(cUnit, r0,
(int) (cUnit->method->insns + mir->offset +
dexGetInstrWidthAbs(gDvm.instrWidth, OP_MONITOR_EXIT)));
@@ -1606,8 +1602,7 @@
opReg(cUnit, kOpBlx, r2);
dvmCompilerClobberCallRegs(cUnit);
/* generate a branch over if allocation is successful */
- opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
/*
* OOM exception needs to be thrown here and cannot re-execute
*/
@@ -1648,8 +1643,9 @@
loadConstant(cUnit, r1, (int) classPtr );
rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
- opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0); /* Null? */
- ArmLIR *branch1 = opCondBranch(cUnit, kArmCondEq);
+ /* Null? */
+ ArmLIR *branch1 = genCmpImmBranch(cUnit, kArmCondEq,
+ rlSrc.lowReg, 0);
/*
* rlSrc.lowReg now contains object->clazz. Note that
* it could have been allocated r0, but we're okay so long
@@ -2253,8 +2249,7 @@
opReg(cUnit, kOpBlx, r3);
dvmCompilerClobberCallRegs(cUnit);
/* generate a branch over if allocation is successful */
- opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
/*
* OOM exception needs to be thrown here and cannot re-execute
*/
@@ -2293,10 +2288,8 @@
dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
loadValueDirectFixed(cUnit, rlSrc, r0); /* Ref */
loadConstant(cUnit, r2, (int) classPtr );
-//TUNING: compare to 0 primative to allow use of CB[N]Z
- opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
/* When taken r0 has NULL which can be used for store directly */
- ArmLIR *branch1 = opCondBranch(cUnit, kArmCondEq);
+ ArmLIR *branch1 = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
/* r1 now contains object->clazz */
loadWordDisp(cUnit, r0, offsetof(Object, clazz), r1);
/* r1 now contains object->clazz */
@@ -2708,8 +2701,7 @@
opReg(cUnit, kOpBlx, r2);
dvmCompilerClobberCallRegs(cUnit);
/* generate a branch over if successful */
- opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
loadConstant(cUnit, r0,
(int) (cUnit->method->insns + mir->offset));
genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
@@ -3055,8 +3047,7 @@
dvmCompilerClobberCallRegs(cUnit);
/* generate a branch over if the interface method is resolved */
- opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
/*
* calleeMethod == NULL -> throw
*/
@@ -3072,9 +3063,8 @@
genRegCopy(cUnit, r1, r8);
/* Check if rechain limit is reached */
- opRegImm(cUnit, kOpCmp, r1, 0);
-
- ArmLIR *bypassRechaining = opCondBranch(cUnit, kArmCondGt);
+ ArmLIR *bypassRechaining = genCmpImmBranch(cUnit, kArmCondGt,
+ r1, 0);
loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
jitToInterpEntries.dvmJitToPatchPredictedChain), r7);
@@ -3448,8 +3438,8 @@
}
opReg(cUnit, kOpBlx, r4PC);
opRegImm(cUnit, kOpAdd, r13, 8);
- opRegImm(cUnit, kOpCmp, r0, 0); /* NULL? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ /* NULL? */
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
loadConstant(cUnit, r0,
(int) (cUnit->method->insns + mir->offset));
genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
diff --git a/vm/compiler/codegen/arm/CodegenFactory.c b/vm/compiler/codegen/arm/CodegenFactory.c
index 157bd1f..1de9f90 100644
--- a/vm/compiler/codegen/arm/CodegenFactory.c
+++ b/vm/compiler/codegen/arm/CodegenFactory.c
@@ -257,6 +257,20 @@
}
}
}
+
+/*
+ * Perform a "reg cmp imm" operation and jump to the PCR region if condition
+ * satisfies.
+ */
+static ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
+ ArmConditionCode cond, int reg,
+ int checkValue, int dOffset,
+ ArmLIR *pcrLabel)
+{
+ ArmLIR *branch = genCmpImmBranch(cUnit, cond, reg, checkValue);
+ return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+}
+
/*
* Perform null-check on a register. sReg is the ssa register being checked,
* and mReg is the machine register holding the actual value. If internal state
diff --git a/vm/compiler/codegen/arm/Thumb/Factory.c b/vm/compiler/codegen/arm/Thumb/Factory.c
index 85f612e..e18aa75 100644
--- a/vm/compiler/codegen/arm/Thumb/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb/Factory.c
@@ -859,21 +859,18 @@
}
}
-static inline ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
+static ArmLIR *genCmpImmBranch(CompilationUnit *cUnit,
ArmConditionCode cond, int reg,
- int checkValue, int dOffset,
- ArmLIR *pcrLabel)
+ int checkValue)
{
- int tReg;
- ArmLIR *res;
if ((checkValue & 0xff) != checkValue) {
- tReg = dvmCompilerAllocTemp(cUnit);
+ int tReg = dvmCompilerAllocTemp(cUnit);
loadConstant(cUnit, tReg, checkValue);
- res = genRegRegCheck(cUnit, cond, reg, tReg, dOffset, pcrLabel);
+ newLIR2(cUnit, kThumbCmpRR, reg, tReg);
dvmCompilerFreeTemp(cUnit, tReg);
- return res;
+ } else {
+ newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
}
- newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
ArmLIR *branch = newLIR2(cUnit, kThumbBCond, 0, cond);
- return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+ return branch;
}
diff --git a/vm/compiler/codegen/arm/Thumb2/Factory.c b/vm/compiler/codegen/arm/Thumb2/Factory.c
index 2bf2940..5074e42 100644
--- a/vm/compiler/codegen/arm/Thumb2/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb2/Factory.c
@@ -1088,15 +1088,13 @@
loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
}
-
/*
- * Perform a "reg cmp imm" operation and jump to the PCR region if condition
- * satisfies.
+ * Generate a register comparison to an immediate and branch. Caller
+ * is responsible for setting branch target field.
*/
-static ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
+static ArmLIR *genCmpImmBranch(CompilationUnit *cUnit,
ArmConditionCode cond, int reg,
- int checkValue, int dOffset,
- ArmLIR *pcrLabel)
+ int checkValue)
{
ArmLIR *branch;
int modImm;
@@ -1118,7 +1116,7 @@
}
branch = newLIR2(cUnit, kThumbBCond, 0, cond);
}
- return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+ return branch;
}
static ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
diff --git a/vm/compiler/codegen/arm/Thumb2/Gen.c b/vm/compiler/codegen/arm/Thumb2/Gen.c
index 3632388..8858bb0 100644
--- a/vm/compiler/codegen/arm/Thumb2/Gen.c
+++ b/vm/compiler/codegen/arm/Thumb2/Gen.c
@@ -220,11 +220,6 @@
hopTarget->defMask = ENCODE_ALL;
hopBranch->generic.target = (LIR *)hopTarget;
- // Clear the lock
- ArmLIR *inst = newLIR0(cUnit, kThumb2Clrex);
- // ...and make it a scheduling barrier
- inst->defMask = ENCODE_ALL;
-
// Export PC (part 1)
loadConstant(cUnit, r3, (int) (cUnit->method->insns + mir->offset));
@@ -290,8 +285,8 @@
sizeof(StackSaveArea) -
offsetof(StackSaveArea, xtra.currentPc));
opReg(cUnit, kOpBlx, r7);
- opRegImm(cUnit, kOpCmp, r0, 0); /* Did we throw? */
- ArmLIR *branchOver = opCondBranch(cUnit, kArmCondNe);
+ /* Did we throw? */
+ ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
loadConstant(cUnit, r0,
(int) (cUnit->method->insns + mir->offset +
dexGetInstrWidthAbs(gDvm.instrWidth, OP_MONITOR_EXIT)));