diff options
| author | Anders O Nilsson <anders.o.nilsson@stericsson.com> | 2012-12-18 09:31:44 +0100 |
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2013-07-24 12:59:42 -0700 |
| commit | a9ecd84e5f5423a1ba6bbb2bb9256b0dc382de44 (patch) | |
| tree | bc7770441f6db096e8f9d00d064282dedab84773 /vm/compiler/codegen/arm/CodegenDriver.cpp | |
| parent | 96d80eebbb1ba0c8a7b195514e82ac1118a88eb6 (diff) | |
JIT: Combine add with shift and offset for array load & store.
Optimize long and double array load / store for ARM JIT.
Array load / store performs a logical shift left and add,
replace it with add capable of performing shift in the
same instruction.
Array load / store performs an add instead of using offset
for vldr/vstr. Replace the add and vldr/vstr with a vldr/vstr
that is capable of handling offset.
This improves performance for usecases involving long and double
array code execution in Dalvik. E.g WindowOrientation.
Change-Id: I90220c349ab936cdba1987139ccdf4dc31d7bbb0
Signed-off-by: Patrik Ryd <patrik.ryd@stericsson.com>
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenDriver.cpp')
| -rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.cpp | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/vm/compiler/codegen/arm/CodegenDriver.cpp b/vm/compiler/codegen/arm/CodegenDriver.cpp index de53b00fb..ad8fd81ff 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.cpp +++ b/vm/compiler/codegen/arm/CodegenDriver.cpp @@ -398,149 +398,6 @@ static void genIPut(CompilationUnit *cUnit, MIR *mir, OpSize size, } } - -/* - * Generate array load - */ -static void genArrayGet(CompilationUnit *cUnit, MIR *mir, OpSize size, - RegLocation rlArray, RegLocation rlIndex, - RegLocation rlDest, int scale) -{ - RegisterClass regClass = dvmCompilerRegClassBySize(size); - int lenOffset = OFFSETOF_MEMBER(ArrayObject, length); - int dataOffset = OFFSETOF_MEMBER(ArrayObject, contents); - RegLocation rlResult; - rlArray = loadValue(cUnit, rlArray, kCoreReg); - rlIndex = loadValue(cUnit, rlIndex, kCoreReg); - int regPtr; - - /* null object? */ - ArmLIR * pcrLabel = NULL; - - if (!(mir->OptimizationFlags & MIR_IGNORE_NULL_CHECK)) { - pcrLabel = genNullCheck(cUnit, rlArray.sRegLow, - rlArray.lowReg, mir->offset, NULL); - } - - regPtr = dvmCompilerAllocTemp(cUnit); - - if (!(mir->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) { - int regLen = dvmCompilerAllocTemp(cUnit); - /* Get len */ - loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen); - /* regPtr -> array data */ - opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset); - genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir->offset, - pcrLabel); - dvmCompilerFreeTemp(cUnit, regLen); - } else { - /* regPtr -> array data */ - opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset); - } - if ((size == kLong) || (size == kDouble)) { - if (scale) { - int rNewIndex = dvmCompilerAllocTemp(cUnit); - opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale); - opRegReg(cUnit, kOpAdd, regPtr, rNewIndex); - dvmCompilerFreeTemp(cUnit, rNewIndex); - } else { - opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg); - } - rlResult = dvmCompilerEvalLoc(cUnit, rlDest, regClass, true); - - HEAP_ACCESS_SHADOW(true); - loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg); - HEAP_ACCESS_SHADOW(false); - - dvmCompilerFreeTemp(cUnit, regPtr); - storeValueWide(cUnit, rlDest, rlResult); - } else { - rlResult = dvmCompilerEvalLoc(cUnit, rlDest, regClass, true); - - HEAP_ACCESS_SHADOW(true); - loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg, - scale, size); - HEAP_ACCESS_SHADOW(false); - - dvmCompilerFreeTemp(cUnit, regPtr); - storeValue(cUnit, rlDest, rlResult); - } -} - -/* - * Generate array store - * - */ -static void genArrayPut(CompilationUnit *cUnit, MIR *mir, OpSize size, - RegLocation rlArray, RegLocation rlIndex, - RegLocation rlSrc, int scale) -{ - RegisterClass regClass = dvmCompilerRegClassBySize(size); - int lenOffset = OFFSETOF_MEMBER(ArrayObject, length); - int dataOffset = OFFSETOF_MEMBER(ArrayObject, contents); - - int regPtr; - rlArray = loadValue(cUnit, rlArray, kCoreReg); - rlIndex = loadValue(cUnit, rlIndex, kCoreReg); - - if (dvmCompilerIsTemp(cUnit, rlArray.lowReg)) { - dvmCompilerClobber(cUnit, rlArray.lowReg); - regPtr = rlArray.lowReg; - } else { - regPtr = dvmCompilerAllocTemp(cUnit); - genRegCopy(cUnit, regPtr, rlArray.lowReg); - } - - /* null object? */ - ArmLIR * pcrLabel = NULL; - - if (!(mir->OptimizationFlags & MIR_IGNORE_NULL_CHECK)) { - pcrLabel = genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, - mir->offset, NULL); - } - - if (!(mir->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) { - int regLen = dvmCompilerAllocTemp(cUnit); - //NOTE: max live temps(4) here. - /* Get len */ - loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen); - /* regPtr -> array data */ - opRegImm(cUnit, kOpAdd, regPtr, dataOffset); - genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir->offset, - pcrLabel); - dvmCompilerFreeTemp(cUnit, regLen); - } else { - /* regPtr -> array data */ - opRegImm(cUnit, kOpAdd, regPtr, dataOffset); - } - /* at this point, regPtr points to array, 2 live temps */ - if ((size == kLong) || (size == kDouble)) { - //TODO: need specific wide routine that can handle fp regs - if (scale) { - int rNewIndex = dvmCompilerAllocTemp(cUnit); - opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale); - opRegReg(cUnit, kOpAdd, regPtr, rNewIndex); - dvmCompilerFreeTemp(cUnit, rNewIndex); - } else { - opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg); - } - rlSrc = loadValueWide(cUnit, rlSrc, regClass); - - HEAP_ACCESS_SHADOW(true); - storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg); - HEAP_ACCESS_SHADOW(false); - - dvmCompilerFreeTemp(cUnit, regPtr); - } else { - rlSrc = loadValue(cUnit, rlSrc, regClass); - - HEAP_ACCESS_SHADOW(true); - storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg, - scale, size); - HEAP_ACCESS_SHADOW(false); - } -} - /* * Generate array object store * Must use explicit register allocation here because of |
