updates for script optimization

This commit is contained in:
Vern Paxson 2022-03-11 14:35:45 -08:00 committed by Tim Wojtulewicz
parent ae75635c5a
commit 18cfee51c2
3 changed files with 115 additions and 28 deletions

View file

@ -881,34 +881,63 @@ ExprPtr AddToExpr::Duplicate()
return SetSucc(new AddToExpr(op1_d, op2_d)); return SetSucc(new AddToExpr(op1_d, op2_d));
} }
bool AddToExpr::IsReduced(Reducer* c) const
{
auto t = op1->GetType();
auto tag = t->Tag();
if ( tag == TYPE_PATTERN )
return op1->HasReducedOps(c) && op2->IsReduced(c);
if ( tag == TYPE_TABLE )
return op1->IsReduced(c) && op2->IsReduced(c);
if ( tag == TYPE_VECTOR && same_type(t, op2->GetType()) )
return op1->IsReduced(c) && op2->IsReduced(c);
return NonReduced(this);
}
ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
{ {
if ( IsVector(op1->GetType()->Tag()) ) auto tag = op1->GetType()->Tag();
switch ( tag )
{
case TYPE_PATTERN:
case TYPE_TABLE:
case TYPE_VECTOR:
{ {
StmtPtr red_stmt1; StmtPtr red_stmt1;
StmtPtr red_stmt2; StmtPtr red_stmt2;
if ( op1->Tag() == EXPR_FIELD ) if ( tag == TYPE_PATTERN && op1->Tag() == EXPR_FIELD )
red_stmt1 = op1->ReduceToSingletons(c); red_stmt1 = op1->ReduceToSingletons(c);
else else
op1 = op1->Reduce(c, red_stmt1); op1 = op1->Reduce(c, red_stmt1);
auto& t = op1->GetType();
op2 = op2->Reduce(c, red_stmt2); op2 = op2->Reduce(c, red_stmt2);
red_stmt = MergeStmts(red_stmt1, red_stmt2);
if ( tag == TYPE_VECTOR && ! same_type(t, op2->GetType()) )
{
auto append = make_intrusive<AppendToExpr>(op1->Duplicate(), op2); auto append = make_intrusive<AppendToExpr>(op1->Duplicate(), op2);
append->SetOriginal(ThisPtr()); append->SetOriginal(ThisPtr());
auto append_stmt = make_intrusive<ExprStmt>(append); auto append_stmt = make_intrusive<ExprStmt>(append);
red_stmt = MergeStmts(red_stmt1, red_stmt2, append_stmt); red_stmt = MergeStmts(red_stmt, append_stmt);
return op1; return op1;
} }
else return ThisPtr();
}
default:
{ {
// We could do an ASSERT that op1 is an EXPR_REF, but
// the following is basically equivalent.
auto rhs = op1->AsRefExprPtr()->GetOp1(); auto rhs = op1->AsRefExprPtr()->GetOp1();
auto do_incr = make_intrusive<AddExpr>(rhs->Duplicate(), op2); auto do_incr = make_intrusive<AddExpr>(rhs->Duplicate(), op2);
auto assign = make_intrusive<AssignExpr>(op1, do_incr, false, nullptr, nullptr, false); auto assign = make_intrusive<AssignExpr>(op1, do_incr, false, nullptr, nullptr, false);
@ -916,6 +945,14 @@ ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
return assign->ReduceToSingleton(c, red_stmt); return assign->ReduceToSingleton(c, red_stmt);
} }
} }
}
ExprPtr AddToExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt)
{
auto at_stmt = make_intrusive<ExprStmt>(Duplicate());
red_stmt = at_stmt->Reduce(c);
return op1;
}
ExprPtr SubExpr::Duplicate() ExprPtr SubExpr::Duplicate()
{ {
@ -972,15 +1009,43 @@ ExprPtr RemoveFromExpr::Duplicate()
return SetSucc(new RemoveFromExpr(op1_d, op2_d)); return SetSucc(new RemoveFromExpr(op1_d, op2_d));
} }
bool RemoveFromExpr::IsReduced(Reducer* c) const
{
if ( op1->GetType()->Tag() == TYPE_TABLE )
return op1->IsReduced(c) && op2->IsReduced(c);
return NonReduced(this);
}
ExprPtr RemoveFromExpr::Reduce(Reducer* c, StmtPtr& red_stmt) ExprPtr RemoveFromExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
{ {
auto rhs = op1->AsRefExprPtr()->GetOp1(); if ( op1->GetType()->Tag() == TYPE_TABLE )
auto do_decr = make_intrusive<SubExpr>(rhs->Duplicate(), op2); {
StmtPtr red_stmt1;
StmtPtr red_stmt2;
op1 = op1->Reduce(c, red_stmt1);
op2 = op2->Reduce(c, red_stmt2);
red_stmt = MergeStmts(red_stmt1, red_stmt2);
return ThisPtr();
}
auto lhs = op1->AsRefExprPtr()->GetOp1();
auto do_decr = make_intrusive<SubExpr>(lhs->Duplicate(), op2);
auto assign = make_intrusive<AssignExpr>(op1, do_decr, false, nullptr, nullptr, false); auto assign = make_intrusive<AssignExpr>(op1, do_decr, false, nullptr, nullptr, false);
return assign->Reduce(c, red_stmt); return assign->Reduce(c, red_stmt);
} }
ExprPtr RemoveFromExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt)
{
auto rf_stmt = make_intrusive<ExprStmt>(Duplicate());
red_stmt = rf_stmt->Reduce(c);
return op1;
}
ExprPtr TimesExpr::Duplicate() ExprPtr TimesExpr::Duplicate()
{ {
auto op1_d = op1->Duplicate(); auto op1_d = op1->Duplicate();
@ -2676,6 +2741,13 @@ ExprPtr AppendToExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
return ThisPtr(); return ThisPtr();
} }
ExprPtr AppendToExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt)
{
auto at_stmt = make_intrusive<ExprStmt>(Duplicate());
red_stmt = at_stmt->Reduce(c);
return op1->AsRefExprPtr()->GetOp1();
}
IndexAssignExpr::IndexAssignExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3) IndexAssignExpr::IndexAssignExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3)
: BinaryExpr(EXPR_INDEX_ASSIGN, std::move(arg_op1), std::move(arg_op2)) : BinaryExpr(EXPR_INDEX_ASSIGN, std::move(arg_op1), std::move(arg_op2))
{ {

View file

@ -161,7 +161,8 @@ StmtPtr ExprStmt::DoReduce(Reducer* c)
return TransformMe(make_intrusive<NullStmt>(), c); return TransformMe(make_intrusive<NullStmt>(), c);
if ( (t == EXPR_ASSIGN || t == EXPR_CALL || t == EXPR_INDEX_ASSIGN || if ( (t == EXPR_ASSIGN || t == EXPR_CALL || t == EXPR_INDEX_ASSIGN ||
t == EXPR_FIELD_LHS_ASSIGN || t == EXPR_APPEND_TO) && t == EXPR_FIELD_LHS_ASSIGN || t == EXPR_APPEND_TO || t == EXPR_ADD_TO ||
t == EXPR_REMOVE_FROM) &&
e->IsReduced(c) ) e->IsReduced(c) )
return ThisPtr(); return ThisPtr();

View file

@ -466,6 +466,15 @@ UDs UseDefs::ExprUDs(const Expr* e)
AddInExprUDs(uds, e->GetOp1()->AsRefExprPtr()->GetOp1().get()); AddInExprUDs(uds, e->GetOp1()->AsRefExprPtr()->GetOp1().get());
break; break;
case EXPR_ADD_TO:
case EXPR_REMOVE_FROM:
{
AddInExprUDs(uds, e->GetOp1().get());
auto rhs_UDs = ExprUDs(e->GetOp2().get());
uds = UD_Union(uds, rhs_UDs);
break;
}
case EXPR_RECORD_CONSTRUCTOR: case EXPR_RECORD_CONSTRUCTOR:
{ {
auto r = static_cast<const RecordConstructorExpr*>(e); auto r = static_cast<const RecordConstructorExpr*>(e);
@ -527,6 +536,10 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e)
{ {
switch ( e->Tag() ) switch ( e->Tag() )
{ {
case EXPR_REF:
AddInExprUDs(uds, e->GetOp1().get());
break;
case EXPR_NAME: case EXPR_NAME:
AddID(uds, e->AsNameExpr()->Id()); AddID(uds, e->AsNameExpr()->Id());
break; break;
@ -548,8 +561,9 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e)
AddInExprUDs(uds, e->GetOp1()->AsRefExprPtr()->GetOp1().get()); AddInExprUDs(uds, e->GetOp1()->AsRefExprPtr()->GetOp1().get());
break; break;
case EXPR_ASSIGN: case EXPR_ASSIGN: // can occur inside a table constructor
// These occur inside of table constructors. case EXPR_ADD_TO:
case EXPR_REMOVE_FROM:
AddInExprUDs(uds, e->GetOp1().get()); AddInExprUDs(uds, e->GetOp1().get());
AddInExprUDs(uds, e->GetOp2().get()); AddInExprUDs(uds, e->GetOp2().get());
break; break;