Bug fixes for JIT loop detection and formation
Specifically:
- Don't apply loop optimization if the basic induction variable is
manipulated (ie excluding cases like "i+=0")
- Fix a case where variables reloaded with constants in the body are
not considered as loop invariants
Bug: 2804188
Change-Id: Ia5ebb29bc6814b1be069e23794585f8313900b7d
diff --git a/vm/compiler/Frontend.c b/vm/compiler/Frontend.c
index 40da0e1..a828886 100644
--- a/vm/compiler/Frontend.c
+++ b/vm/compiler/Frontend.c
@@ -399,7 +399,8 @@
* bytecode into machine code.
*/
bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
- JitTranslationInfo *info, jmp_buf *bailPtr)
+ JitTranslationInfo *info, jmp_buf *bailPtr,
+ int optHints)
{
const DexCode *dexCode = dvmGetMethodCode(desc->method);
const JitTraceRun* currRun = &desc->trace[0];
@@ -671,10 +672,12 @@
kInstrInvoke)) == 0) ||
(lastInsn->dalvikInsn.opCode == OP_INVOKE_DIRECT_EMPTY);
+ /* Only form a loop if JIT_OPT_NO_LOOP is not set */
if (curBB->taken == NULL &&
curBB->fallThrough == NULL &&
flags == (kInstrCanBranch | kInstrCanContinue) &&
- fallThroughOffset == startBB->startOffset) {
+ fallThroughOffset == startBB->startOffset &&
+ JIT_OPT_NO_LOOP != (optHints & JIT_OPT_NO_LOOP)) {
BasicBlock *loopBranch = curBB;
BasicBlock *exitBB;
BasicBlock *exitChainingCell;
@@ -883,7 +886,21 @@
dvmInitializeSSAConversion(&cUnit);
if (cUnit.hasLoop) {
- dvmCompilerLoopOpt(&cUnit);
+ /*
+ * Loop is not optimizable (for example lack of a single induction
+ * variable), punt and recompile the trace with loop optimization
+ * disabled.
+ */
+ bool loopOpt = dvmCompilerLoopOpt(&cUnit);
+ if (loopOpt == false) {
+ if (cUnit.printMe) {
+ LOGD("Loop is not optimizable - retry codegen");
+ }
+ /* Reset the compiler resource pool */
+ dvmCompilerArenaReset();
+ return dvmCompileTrace(desc, cUnit.numInsts, info, bailPtr,
+ optHints | JIT_OPT_NO_LOOP);
+ }
}
else {
dvmCompilerNonLoopAnalysis(&cUnit);
@@ -927,7 +944,8 @@
/* Halve the instruction count and retry again */
} else {
- return dvmCompileTrace(desc, cUnit.numInsts / 2, info, bailPtr);
+ return dvmCompileTrace(desc, cUnit.numInsts / 2, info, bailPtr,
+ optHints);
}
}