bool RangeAnalysis::analyze() { int numBlocks = 0; for (PostorderIterator i(graph_.poBegin()); i != graph_.poEnd(); i++) { numBlocks++; MBasicBlock *curBlock = *i; if (!curBlock->isLoopHeader()) continue; for (MPhiIterator pi(curBlock->phisBegin()); pi != curBlock->phisEnd(); pi++) if (!pi->initCounts()) return false; } IonSpew(IonSpew_Range, "Doing range propagation"); MDefinitionVector worklist; for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) { for (MDefinitionIterator iter(*block); iter; iter++) { MDefinition *def = *iter; AddToWorklist(worklist, def); } } size_t iters = 0; while (!worklist.empty()) { MDefinition *def = PopFromWorklist(worklist); IonSpew(IonSpew_Range, "recomputing range on %d", def->id()); SpewRange(def); if (!def->earlyAbortCheck() && def->recomputeRange()) { JS_ASSERT(def->range()->lower() <= def->range()->upper()); IonSpew(IonSpew_Range, "Range changed; adding consumers"); IonSpew(IonSpew_Range, "New range for %d is: (%d, %d)", def->id(), def->range()->lower(), def->range()->upper()); for (MUseDefIterator use(def); use; use++) { if(!AddToWorklist(worklist, use.def())) return false; } } iters++; if (iters >= numBlocks * 100) return false; } // Cleanup (in case we stopped due to MAX_ITERS) for(size_t i = 0; i < worklist.length(); i++) worklist[i]->setNotInWorklist(); #ifdef DEBUG for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) { for (MDefinitionIterator iter(*block); iter; iter++) { MDefinition *def = *iter; SpewRange(def); JS_ASSERT(def->range()->lower() <= def->range()->upper()); JS_ASSERT(!def->isInWorklist()); } } #endif return true; }