bool EagerSimdUnbox(MIRGenerator* mir, MIRGraph& graph) { const JitCompartment* jitCompartment = GetJitContext()->compartment->jitCompartment(); for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) { if (mir->shouldCancel("Eager Simd Unbox")) return false; for (MInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) { if (!ins->isSimdUnbox()) continue; MSimdUnbox* unbox = ins->toSimdUnbox(); if (!unbox->input()->isPhi()) continue; MPhi* phi = unbox->input()->toPhi(); if (!CanUnboxSimdPhi(jitCompartment, phi, unbox->simdType())) continue; UnboxSimdPhi(jitCompartment, graph, phi, unbox->simdType()); } } return true; }
void MBasicBlock::flagOperandsOfPrunedBranches(MInstruction* ins) { // Find the previous resume point which would be used for bailing out. MResumePoint* rp = nullptr; for (MInstructionReverseIterator iter = rbegin(ins); iter != rend(); iter++) { rp = iter->resumePoint(); if (rp) break; } // If none, take the entry resume point. if (!rp) rp = entryResumePoint(); // The only blocks which do not have any entryResumePoint in Ion, are the // SplitEdge blocks. SplitEdge blocks only have a Goto instruction before // Range Analysis phase. In adjustInputs, we are manipulating instructions // which have a TypePolicy. So, as a Goto has no operand and no type // policy, the entry resume point should exists. MOZ_ASSERT(rp); // Flag all operand as being potentially used. while (rp) { for (size_t i = 0, end = rp->numOperands(); i < end; i++) rp->getOperand(i)->setUseRemovedUnchecked(); rp = rp->caller(); } }
MInstructionReverseIterator MBasicBlock::discardAt(MInstructionReverseIterator &iter) { for (size_t i = 0; i < iter->numOperands(); i++) iter->replaceOperand(i, NULL); return instructions_.removeAt(iter); }
MInstructionReverseIterator MBasicBlock::discardAt(MInstructionReverseIterator &iter) { AssertSafelyDiscardable(*iter); for (size_t i = 0; i < iter->numOperands(); i++) iter->discardOperand(i); return instructions_.removeAt(iter); }
// Instructions are useless if they are unused and have no side effects. // This pass eliminates useless instructions. // The graph itself is unchanged. bool ion::EliminateDeadCode(MIRGenerator *mir, MIRGraph &graph) { // Traverse in postorder so that we hit uses before definitions. // Traverse instruction list backwards for the same reason. for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) { if (mir->shouldCancel("Eliminate Dead Code (main loop)")) return false; // Remove unused instructions. for (MInstructionReverseIterator inst = block->rbegin(); inst != block->rend(); ) { if (!inst->isEffectful() && !inst->hasUses() && !inst->isGuard() && !inst->isControlInstruction()) { inst = block->discardAt(inst); } else { inst++; } } } return true; }