WhenStmt/WhenInfo restructuring in support of ZAM "when" statements

This commit is contained in:
Vern Paxson 2023-06-16 16:10:43 -07:00 committed by Arne Welzel
parent 7d5760ac74
commit 1dd2270272
5 changed files with 200 additions and 90 deletions

View file

@ -939,34 +939,85 @@ StmtPtr AssertStmt::DoReduce(Reducer* c)
return make_intrusive<NullStmt>();
}
StmtPtr WhenStmt::Duplicate()
bool WhenInfo::HasUnreducedIDs(Reducer* c) const
{
FuncType::CaptureList* cl_dup = nullptr;
if ( wi->Captures() )
for ( auto& cp : *cl )
{
cl_dup = new FuncType::CaptureList;
*cl_dup = *wi->Captures();
auto cid = cp.Id();
if ( when_new_locals.count(cid.get()) == 0 && ! c->ID_IsReduced(cp.Id()) )
return true;
}
auto new_wi = new WhenInfo(Cond(), cl_dup, IsReturn());
new_wi->AddBody(Body());
new_wi->AddTimeout(TimeoutExpr(), TimeoutBody());
for ( auto& l : when_expr_locals )
if ( ! c->ID_IsReduced(l) )
return true;
return SetSucc(new WhenStmt(wi));
return false;
}
void WhenStmt::Inline(Inliner* inl)
void WhenInfo::UpdateIDs(Reducer* c)
{
// Don't inline, since we currently don't correctly capture
// the frames of closures.
for ( auto& cp : *cl )
{
auto& cid = cp.Id();
if ( when_new_locals.count(cid.get()) == 0 )
cp.SetID(c->UpdateID(cid));
}
for ( auto& l : when_expr_locals )
l = c->UpdateID(l);
}
StmtPtr WhenStmt::Duplicate()
{
return SetSucc(new WhenStmt(new WhenInfo(wi)));
}
bool WhenStmt::IsReduced(Reducer* c) const
{
// We consider these always reduced because they're not
// candidates for any further optimization.
return true;
if ( wi->HasUnreducedIDs(c) )
return false;
if ( ! wi->Lambda()->IsReduced(c) )
return false;
if ( ! wi->TimeoutExpr() )
return true;
return wi->TimeoutExpr()->IsReduced(c);
}
StmtPtr WhenStmt::DoReduce(Reducer* c)
{
if ( ! c->Optimizing() )
{
wi->UpdateIDs(c);
(void)wi->Lambda()->ReduceToSingletons(c);
}
auto e = wi->TimeoutExpr();
if ( ! e )
return ThisPtr();
if ( c->Optimizing() )
wi->SetTimeoutExpr(c->OptExpr(e));
else if ( ! e->IsSingleton(c) )
{
StmtPtr red_e_stmt;
auto new_e = e->ReduceToSingleton(c, red_e_stmt);
wi->SetTimeoutExpr(new_e);
if ( red_e_stmt )
{
auto s = make_intrusive<StmtList>(red_e_stmt, ThisPtr());
return TransformMe(s, c);
}
}
return ThisPtr();
}
CatchReturnStmt::CatchReturnStmt(StmtPtr _block, NameExprPtr _ret_var) : Stmt(STMT_CATCH_RETURN)