ZAM fixes for "for" loops that are only used to choose an element from a table/set

This commit is contained in:
Vern Paxson 2024-01-10 18:42:36 -08:00 committed by Arne Welzel
parent d1dffd3e1b
commit 6660738b7d
3 changed files with 30 additions and 9 deletions

View file

@ -158,16 +158,16 @@ bool ZAMCompiler::RemoveDeadCode() {
} }
if ( t && t->inst_num > i0->inst_num && (! i1 || t->inst_num <= i1->inst_num) ) { if ( t && t->inst_num > i0->inst_num && (! i1 || t->inst_num <= i1->inst_num) ) {
// This is effectively a branch to the next // This is effectively a branch to the next instruction.
// instruction. Even if i0 is conditional, there's // We can remove it *unless* the instruction has side effects.
// no point executing it because regardless of the // Conditionals don't, but loop-iteration-advancement
// outcome of the conditional, we go to the next // instructions do.
// successive live instruction (and we don't have if ( ! i0->IsLoopIterationAdvancement() ) {
// conditionals with side effects).
KillInst(i0); KillInst(i0);
did_removal = true; did_removal = true;
continue; continue;
} }
}
if ( i0->DoesNotContinue() && i1 && i1->num_labels == 0 ) { if ( i0->DoesNotContinue() && i1 && i1->num_labels == 0 ) {
// i1 can't be reached - nor anything unlabeled // i1 can't be reached - nor anything unlabeled

View file

@ -214,6 +214,23 @@ ValPtr ZInst::ConstVal() const {
return nullptr; return nullptr;
} }
bool ZInst::IsLoopIterationAdvancement() const {
switch ( op ) {
case OP_NEXT_TABLE_ITER_VV:
case OP_NEXT_TABLE_ITER_NO_VARS_VV:
case OP_NEXT_TABLE_ITER_VAL_VAR_VVV:
case OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_VVV:
case OP_NEXT_VECTOR_ITER_VVV:
case OP_NEXT_VECTOR_BLANK_ITER_VV:
case OP_NEXT_VECTOR_ITER_VAL_VAR_VVVV:
case OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_VVV:
case OP_NEXT_STRING_ITER_VVV:
case OP_NEXT_STRING_BLANK_ITER_VV: return true;
default: return false;
}
}
string ZInst::ConstDump() const { string ZInst::ConstDump() const {
auto v = ConstVal(); auto v = ConstVal();

View file

@ -88,6 +88,10 @@ public:
// Returns nil if this instruction doesn't have an associated constant. // Returns nil if this instruction doesn't have an associated constant.
ValPtr ConstVal() const; ValPtr ConstVal() const;
// Returns true if this instruction represents a form of advancing
// a loop iteration, false otherwise.
bool IsLoopIterationAdvancement() const;
// Returns a string describing the constant. // Returns a string describing the constant.
std::string ConstDump() const; std::string ConstDump() const;