Optimize record constructor expression.

We remove the inheritance from UnaryExpression because we know the
type of the operand precisely and can skip a temporary when evaluating
the expression.

#425
This commit is contained in:
Robin Sommer 2020-10-02 14:17:43 +00:00
parent d782c60f19
commit e9aa531b83
2 changed files with 37 additions and 8 deletions

View file

@ -3055,7 +3055,7 @@ void HasFieldExpr::ExprDescribe(ODesc* d) const
}
RecordConstructorExpr::RecordConstructorExpr(ListExprPtr constructor_list)
: UnaryExpr(EXPR_RECORD_CONSTRUCTOR, std::move(constructor_list))
: Expr(EXPR_RECORD_CONSTRUCTOR), op(std::move(constructor_list))
{
if ( IsError() )
return;
@ -3108,22 +3108,30 @@ ValPtr RecordConstructorExpr::InitVal(const zeek::Type* t, ValPtr aggr) const
return nullptr;
}
ValPtr RecordConstructorExpr::Fold(Val* v) const
ValPtr RecordConstructorExpr::Eval(Frame* f) const
{
ListVal* lv = v->AsListVal();
if ( IsError() )
return nullptr;
const auto& exprs = op->Exprs();
auto rt = cast_intrusive<RecordType>(type);
if ( lv->Length() != rt->NumFields() )
if ( exprs.length() != rt->NumFields() )
RuntimeErrorWithCallStack("inconsistency evaluating record constructor");
auto rv = make_intrusive<RecordVal>(std::move(rt));
for ( int i = 0; i < lv->Length(); ++i )
rv->Assign(i, lv->Idx(i));
for ( int i = 0; i < exprs.length(); ++i )
rv->Assign(i, exprs[i]->Eval(f));
return rv;
}
bool RecordConstructorExpr::IsPure() const
{
return op->IsPure();
}
void RecordConstructorExpr::ExprDescribe(ODesc* d) const
{
d->Add("[");
@ -3131,6 +3139,18 @@ void RecordConstructorExpr::ExprDescribe(ODesc* d) const
d->Add("]");
}
TraversalCode RecordConstructorExpr::Traverse(TraversalCallback* cb) const
{
TraversalCode tc = cb->PreExpr(this);
HANDLE_TC_EXPR_PRE(tc);
tc = op->Traverse(cb);
HANDLE_TC_EXPR_PRE(tc);
tc = cb->PostExpr(this);
HANDLE_TC_EXPR_POST(tc);
}
TableConstructorExpr::TableConstructorExpr(ListExprPtr constructor_list,
std::unique_ptr<std::vector<AttrPtr>> arg_attrs,
TypePtr arg_type)

View file

@ -630,16 +630,25 @@ protected:
int field;
};
class RecordConstructorExpr final : public UnaryExpr {
class RecordConstructorExpr final : public Expr {
public:
explicit RecordConstructorExpr(ListExprPtr constructor_list);
~RecordConstructorExpr() override;
ListExpr* Op() const { return op.get(); }
ValPtr Eval(Frame* f) const override;
bool IsPure() const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
ValPtr InitVal(const zeek::Type* t, ValPtr aggr) const override;
ValPtr Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override;
ListExprPtr op;
};
class TableConstructorExpr final : public UnaryExpr {