コード例 #1
0
ファイル: loopOpt.cpp プロジェクト: sebkirche/strongtalk
void CompiledLoop::removeLoopVarOverflow() {
  // bug: should remove overflow only if increment is constant and not too large -- fix this
  Node* n = _incNode->next();
  assert(n->isBranchNode(), "must be branch");
  BranchNode* overflowCheck = (BranchNode*)n;
  assert(overflowCheck->op() == VSBranchOp, "should be overflow check");
  if (CompilerDebug || PrintLoopOpts) {
    cout(PrintLoopOpts)->print("*removing overflow check at node N%d\n", overflowCheck->id());
  }
  Node* taken = overflowCheck->next(1);	  // overflow handling code
  taken->removeUpToMerge();
  overflowCheck->removeNext(taken);	  // so overflowCheck can be eliminated
  overflowCheck->eliminate(overflowCheck->bb(), NULL, true, false);

  // since increment cannot fail anymore, directly increment loop counter if possible
  // need to search for assignment of incremented value to loop var
  Node* a = overflowCheck->next();
  while (1) {
    if (a->nPredecessors() > 1) break;	  // can't search beyond merge
    if (a->nSuccessors()   > 1) break;	  // can't search beyond branches
    if (a->isAssignNode()) {
      if (!a->deleted) {
	AssignNode* assign = (AssignNode*)a;
	if (assign->src() == _incNode->dest() && assign->dest() == _loopVar) {
	  if (CompilerDebug || PrintLoopOpts) {
	    cout(PrintLoopOpts)->print("*optimizing loopVar increment at N%d\n", _incNode->id());
	  }
	  _incNode->setDest(_incNode->bb(), _loopVar);
	  assign->eliminate(assign->bb(), NULL, true, false);
	}
      }
    } else if (!a->isTrivial()) {
      compiler_warning("unexpected nontrivial node N%d after loopVar increment\n", a->id());
    }
    a = a->next();
  }
}