bool RangeAnalysis::removeBetaNobes() { IonSpew(IonSpew_Range, "Removing beta nobes"); for (PostorderIterator i(graph_.poBegin()); i != graph_.poEnd(); i++) { MBasicBlock *block = *i; for (MDefinitionIterator iter(*i); iter; ) { MDefinition *def = *iter; if (def->isBeta()) { MDefinition *op = def->getOperand(0); IonSpew(IonSpew_Range, "Removing beta node %d for %d", def->id(), op->id()); def->replaceAllUsesWith(op); iter = block->discardDefAt(iter); } else { // We only place Beta nodes at the beginning of basic // blocks, so if we see something else, we can move on // to the next block. break; } } } return true; }
static bool CheckUseImpliesOperand(MInstruction *ins, MUse *use) { MNode *consumer = use->consumer(); uint32_t index = use->index(); if (consumer->isDefinition()) { MDefinition *def = consumer->toDefinition(); return (def->getOperand(index) == ins); } JS_ASSERT(consumer->isResumePoint()); MResumePoint *res = consumer->toResumePoint(); return (res->getOperand(index) == ins); }
MDefinition * MBitNot::foldsTo(bool useValueNumbers) { if (specialization_ != MIRType_Int32) return this; MDefinition *input = getOperand(0); if (input->isConstant()) { js::Value v = Int32Value(~(input->toConstant()->value().toInt32())); return MConstant::New(v); } if (input->isBitNot()) return input->getOperand(0); // ~~x => x return this; }
LoopIterationBound * RangeAnalysis::analyzeLoopIterationCount(MBasicBlock *header, MTest *test, BranchDirection direction) { SimpleLinearSum lhs(NULL, 0); MDefinition *rhs; bool lessEqual; if (!ExtractLinearInequality(test, direction, &lhs, &rhs, &lessEqual)) return NULL; // Ensure the rhs is a loop invariant term. if (rhs && rhs->block()->isMarked()) { if (lhs.term && lhs.term->block()->isMarked()) return NULL; MDefinition *temp = lhs.term; lhs.term = rhs; rhs = temp; if (!SafeSub(0, lhs.constant, &lhs.constant)) return NULL; lessEqual = !lessEqual; } JS_ASSERT_IF(rhs, !rhs->block()->isMarked()); // Ensure the lhs is a phi node from the start of the loop body. if (!lhs.term || !lhs.term->isPhi() || lhs.term->block() != header) return NULL; // Check that the value of the lhs changes by a constant amount with each // loop iteration. This requires that the lhs be written in every loop // iteration with a value that is a constant difference from its value at // the start of the iteration. if (lhs.term->toPhi()->numOperands() != 2) return NULL; // The first operand of the phi should be the lhs' value at the start of // the first executed iteration, and not a value written which could // replace the second operand below during the middle of execution. MDefinition *lhsInitial = lhs.term->toPhi()->getOperand(0); if (lhsInitial->block()->isMarked()) return NULL; // The second operand of the phi should be a value written by an add/sub // in every loop iteration, i.e. in a block which dominates the backedge. MDefinition *lhsWrite = lhs.term->toPhi()->getOperand(1); if (lhsWrite->isBeta()) lhsWrite = lhsWrite->getOperand(0); if (!lhsWrite->isAdd() && !lhsWrite->isSub()) return NULL; if (!lhsWrite->block()->isMarked()) return NULL; MBasicBlock *bb = header->backedge(); for (; bb != lhsWrite->block() && bb != header; bb = bb->immediateDominator()) {} if (bb != lhsWrite->block()) return NULL; SimpleLinearSum lhsModified = ExtractLinearSum(lhsWrite); // Check that the value of the lhs at the backedge is of the form // 'old(lhs) + N'. We can be sure that old(lhs) is the value at the start // of the iteration, and not that written to lhs in a previous iteration, // as such a previous value could not appear directly in the addition: // it could not be stored in lhs as the lhs add/sub executes in every // iteration, and if it were stored in another variable its use here would // be as an operand to a phi node for that variable. if (lhsModified.term != lhs.term) return NULL; LinearSum bound; if (lhsModified.constant == 1 && !lessEqual) { // The value of lhs is 'initial(lhs) + iterCount' and this will end // execution of the loop if 'lhs + lhsN >= rhs'. Thus, an upper bound // on the number of backedges executed is: // // initial(lhs) + iterCount + lhsN == rhs // iterCount == rhsN - initial(lhs) - lhsN if (rhs) { if (!bound.add(rhs, 1)) return NULL; } if (!bound.add(lhsInitial, -1)) return NULL; int32_t lhsConstant; if (!SafeSub(0, lhs.constant, &lhsConstant)) return NULL; if (!bound.add(lhsConstant)) return NULL; } else if (lhsModified.constant == -1 && lessEqual) { // The value of lhs is 'initial(lhs) - iterCount'. Similar to the above // case, an upper bound on the number of backedges executed is: // // initial(lhs) - iterCount + lhsN == rhs // iterCount == initial(lhs) - rhs + lhsN if (!bound.add(lhsInitial, 1)) return NULL; if (rhs) { if (!bound.add(rhs, -1)) return NULL; } if (!bound.add(lhs.constant)) return NULL; } else { return NULL; } return new LoopIterationBound(header, test, bound); }