bool checkBlockEnd(const Vunit& unit, Vlabel b) { assertx(!unit.blocks[b].code.empty()); auto& block = unit.blocks[b]; auto n = block.code.size(); for (size_t i = 0; i < n - 1; ++i) { assertx(!isBlockEnd(block.code[i])); } assertx(isBlockEnd(block.code[n - 1])); return true; }
void SCCP::analyzeSSA(Instr* instr) { if (numDefs(instr) == 0) { if (isBlockEnd(instr)) analyzeBranch((BlockEndInstr*)instr); return; } // dev: save current types for later check int i = 0; for (ArrayRange<Def> d = defRange(instr); !d.empty(); d.popFront(), ++i) old_types[i] = type(d.front()); // compute types eval_counts[instr->id]++; analyzer.computeTypes(instr); // dev: check computation result bool changed2 = false; i = 0; for (ArrayRange<Def> d = defRange(instr); !d.empty(); d.popFront(), ++i) { AvmAssert(subtypeof(old_types[i], type(d.front())) && "illegal type narrowing"); changed2 |= *type(d.front()) != *old_types[i]; } if (changed2) { if (enable_typecheck) { printInstr(instr); } addInstrUsers(instr); } }
bool Vout::closed() const { return !empty() && isBlockEnd(m_unit.blocks[m_block].code.back()); }