char* CompiledLoop::findUpperBound() { // find upper bound and loop variable int condBCI = findStartOfSend(_endOfCond->bci() - InterpretedIC::size); if (condBCI == IllegalBCI) return "loop condition: no send found"; // first find comparison in loop condition Expr* loopCond = _scope->exprStackElems()->at(condBCI); if (loopCond == NULL) return "loop condition: no expr (possible compiler bug)"; if (loopCond->isMergeExpr()) { MergeExpr* cond = (MergeExpr*)loopCond; if (cond->isSplittable()) { Node* first = cond->exprs->first()->node(); if (first->nPredecessors() == 1) { Node* prev = first->firstPrev(); if (prev->isBranchNode()) _loopBranch = (BranchNode*)prev; } } } if (!_loopBranch) return "loop condition: conditional branch not found"; NonTrivialNode* n = (NonTrivialNode*)_loopBranch->firstPrev(); PReg* operand; if (n->isTArithNode()) { operand = ((TArithRRNode*)n)->operand(); } else if (n->isArithNode()) { operand = ((ArithRRNode*)n)->operand(); } else { return "loop condition: comparison not found"; } BranchOpCode op = _loopBranch->op(); // Now see if it's a simple comparison involving the loop variable // and make an initial guess about the loop variable. // NB: code generator inverts loop condition, i.e., branch leaves loop if (op == LTBranchOp || op == LEBranchOp) { // upperBound > loopVar _loopVar = operand; _upperBound = n->src(); } else if (op == GTBranchOp || op == GEBranchOp) { // loopVar < upperBound _loopVar = n->src(); _upperBound = operand; } else { return "loop condition: not oneof(<, <=, >, >=)"; } // The above code assumes a loop counting up; check the loopVar now and switch // directions if it doesn't work. if (checkLoopVar()) { // the reverse guess may be wrong too, but it doesn't hurt to try PReg* temp = _loopVar; _loopVar = _upperBound; _upperBound = temp; } return NULL; }
int InterpretedIC::findStartOfSend(methodOop m, int bci) { u_char* p = findStartOfSend(m->codes(bci)); return (p == NULL) ? IllegalBCI : p - m->codes() + 1; }