bool Loop::optimize() { InstructionQueue invariantInstructions; InstructionQueue boundsChecks; IonSpew(IonSpew_LICM, "These instructions are in the loop: "); while (!worklist_.empty()) { if (mir->shouldCancel("LICM (worklist)")) return false; MInstruction *ins = popFromWorklist(); IonSpewHeader(IonSpew_LICM); if (IonSpewEnabled(IonSpew_LICM)) { ins->printName(IonSpewFile); fprintf(IonSpewFile, " <- "); ins->printOpcode(IonSpewFile); fprintf(IonSpewFile, ": "); } if (isLoopInvariant(ins)) { // Flag this instruction as loop invariant. ins->setLoopInvariant(); if (!invariantInstructions.append(ins)) return false; // Loop through uses of invariant instruction and add back to work list. for (MUseDefIterator iter(ins->toDefinition()); iter; iter++) { MDefinition *consumer = iter.def(); if (consumer->isInWorklist()) continue; // if the consumer of this invariant instruction is in the // loop, and it is also worth hoisting, then process it. if (isInLoop(consumer) && isHoistable(consumer)) { if (!insertInWorklist(consumer->toInstruction())) return false; } } if (IonSpewEnabled(IonSpew_LICM)) fprintf(IonSpewFile, " Loop Invariant!\n"); } else if (ins->isBoundsCheck()) { if (!boundsChecks.append(ins)) return false; } } if (!hoistInstructions(invariantInstructions, boundsChecks)) return false; return true; }