bool IRInstruction::canCSE() const { auto canCSE = opcodeHasFlags(op(), CanCSE); // Make sure that instructions that are CSE'able can't consume reference // counts. assert(!canCSE || !consumesReferences()); return canCSE && !mayReenterHelper(); }
bool IRInstruction::canCSE() const { auto canCSE = opcodeHasFlags(op(), CanCSE); // Make sure that instructions that are CSE'able can't produce a reference // count or consume reference counts. CheckType/AssertType are special // because they can refine a maybeCounted type to a notCounted type, so they // logically consume and produce a reference without doing any work. assert(!canCSE || !consumesReferences() || m_op == CheckType || m_op == AssertType); return canCSE && !mayReenterHelper(); }
bool IRInstruction::mayRaiseError() const { if (!opcodeHasFlags(op(), MayRaiseError)) return false; // Some instructions only throw if they do not have a non-catch label. if (is(LdClsPropAddrCached, LdClsPropAddr) && taken() && !taken()->isCatch()) { return false; } return opcodeHasFlags(op(), MayRaiseError) || mayReenterHelper(); }
bool IRInstruction::isEssential() const { Opcode opc = op(); if (opc == DecRefNZ) { // If the source of a DecRefNZ is not an IncRef, mark it as essential // because we won't remove its source as well as itself. // If the ref count optimization is turned off, mark all DecRefNZ as // essential. if (!RuntimeOption::EvalHHIREnableRefCountOpt || src(0)->inst()->op() != IncRef) { return true; } } return isControlFlow() || opcodeHasFlags(opc, Essential) || mayReenterHelper(); }
bool IRInstruction::mayModifyRefs() const { Opcode opc = op(); // DecRefNZ does not have side effects other than decrementing the ref // count. Therefore, its MayModifyRefs should be false. if (opc == DecRef) { auto type = src(0)->type(); if (isControlFlow()) { // If the decref has a target label, then it exits if the destructor // has to be called, so it does not have any side effects on the main // trace. return false; } if (!type.canRunDtor()) { return false; } } return opcodeHasFlags(opc, MayModifyRefs) || mayReenterHelper(); }
bool IRInstruction::hasMemEffects() const { return opcodeHasFlags(op(), MemEffects) || mayReenterHelper(); }
bool IRInstruction::mayRaiseError() const { return opcodeHasFlags(op(), MayRaiseError) || mayReenterHelper(); }
bool IRInstruction::isEssential() const { return isControlFlow() || opcodeHasFlags(op(), Essential) || mayReenterHelper(); }