diff --git a/auxil/gen-zam b/auxil/gen-zam index 43e49234dc..425223e05c 160000 --- a/auxil/gen-zam +++ b/auxil/gen-zam @@ -1 +1 @@ -Subproject commit 43e49234dcb8b7b7060e3cb1c62e194e759f31a0 +Subproject commit 425223e05c4deb6f8f6e4fa4f7219bf1136271ec diff --git a/src/script_opt/ZAM/AM-Opt.cc b/src/script_opt/ZAM/AM-Opt.cc index 9ca01b0975..29e9d38266 100644 --- a/src/script_opt/ZAM/AM-Opt.cc +++ b/src/script_opt/ZAM/AM-Opt.cc @@ -336,8 +336,8 @@ void ZAMCompiler::ComputeFrameLifetimes() { // Some special-casing. switch ( inst->op ) { - case OP_NEXT_TABLE_ITER_ib: - case OP_NEXT_TABLE_ITER_VAL_VAR_Vib: { + case OP_NEXT_TABLE_ITER_fb: + case OP_NEXT_TABLE_ITER_VAL_VAR_Vfb: { // These assign to an arbitrary long list of variables. auto& iter_vars = inst->aux->loop_vars; auto depth = inst->loop_depth; @@ -361,21 +361,21 @@ void ZAMCompiler::ComputeFrameLifetimes() { } // No need to check the additional "var" associated - // with OP_NEXT_TABLE_ITER_VAL_VAR_Vib as that's + // with OP_NEXT_TABLE_ITER_VAL_VAR_Vfb as that's // a slot-1 assignment. However, similar to other // loop variables, mark this as a usage. - if ( inst->op == OP_NEXT_TABLE_ITER_VAL_VAR_Vib ) + if ( inst->op == OP_NEXT_TABLE_ITER_VAL_VAR_Vfb ) ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); } break; - case OP_NEXT_TABLE_ITER_NO_VARS_ib: break; + case OP_NEXT_TABLE_ITER_NO_VARS_fb: break; - case OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_Vib: { + case OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_Vfb: { auto depth = inst->loop_depth; ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); } break; - case OP_NEXT_VECTOR_ITER_VAL_VAR_VVib: { + case OP_NEXT_VECTOR_ITER_VAL_VAR_VVsb: { CheckSlotAssignment(inst->v2, inst); auto depth = inst->loop_depth; @@ -383,13 +383,13 @@ void ZAMCompiler::ComputeFrameLifetimes() { ExtendLifetime(inst->v2, EndOfLoop(inst, depth)); } break; - case OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_Vib: { + case OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_Vsb: { auto depth = inst->loop_depth; ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); } break; - case OP_NEXT_VECTOR_ITER_Vib: - case OP_NEXT_STRING_ITER_Vib: + case OP_NEXT_VECTOR_ITER_Vsb: + case OP_NEXT_STRING_ITER_Vsb: // Sometimes loops are written that don't actually // use the iteration variable. However, we still // need to mark the variable as having usage @@ -401,12 +401,12 @@ void ZAMCompiler::ComputeFrameLifetimes() { ExtendLifetime(inst->v1, EndOfLoop(inst, inst->loop_depth)); break; - case OP_NEXT_VECTOR_BLANK_ITER_ib: - case OP_NEXT_STRING_BLANK_ITER_ib: break; + case OP_NEXT_VECTOR_BLANK_ITER_sb: + case OP_NEXT_STRING_BLANK_ITER_sb: break; - case OP_INIT_TABLE_LOOP_Vi: - case OP_INIT_VECTOR_LOOP_Vi: - case OP_INIT_STRING_LOOP_Vi: { + case OP_INIT_TABLE_LOOP_Vf: + case OP_INIT_VECTOR_LOOP_Vs: + case OP_INIT_STRING_LOOP_Vs: { // For all of these, the scope of the aggregate being // looped over is the entire loop, even if it doesn't // directly appear in it, and not just the initializer. @@ -549,8 +549,8 @@ void ZAMCompiler::ReMapFrame() { // Handle special cases. switch ( inst->op ) { - case OP_NEXT_TABLE_ITER_ib: - case OP_NEXT_TABLE_ITER_VAL_VAR_Vib: { + case OP_NEXT_TABLE_ITER_fb: + case OP_NEXT_TABLE_ITER_VAL_VAR_Vfb: { // Rewrite iteration variables. auto& iter_vars = inst->aux->loop_vars; for ( auto& v : iter_vars ) { diff --git a/src/script_opt/ZAM/OPs/iterations.op b/src/script_opt/ZAM/OPs/iterations.op index 31bbf255f3..6e9c6744f5 100644 --- a/src/script_opt/ZAM/OPs/iterations.op +++ b/src/script_opt/ZAM/OPs/iterations.op @@ -2,149 +2,124 @@ internal-op Init-Table-Loop op1-read -class Vi +class Vf op-types T I -eval auto& ti = (*tiv_ptr)[$2]; - ti.BeginLoop({NewRef{}, $1}, Z_AUX); +eval $2.BeginLoop({NewRef{}, $1}, Z_AUX); internal-op Next-Table-Iter op1-read -# v1 = iteration info -# v2 = branch target if loop done -class ib +class fb eval NextTableIterPre($1, $2) - ti.NextIter(frame); + $1.NextIter(frame); macro NextTableIterPre(iter, BRANCH) - auto& ti = (*tiv_ptr)[iter]; - if ( ti.IsDoneIterating() ) + if ( iter.IsDoneIterating() ) BRANCH internal-op Next-Table-Iter-No-Vars op1-read -# v1 = iteration info -# v2 = branch target if loop done -class ib +class fb eval NextTableIterPre($1, $2) - ti.IterFinished(); + $1.IterFinished(); internal-op Next-Table-Iter-Val-Var # v1 = slot of the "ValueVar" -# v2 = iteration info -# v3 = branch target if loop done -class Vib +class Vfb eval NextTableIterPre($1, $2) - AssignTarget($$, ti.IterValue()); - ti.NextIter(frame); + AssignTarget($$, $1.IterValue()); + $1.NextIter(frame); internal-op Next-Table-Iter-Val-Var-No-Vars # v1 = slot of the "ValueVar" -# v2 = iteration info -# v3 = branch target if loop done -class Vib +class Vfb eval NextTableIterPre($1, $2) - AssignTarget($$, ti.IterValue()); - ti.IterFinished(); + AssignTarget($$, $1.IterValue()); + $1.IterFinished(); internal-op Init-Vector-Loop op1-read -class Vi +class Vs op-types V I eval auto& vv = $1->RawVec(); - step_iters[$2].InitLoop(&vv); + $2.InitLoop(&vv); macro NextVectorIterCore(info, BRANCH) - auto& si = step_iters[info]; - if ( si.IsDoneIterating() ) + if ( info.IsDoneIterating() ) BRANCH - const auto& vv = *si.vv; - if ( ! vv[si.iter] ) + const auto& vv = *info.vv; + if ( ! vv[info.iter] ) { /* Account for vector hole. Re-execute for next position. */ - si.IterFinished(); + info.IterFinished(); --pc; /* so we then increment to here again */ break; } internal-op Next-Vector-Iter # v1 = iteration variable -# v2 = iteration info -# v3 = branch target if loop done -class Vib +class Vsb op-types U I I eval NextVectorIterCore($1, $2) - $$ = si.iter; - si.IterFinished(); + $$ = $1.iter; + $1.IterFinished(); internal-op Next-Vector-Blank-Iter -# v1 = iteration info -# v2 = branch target if loop done op1-internal -class ib +class sb eval NextVectorIterCore($1, $2) - si.IterFinished(); + $1.IterFinished(); internal-op Next-Vector-Iter-Val-Var # v1 = iteration variable # v2 = value variable -# v3 = iteration info -# v4 = branch target if loop done op1-read-write -class VVib +class VVsb op-types U X I I eval NextVectorIterCore($2, $3) - $$ = si.iter; + $$ = $2.iter; if ( Z_IS_MANAGED ) - $1 = BuildVal(vv[si.iter]->ToVal(Z_TYPE), Z_TYPE); + $1 = BuildVal(vv[$2.iter]->ToVal(Z_TYPE), Z_TYPE); else - $1 = *vv[si.iter]; - si.IterFinished(); + $1 = *vv[$2.iter]; + $2.IterFinished(); internal-op Next-Vector-Blank-Iter-Val-Var # v1 = value variable -# v2 = iteration info -# v3 = branch target if loop done -class Vib +class Vsb eval NextVectorIterCore($1, $2) if ( Z_IS_MANAGED ) - $$ = BuildVal(vv[si.iter]->ToVal(Z_TYPE), Z_TYPE); + $$ = BuildVal(vv[$1.iter]->ToVal(Z_TYPE), Z_TYPE); else - $$ = *vv[si.iter]; - si.IterFinished(); + $$ = *vv[$1.iter]; + $1.IterFinished(); internal-op Init-String-Loop op1-read -classes Vi Ci +classes Vs Cs op-types S I -eval step_iters[$2].InitLoop($1->AsString()); +eval $2.InitLoop($1->AsString()); internal-op Next-String-Iter # v1 = iteration variable -# v2 = iteration info -# v3 = branch target if loop done -class Vib +class Vsb op-types S I I -eval auto& si = step_iters[$1]; - if ( si.IsDoneIterating() ) +eval if ( $1.IsDoneIterating() ) $2 - auto bytes = (const char*) si.s->Bytes() + si.iter; + auto bytes = (const char*) $1.s->Bytes() + $1.iter; auto sv = new StringVal(1, bytes); Unref($$); $$ = sv; - si.IterFinished(); + $1.IterFinished(); internal-op Next-String-Blank-Iter -# v1 = iteration info -# v2 = branch target if loop done op1-internal -class ib -eval auto& si = step_iters[$1]; - if ( si.IsDoneIterating() ) +class sb +eval if ( $1.IsDoneIterating() ) $2 - si.IterFinished(); + $1.IterFinished(); internal-op End-Table-Loop op1-internal -class i -eval (*tiv_ptr)[$1].Clear(); +class f +eval $1.Clear(); diff --git a/src/script_opt/ZAM/OPs/macros.op b/src/script_opt/ZAM/OPs/macros.op index 1dc581dc3d..1a70ff1b12 100644 --- a/src/script_opt/ZAM/OPs/macros.op +++ b/src/script_opt/ZAM/OPs/macros.op @@ -41,3 +41,7 @@ macro AssignTarget(target, v) { macro Branch(target) { DO_ZAM_PROFILE; pc = target; continue; } macro Global(slot) globals[slot] + +macro StepIter(slot) step_iters[slot] + +macro TableIter(slot) (*tiv_ptr)[slot] diff --git a/src/script_opt/ZAM/OpAnaly.cc b/src/script_opt/ZAM/OpAnaly.cc index 9b8be753e3..90b0f3e85a 100644 --- a/src/script_opt/ZAM/OpAnaly.cc +++ b/src/script_opt/ZAM/OpAnaly.cc @@ -32,6 +32,8 @@ static std::map type_pats = { }; int num_valid = 0; +int num_tested = 0; +int num_skipped = 0; void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { auto& oc = zid.op_class; @@ -55,7 +57,9 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { case 'R': op = "frame\\[z\\.v" + std::to_string(++nslot) + "\\]"; break; case 'b': + case 'f': case 'g': + case 's': case 'i': op = "z\\.v" + std::to_string(++nslot); break; case 'C': op = "z\\.c"; break; @@ -68,7 +72,8 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { auto match_pat = op; if ( have_ot ) { auto ot_i = ot[i]; - bool bare_int = oc_i == 'i' || oc_i == 'b' || oc_i == 'g'; + + bool bare_int = std::string("bfgis").find(oc_i) != std::string::npos; if ( ot_i == 'X' || bare_int ) { if ( ot_i == 'X' && bare_int ) @@ -77,6 +82,7 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { if ( ! std::regex_search(eval, std::regex(op)) ) reporter->InternalError("%s: operand %s not found", op_name, op.c_str()); + ++num_skipped; continue; } @@ -84,6 +90,7 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { if ( tp == type_pats.end() ) reporter->InternalError("%s: instruction type %c not found", op_name, ot_i); match_pat += ".(" + tp->second + ")"; + ++num_tested; } if ( ! std::regex_search(eval, std::regex(match_pat)) ) @@ -104,7 +111,7 @@ void analyze_ZAM_insts() { for ( auto& zid : zam_inst_desc ) analyze_ZAM_inst(ZOP_name(zid.first), zid.second); - printf("%d valid\n", num_valid); + printf("%d valid, %d tested, %d skipped\n", num_valid, num_tested, num_skipped); } } // namespace zeek::detail diff --git a/src/script_opt/ZAM/Stmt.cc b/src/script_opt/ZAM/Stmt.cc index 2baadb2dfa..f5af4b7710 100644 --- a/src/script_opt/ZAM/Stmt.cc +++ b/src/script_opt/ZAM/Stmt.cc @@ -777,7 +777,7 @@ const ZAMStmt ZAMCompiler::LoopOverTable(const ForStmt* f, const NameExpr* val) auto iter_slot = table_iters.size(); table_iters.emplace_back(); - auto z = ZInstI(OP_INIT_TABLE_LOOP_Vi, FrameSlot(val), iter_slot); + auto z = ZInstI(OP_INIT_TABLE_LOOP_Vf, FrameSlot(val), iter_slot); z.op_type = OP_VV_I2; z.SetType(value_var ? value_var->GetType() : nullptr); z.aux = aux; @@ -786,13 +786,13 @@ const ZAMStmt ZAMCompiler::LoopOverTable(const ForStmt* f, const NameExpr* val) auto iter_head = StartingBlock(); if ( value_var ) { - ZOp op = no_loop_vars ? OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_Vib : OP_NEXT_TABLE_ITER_VAL_VAR_Vib; + ZOp op = no_loop_vars ? OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_Vfb : OP_NEXT_TABLE_ITER_VAL_VAR_Vfb; z = ZInstI(op, FrameSlot(value_var), iter_slot, 0); z.CheckIfManaged(value_var->GetType()); z.op_type = OP_VVV_I2_I3; } else { - ZOp op = no_loop_vars ? OP_NEXT_TABLE_ITER_NO_VARS_ib : OP_NEXT_TABLE_ITER_ib; + ZOp op = no_loop_vars ? OP_NEXT_TABLE_ITER_NO_VARS_fb : OP_NEXT_TABLE_ITER_fb; z = ZInstI(op, iter_slot, 0); z.op_type = OP_VV_I1_I2; } @@ -809,7 +809,7 @@ const ZAMStmt ZAMCompiler::LoopOverVector(const ForStmt* f, const NameExpr* val) int iter_slot = num_step_iters++; - auto z = ZInstI(OP_INIT_VECTOR_LOOP_Vi, FrameSlot(val), iter_slot); + auto z = ZInstI(OP_INIT_VECTOR_LOOP_Vs, FrameSlot(val), iter_slot); z.op_type = OP_VV_I2; auto init_end = AddInst(z); @@ -819,11 +819,11 @@ const ZAMStmt ZAMCompiler::LoopOverVector(const ForStmt* f, const NameExpr* val) if ( value_var ) { if ( slot >= 0 ) { - z = ZInstI(OP_NEXT_VECTOR_ITER_VAL_VAR_VVib, slot, FrameSlot(value_var), iter_slot, 0); + z = ZInstI(OP_NEXT_VECTOR_ITER_VAL_VAR_VVsb, slot, FrameSlot(value_var), iter_slot, 0); z.op_type = OP_VVVV_I3_I4; } else { - z = ZInstI(OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_Vib, FrameSlot(value_var), iter_slot, 0); + z = ZInstI(OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_Vsb, FrameSlot(value_var), iter_slot, 0); z.op_type = OP_VVV_I2_I3; } @@ -833,11 +833,11 @@ const ZAMStmt ZAMCompiler::LoopOverVector(const ForStmt* f, const NameExpr* val) else { if ( slot >= 0 ) { - z = ZInstI(OP_NEXT_VECTOR_ITER_Vib, slot, iter_slot, 0); + z = ZInstI(OP_NEXT_VECTOR_ITER_Vsb, slot, iter_slot, 0); z.op_type = OP_VVV_I2_I3; } else { - z = ZInstI(OP_NEXT_VECTOR_BLANK_ITER_ib, iter_slot, 0); + z = ZInstI(OP_NEXT_VECTOR_BLANK_ITER_sb, iter_slot, 0); z.op_type = OP_VV_I1_I2; } } @@ -856,12 +856,12 @@ const ZAMStmt ZAMCompiler::LoopOverString(const ForStmt* f, const Expr* e) { ZInstI z; if ( n ) { - z = ZInstI(OP_INIT_STRING_LOOP_Vi, FrameSlot(n), iter_slot); + z = ZInstI(OP_INIT_STRING_LOOP_Vs, FrameSlot(n), iter_slot); z.op_type = OP_VV_I2; } else { ASSERT(c); - z = ZInstI(OP_INIT_STRING_LOOP_Ci, iter_slot, c); + z = ZInstI(OP_INIT_STRING_LOOP_Cs, iter_slot, c); z.op_type = OP_VC_I1; } @@ -869,11 +869,11 @@ const ZAMStmt ZAMCompiler::LoopOverString(const ForStmt* f, const Expr* e) { auto iter_head = StartingBlock(); if ( loop_var->IsBlank() ) { - z = ZInstI(OP_NEXT_STRING_BLANK_ITER_ib, iter_slot, 0); + z = ZInstI(OP_NEXT_STRING_BLANK_ITER_sb, iter_slot, 0); z.op_type = OP_VV_I1_I2; } else { - z = ZInstI(OP_NEXT_STRING_ITER_Vib, FrameSlot(loop_var), iter_slot, 0); + z = ZInstI(OP_NEXT_STRING_ITER_Vsb, FrameSlot(loop_var), iter_slot, 0); z.op_type = OP_VVV_I2_I3; z.is_managed = true; } @@ -903,7 +903,7 @@ const ZAMStmt ZAMCompiler::FinishLoop(const ZAMStmt iter_head, ZInstI& iter_stmt // We only need cleanup for looping over tables, but for now we // need some sort of placeholder instruction (until the optimizer // can elide it) to resolve loop exits. - ZOp op = is_table ? OP_END_TABLE_LOOP_i : OP_NOP; + ZOp op = is_table ? OP_END_TABLE_LOOP_f : OP_NOP; auto loop_end = GoTo(GoToTarget(iter_head)); auto z = ZInstI(op, iter_slot); diff --git a/src/script_opt/ZAM/ZInst.cc b/src/script_opt/ZAM/ZInst.cc index bdd3cbe3d1..26308a6c87 100644 --- a/src/script_opt/ZAM/ZInst.cc +++ b/src/script_opt/ZAM/ZInst.cc @@ -229,16 +229,16 @@ ValPtr ZInst::ConstVal() const { bool ZInst::IsLoopIterationAdvancement() const { switch ( op ) { - case OP_NEXT_TABLE_ITER_ib: - case OP_NEXT_TABLE_ITER_NO_VARS_ib: - case OP_NEXT_TABLE_ITER_VAL_VAR_Vib: - case OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_Vib: - case OP_NEXT_VECTOR_ITER_Vib: - case OP_NEXT_VECTOR_BLANK_ITER_ib: - case OP_NEXT_VECTOR_ITER_VAL_VAR_VVib: - case OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_Vib: - case OP_NEXT_STRING_ITER_Vib: - case OP_NEXT_STRING_BLANK_ITER_ib: return true; + case OP_NEXT_TABLE_ITER_fb: + case OP_NEXT_TABLE_ITER_NO_VARS_fb: + case OP_NEXT_TABLE_ITER_VAL_VAR_Vfb: + case OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_Vfb: + case OP_NEXT_VECTOR_ITER_Vsb: + case OP_NEXT_VECTOR_BLANK_ITER_sb: + case OP_NEXT_VECTOR_ITER_VAL_VAR_VVsb: + case OP_NEXT_VECTOR_BLANK_ITER_VAL_VAR_Vsb: + case OP_NEXT_STRING_ITER_Vsb: + case OP_NEXT_STRING_BLANK_ITER_sb: return true; default: return false; } @@ -281,7 +281,7 @@ bool ZInst::AssignsToSlot1() const { bool ZInst::AssignsToSlot(int slot) const { switch ( op ) { - case OP_NEXT_VECTOR_ITER_VAL_VAR_VVib: return slot == 1 || slot == 2; + case OP_NEXT_VECTOR_ITER_VAL_VAR_VVsb: return slot == 1 || slot == 2; default: return slot == 1 && AssignsToSlot1(); }