script optimization support for using strings to index table[pattern] values

This commit is contained in:
Vern Paxson 2023-11-01 11:44:58 +01:00 committed by Arne Welzel
parent fd1094a184
commit 61fcca8482
5 changed files with 81 additions and 5 deletions

View file

@ -388,7 +388,26 @@ string CPPCompile::GenIndexExpr(const Expr* e, GenType gt) {
string func; string func;
if ( aggr_t->Tag() == TYPE_TABLE ) { if ( aggr_t->Tag() == TYPE_TABLE ) {
func = inside_when ? "when_index_table__CPP" : "index_table__CPP"; auto ind_expr = e->GetOp2()->AsListExpr()->Exprs()[0];
auto is_pat_str_ind = false;
auto& indices = aggr_t->AsTableType()->GetIndices()->GetTypes();
if ( indices.size() == 1 && indices[0]->Tag() == TYPE_PATTERN && ind_expr->GetType()->Tag() == TYPE_STRING )
is_pat_str_ind = true;
if ( inside_when ) {
if ( is_pat_str_ind )
func = "when_index_patstr__CPP";
else
func = "when_index_table__CPP";
}
else {
if ( is_pat_str_ind )
func = "index_patstr_table__CPP";
else
func = "index_table__CPP";
}
gen = func + "(" + GenExpr(aggr, GEN_NATIVE) + ", {" + GenExpr(e->GetOp2(), GEN_VAL_PTR) + "})"; gen = func + "(" + GenExpr(aggr, GEN_NATIVE) + ", {" + GenExpr(e->GetOp2(), GEN_VAL_PTR) + "})";
} }

View file

@ -44,6 +44,10 @@ ValPtr index_table__CPP(const TableValPtr& t, vector<ValPtr> indices) {
return v; return v;
} }
ValPtr index_patstr_table__CPP(const TableValPtr& t, vector<ValPtr> indices) {
return t->LookupPattern(indices[0]->AsStringVal());
}
ValPtr index_vec__CPP(const VectorValPtr& vec, int index) { ValPtr index_vec__CPP(const VectorValPtr& vec, int index) {
if ( index < 0 ) if ( index < 0 )
index += vec->Size(); index += vec->Size();
@ -66,6 +70,13 @@ ValPtr when_index_table__CPP(const TableValPtr& t, vector<ValPtr> indices) {
return v; return v;
} }
ValPtr when_index_patstr__CPP(const TableValPtr& t, vector<ValPtr> indices) {
auto v = index_patstr_table__CPP(t, std::move(indices));
if ( v && IndexExprWhen::evaluating > 0 )
IndexExprWhen::results.emplace_back(v);
return v;
}
ValPtr when_index_vec__CPP(const VectorValPtr& vec, int index) { ValPtr when_index_vec__CPP(const VectorValPtr& vec, int index) {
auto v = index_vec__CPP(vec, index); auto v = index_vec__CPP(vec, index);
if ( v && IndexExprWhen::evaluating > 0 ) if ( v && IndexExprWhen::evaluating > 0 )

View file

@ -32,13 +32,16 @@ extern ListValPtr index_val__CPP(std::vector<ValPtr> indices);
// Returns the value corresponding to indexing the given table/vector/string // Returns the value corresponding to indexing the given table/vector/string
// with the given set of indices. These are functions rather than something // with the given set of indices. These are functions rather than something
// generated directly so that they can package up the error handling for // generated directly so that they can package up the error handling for
// the case where there's no such index. // the case where there's no such index. "patstr" refers to indexing a
// table[pattern] of X with a string value.
extern ValPtr index_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices); extern ValPtr index_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
extern ValPtr index_patstr_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
extern ValPtr index_vec__CPP(const VectorValPtr& vec, int index); extern ValPtr index_vec__CPP(const VectorValPtr& vec, int index);
extern ValPtr index_string__CPP(const StringValPtr& svp, std::vector<ValPtr> indices); extern ValPtr index_string__CPP(const StringValPtr& svp, std::vector<ValPtr> indices);
// The same, but for indexing happening inside a "when" clause. // The same, but for indexing happening inside a "when" clause.
extern ValPtr when_index_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices); extern ValPtr when_index_table__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
extern ValPtr when_index_patstr__CPP(const TableValPtr& t, std::vector<ValPtr> indices);
extern ValPtr when_index_vec__CPP(const VectorValPtr& vec, int index); extern ValPtr when_index_vec__CPP(const VectorValPtr& vec, int index);
// For vector slices, we use the existing index_slice(), but we need a // For vector slices, we use the existing index_slice(), but we need a

View file

@ -573,6 +573,19 @@ const ZAMStmt ZAMCompiler::CompileIndex(const NameExpr* n1, int n2_slot, const T
int n = l->Exprs().length(); int n = l->Exprs().length();
auto n2tag = n2t->Tag(); auto n2tag = n2t->Tag();
// Whether this is an instance of indexing a table[pattern] of X
// with a string.
bool is_pat_str_ind = false;
if ( n2tag == TYPE_TABLE && n == 1 ) {
auto& ind_types = n2t->AsTableType()->GetIndices();
auto& ind_type0 = ind_types->GetTypes()[0];
auto ind = l->Exprs()[0];
if ( ind_type0->Tag() == TYPE_PATTERN && ind->GetType()->Tag() == TYPE_STRING )
is_pat_str_ind = true;
}
if ( n == 1 && ! in_when ) { if ( n == 1 && ! in_when ) {
auto ind = l->Exprs()[0]; auto ind = l->Exprs()[0];
auto var_ind = ind->Tag() == EXPR_NAME; auto var_ind = ind->Tag() == EXPR_NAME;
@ -640,7 +653,8 @@ const ZAMStmt ZAMCompiler::CompileIndex(const NameExpr* n1, int n2_slot, const T
if ( n2tag == TYPE_TABLE ) { if ( n2tag == TYPE_TABLE ) {
if ( n3 ) { if ( n3 ) {
int n3_slot = FrameSlot(n3); int n3_slot = FrameSlot(n3);
auto zop = AssignmentFlavor(OP_TABLE_INDEX1_VVV, n1->GetType()->Tag()); auto op = is_pat_str_ind ? OP_TABLE_PATSTR_INDEX1_VVV : OP_TABLE_INDEX1_VVV;
auto zop = AssignmentFlavor(op, n1->GetType()->Tag());
z = ZInstI(zop, Frame1Slot(n1, zop), n2_slot, n3_slot); z = ZInstI(zop, Frame1Slot(n1, zop), n2_slot, n3_slot);
z.SetType(n3->GetType()); z.SetType(n3->GetType());
} }
@ -648,7 +662,8 @@ const ZAMStmt ZAMCompiler::CompileIndex(const NameExpr* n1, int n2_slot, const T
else { else {
ASSERT(c3); ASSERT(c3);
auto zop = AssignmentFlavor(OP_TABLE_INDEX1_VVC, n1->GetType()->Tag()); auto op = is_pat_str_ind ? OP_TABLE_PATSTR_INDEX1_VVC : OP_TABLE_INDEX1_VVC;
auto zop = AssignmentFlavor(op, n1->GetType()->Tag());
z = ZInstI(zop, Frame1Slot(n1, zop), n2_slot, c3); z = ZInstI(zop, Frame1Slot(n1, zop), n2_slot, c3);
} }
@ -674,7 +689,15 @@ const ZAMStmt ZAMCompiler::CompileIndex(const NameExpr* n1, int n2_slot, const T
break; break;
case TYPE_TABLE: case TYPE_TABLE:
op = in_when ? OP_WHEN_TABLE_INDEX_VV : OP_TABLE_INDEX_VV; if ( in_when ) {
if ( is_pat_str_ind )
op = OP_WHEN_PATSTR_INDEX_VV;
else
op = OP_WHEN_TABLE_INDEX_VV;
}
else
op = OP_TABLE_INDEX_VV;
z = ZInstI(op, Frame1Slot(n1, op), n2_slot); z = ZInstI(op, Frame1Slot(n1, op), n2_slot);
z.SetType(n1->GetType()); z.SetType(n1->GetType());
break; break;

View file

@ -1057,6 +1057,15 @@ macro EvalTableIndex(index)
break; break;
} }
internal-op When-PatStr-Index
type VV
eval auto args = z.aux->ToListVal(frame);
auto arg0 = args->Idx(0);
auto v = frame[z.v2].table_val->LookupPattern(arg0->AsStringVal());
if ( IndexExprWhen::evaluating > 0 )
IndexExprWhen::results.emplace_back(v);
AssignV1(BuildVal(v, z.t))
internal-assignment-op Table-Index1 internal-assignment-op Table-Index1
type VVV type VVV
assign-val v assign-val v
@ -1068,6 +1077,17 @@ type VVC
assign-val v assign-val v
eval EvalTableIndex(z.c.ToVal(z.t)) eval EvalTableIndex(z.c.ToVal(z.t))
# Same, but for indexing table[pattern] of X with a string.
internal-assignment-op Table-PatStr-Index1
type VVV
assign-val v
eval auto v = frame[z.v2].table_val->LookupPattern(frame[z.v3].AsString());
internal-assignment-op Table-PatStr-Index1
type VVC
assign-val v
eval auto v = frame[z.v2].table_val->LookupPattern(z.c.AsString());
# This version is for a variable v3. # This version is for a variable v3.
internal-op Index-String internal-op Index-String
type VVV type VVV