bool IRInstruction::storesCell(uint32_t srcIdx) const { switch (m_op) { case StRetVal: case StLoc: case StLocNT: return srcIdx == 1; case StMem: case StMemNT: case StProp: case StPropNT: case StElem: return srcIdx == 2; case ArraySet: case VectorSet: case MapSet: case StableMapSet: return srcIdx == 3; case SpillStack: return srcIdx >= 2 && srcIdx < numSrcs(); case Call: return srcIdx >= 3 && srcIdx < numSrcs(); case CallBuiltin: return srcIdx >= 1 && srcIdx < numSrcs(); default: return false; } }
bool IRInstruction::cseEquals(IRInstruction* inst) const { assert(canCSE()); if (m_op != inst->m_op || m_typeParam != inst->m_typeParam || m_numSrcs != inst->m_numSrcs) { return false; } for (uint32_t i = 0; i < numSrcs(); i++) { if (src(i) != inst->src(i)) { return false; } } if (hasExtra() && !cseEqualsExtra(op(), m_extra, inst->m_extra)) { return false; } /* * Don't CSE on the edges--it's ok to use the destination of some * earlier guarded load even though the instruction we may have * generated here would've exited to a different trace. * * For example, we use this to cse LdThis regardless of its label. */ return true; }
size_t IRInstruction::cseHash() const { assert(canCSE()); size_t srcHash = 0; for (unsigned i = 0; i < numSrcs(); ++i) { srcHash = CSEHash::hashCombine(srcHash, src(i)); } if (hasExtra()) { srcHash = CSEHash::hashCombine(srcHash, cseHashExtra(op(), m_extra)); } return CSEHash::hashCombine(srcHash, m_op, m_typeParam); }
void IRInstruction::addCopy(IRUnit& unit, SSATmp* src, const PhysLoc& dest) { assert(op() == Shuffle); auto data = extra<Shuffle>(); auto n = numSrcs(); assert(n == data->size && n <= data->cap); if (n == data->cap) { auto cap = data->cap * 2; auto srcs = new (unit.arena()) SSATmp*[cap]; auto dests = new (unit.arena()) PhysLoc[cap]; for (unsigned i = 0; i < n; i++) { srcs[i] = m_srcs[i]; dests[i] = data->dests[i]; } m_srcs = srcs; data->dests = dests; data->cap = cap; } m_numSrcs = n + 1; m_srcs[n] = src; data->size = n + 1; data->dests[n] = dest; }
void IRInstruction::setSrc(uint32_t i, SSATmp* newSrc) { always_assert(i < numSrcs()); m_srcs[i] = newSrc; }
SSATmp* IRInstruction::src(uint32_t i) const { always_assert(i < numSrcs()); return m_srcs[i]; }
SSATmp* IRInstruction::src(uint32_t i) const { if (i >= numSrcs()) return nullptr; return m_srcs[i]; }