diff options
| author | Elliott Hughes <enh@google.com> | 2010-04-28 16:15:38 -0700 |
|---|---|---|
| committer | Elliott Hughes <enh@google.com> | 2010-04-28 16:20:36 -0700 |
| commit | 9c45702765732bb449d4df6b8f0700f40ddcc925 (patch) | |
| tree | 3e2dcedf72a529a8a677db082ce72f64510b2642 /vm/compiler/codegen/arm/CodegenDriver.c | |
| parent | c7ad9b2542d5f1a491c9278c998697141ed2582a (diff) | |
Optimize rem-int/lit too.
Bryan hitting the bug in my div-int/lit optimization (that caused it to
try to rewrite rem-int/lit too) shows that I was wrong in assuming % wasn't
worth doing because it wouldn't be hot enough.
Before:
benchmark ns logarithmic runtime
RemainderIntByConstant2 44 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
RemainderIntByConstant2048 34 XXXXXXXXXXXXXXXXXXXXXX|||||
RemainderIntByConstant8 44 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
RemainderIntByVariable2 40 XXXXXXXXXXXXXXXXXXXXXXXXXXX||
After:
benchmark ns logarithmic runtime
RemainderIntByConstant2 13 XXXXXXXXX|||||||||||
RemainderIntByConstant2048 16 XXXXXXXXXXXX||||||||||
RemainderIntByConstant8 16 XXXXXXXXXXXX||||||||||
RemainderIntByVariable2 40 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Bug: 2614702
Change-Id: I719fc8765feececd5b73c3cb2e44dd3cf20c45ce
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenDriver.c')
| -rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c index c691d15b6..68d5b843a 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.c +++ b/vm/compiler/codegen/arm/CodegenDriver.c @@ -1903,9 +1903,6 @@ static int lowestSetBit(unsigned int x) { static bool handleEasyDivide(CompilationUnit *cUnit, OpCode dalvikOpCode, RegLocation rlSrc, RegLocation rlDest, int lit) { - if (dalvikOpCode != OP_DIV_INT_LIT8 && dalvikOpCode != OP_DIV_INT_LIT16) { - return false; - } if (lit < 2 || !isPowerOfTwo(lit)) { return false; } @@ -1914,19 +1911,39 @@ static bool handleEasyDivide(CompilationUnit *cUnit, OpCode dalvikOpCode, // Avoid special cases. return false; } + bool div = (dalvikOpCode == OP_DIV_INT_LIT8 || dalvikOpCode == OP_DIV_INT_LIT16); rlSrc = loadValue(cUnit, rlSrc, kCoreReg); RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true); - int tReg = dvmCompilerAllocTemp(cUnit); - if (lit == 2) { - // Division by 2 is by far the most common division by constant. - opRegRegImm(cUnit, kOpLsr, tReg, rlSrc.lowReg, 32 - k); - opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg); - opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k); + if (div) { + int tReg = dvmCompilerAllocTemp(cUnit); + if (lit == 2) { + // Division by 2 is by far the most common division by constant. + opRegRegImm(cUnit, kOpLsr, tReg, rlSrc.lowReg, 32 - k); + opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg); + opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k); + } else { + opRegRegImm(cUnit, kOpAsr, tReg, rlSrc.lowReg, 31); + opRegRegImm(cUnit, kOpLsr, tReg, tReg, 32 - k); + opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg); + opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k); + } } else { - opRegRegImm(cUnit, kOpAsr, tReg, rlSrc.lowReg, 31); - opRegRegImm(cUnit, kOpLsr, tReg, tReg, 32 - k); - opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg); - opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k); + int cReg = dvmCompilerAllocTemp(cUnit); + loadConstant(cUnit, cReg, lit - 1); + int tReg1 = dvmCompilerAllocTemp(cUnit); + int tReg2 = dvmCompilerAllocTemp(cUnit); + if (lit == 2) { + opRegRegImm(cUnit, kOpLsr, tReg1, rlSrc.lowReg, 32 - k); + opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg); + opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg); + opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1); + } else { + opRegRegImm(cUnit, kOpAsr, tReg1, rlSrc.lowReg, 31); + opRegRegImm(cUnit, kOpLsr, tReg1, tReg1, 32 - k); + opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg); + opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg); + opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1); + } } storeValue(cUnit, rlDest, rlResult); return true; |
