mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
script optimization fixes for "concretizing" vector-of-any's
This commit is contained in:
parent
fc12ac2b06
commit
bae87fb606
4 changed files with 78 additions and 29 deletions
|
@ -902,6 +902,9 @@ public:
|
||||||
if ( coerce_type )
|
if ( coerce_type )
|
||||||
v = v->AsRecordVal()->CoerceTo(coerce_type);
|
v = v->AsRecordVal()->CoerceTo(coerce_type);
|
||||||
|
|
||||||
|
else if ( init_type->Tag() == TYPE_VECTOR )
|
||||||
|
concretize_if_unspecified(cast_intrusive<VectorVal>(v), init_type->Yield());
|
||||||
|
|
||||||
return ZVal(v, init_type);
|
return ZVal(v, init_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
39
src/Val.cc
39
src/Val.cc
|
@ -1889,19 +1889,23 @@ ValPtr TableVal::Default(const ValPtr& index) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValPtr result;
|
||||||
|
|
||||||
if ( def_val->GetType()->Tag() != TYPE_FUNC || same_type(def_val->GetType(), GetType()->Yield()) ) {
|
if ( def_val->GetType()->Tag() != TYPE_FUNC || same_type(def_val->GetType(), GetType()->Yield()) ) {
|
||||||
if ( def_attr->GetExpr()->IsConst() )
|
if ( def_attr->GetExpr()->IsConst() )
|
||||||
return def_val;
|
return def_val;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return def_val->Clone();
|
result = def_val->Clone();
|
||||||
} catch ( InterpreterException& e ) { /* Already reported. */
|
} catch ( InterpreterException& e ) { /* Already reported. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! result ) {
|
||||||
Error("&default value for table is not clone-able");
|
Error("&default value for table is not clone-able");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
const Func* f = def_val->AsFunc();
|
const Func* f = def_val->AsFunc();
|
||||||
Args vl;
|
Args vl;
|
||||||
|
|
||||||
|
@ -1915,8 +1919,6 @@ ValPtr TableVal::Default(const ValPtr& index) {
|
||||||
else
|
else
|
||||||
vl.emplace_back(index);
|
vl.emplace_back(index);
|
||||||
|
|
||||||
ValPtr result;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result = f->Invoke(&vl);
|
result = f->Invoke(&vl);
|
||||||
}
|
}
|
||||||
|
@ -1928,6 +1930,15 @@ ValPtr TableVal::Default(const ValPtr& index) {
|
||||||
Error("no value returned from &default function");
|
Error("no value returned from &default function");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rt = result->GetType();
|
||||||
|
if ( rt->Tag() == TYPE_VECTOR )
|
||||||
|
// The double-Yield() here is because this is a "table of vector of X"
|
||||||
|
// and we want X. If this is instead a "table of any", that'll be
|
||||||
|
// okay because concretize_if_unspecified() correctly deals with
|
||||||
|
// nil target types.
|
||||||
|
detail::concretize_if_unspecified(cast_intrusive<VectorVal>(result), GetType()->Yield()->Yield());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3474,6 +3485,26 @@ bool VectorVal::Concretize(const TypePtr& t) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void detail::concretize_if_unspecified(VectorValPtr v, TypePtr t) {
|
||||||
|
if ( v->Size() != 0 )
|
||||||
|
// Concretization only applies to empty vectors.
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( v->GetType()->Yield()->Tag() != TYPE_ANY )
|
||||||
|
// It's not an unspecified vector.
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ! t )
|
||||||
|
// "t" can be nil if the vector is being assigned to an "any" value.
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( t->Tag() == TYPE_ANY )
|
||||||
|
// No need to concretize.
|
||||||
|
return;
|
||||||
|
|
||||||
|
v->Concretize(t);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int VectorVal::ComputeFootprint(std::unordered_set<const Val*>* analyzed_vals) const {
|
unsigned int VectorVal::ComputeFootprint(std::unordered_set<const Val*>* analyzed_vals) const {
|
||||||
auto n = vector_val.size();
|
auto n = vector_val.size();
|
||||||
unsigned int fp = n;
|
unsigned int fp = n;
|
||||||
|
|
|
@ -1744,6 +1744,13 @@ namespace detail {
|
||||||
// for normalization. If Func::nil is passed, no normalization happens.
|
// for normalization. If Func::nil is passed, no normalization happens.
|
||||||
extern std::variant<ValPtr, std::string> ValFromJSON(std::string_view json_str, const TypePtr& t,
|
extern std::variant<ValPtr, std::string> ValFromJSON(std::string_view json_str, const TypePtr& t,
|
||||||
const FuncPtr& key_func);
|
const FuncPtr& key_func);
|
||||||
|
|
||||||
|
// If the given vector is an empty vector-of-any ("unspecified"),
|
||||||
|
// concretizes it to the given type. *v* gives the vector and *t* the
|
||||||
|
// type to concretize it to if appropriate. *t* can be nil, in which
|
||||||
|
// case nothing is done.
|
||||||
|
extern void concretize_if_unspecified(VectorValPtr v, TypePtr t);
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
} // namespace zeek
|
} // namespace zeek
|
||||||
|
|
|
@ -124,6 +124,14 @@ StmtPtr Reducer::GenParam(const IDPtr& id, ExprPtr rhs, bool is_modified) {
|
||||||
// the inline block's execution.
|
// the inline block's execution.
|
||||||
is_modified = true;
|
is_modified = true;
|
||||||
|
|
||||||
|
auto& id_t = id->GetType();
|
||||||
|
if ( id_t->Tag() == TYPE_VECTOR && rhs->GetType()->Yield() != id_t->Yield() )
|
||||||
|
// Presumably either the identifier or the RHS is a vector-of-any.
|
||||||
|
// This means there will essentially be a modification of the RHS
|
||||||
|
// due to the need to use (or omit) operations coercing from such
|
||||||
|
// vectors.
|
||||||
|
is_modified = true;
|
||||||
|
|
||||||
if ( ! is_modified ) {
|
if ( ! is_modified ) {
|
||||||
// Can use a temporary variable, which then supports
|
// Can use a temporary variable, which then supports
|
||||||
// optimization via alias propagation.
|
// optimization via alias propagation.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue