fixes for a number of ZAM optimization bugs

This commit is contained in:
Vern Paxson 2023-11-05 16:26:38 -08:00 committed by Arne Welzel
parent 9bfe18473d
commit 1dc74eaa9c
11 changed files with 44 additions and 28 deletions

View file

@ -1468,7 +1468,7 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) {
auto ind1_e = ind_e->Op1()->Reduce(c, ind1_stmt);
auto ind2_e = ind_e->Op2()->Reduce(c, ind2_stmt);
auto rhs_e = op2->Reduce(c, rhs_stmt);
auto rhs_e = op2->ReduceToSingleton(c, rhs_stmt);
red_stmt = MergeStmts(MergeStmts(rhs_reduce, ind1_stmt), ind2_stmt, rhs_stmt);

View file

@ -56,7 +56,7 @@ bool is_lambda(const ScriptFunc* f) { return lambdas.count(f) > 0; }
bool is_when_lambda(const ScriptFunc* f) { return when_lambdas.count(f) > 0; }
const FuncInfo* analyze_global_stmts(Stmt* stmts) {
size_t analyze_global_stmts(Stmt* stmts) {
// We ignore analysis_options.only_{files,funcs} - if they're in use, later
// logic will keep this function from being compiled, but it's handy
// now to enter it into "funcs" so we have a FuncInfo to return.
@ -72,9 +72,11 @@ const FuncInfo* analyze_global_stmts(Stmt* stmts) {
global_stmts->AddBody(stmts->ThisPtr(), empty_inits, sc->Length());
funcs.emplace_back(global_stmts, sc, stmts->ThisPtr(), 0);
return &funcs.back();
return funcs.size() - 1;
}
const FuncInfo& get_global_stmts(size_t global_ind) { return funcs[global_ind]; }
void add_func_analysis_pattern(AnalyOpt& opts, const char* pat) {
try {
std::string full_pat = std::string("^(") + pat + ")$";

View file

@ -171,9 +171,16 @@ extern bool is_lambda(const ScriptFunc* f);
extern bool is_when_lambda(const ScriptFunc* f);
// Analyze the given top-level statement(s) for optimization. Returns
// a pointer to a FuncInfo for an argument-less quasi-function that can
// be Invoked, or its body executed directly, to execute the statements.
extern const FuncInfo* analyze_global_stmts(Stmt* stmts);
// an opaque value that can be provided to get_global_stmts() to retrieve
// the corresponding FuncInfo, which reflects an argument-less quasi-function
// that can be Invoked, or its body executed directly, to execute the
// statements. This indirection is used in case in between the call to
// analyze_global_stmts() and using the value subsequently, the FuncInfo may
// have been updated or shifted. a pointer to a FuncInfo for an argument-less
// quasi-function that can be Invoked, or its body executed directly, to
// execute the statements.
extern size_t analyze_global_stmts(Stmt* stmts);
extern const FuncInfo& get_global_stmts(size_t handle);
// Add a pattern to the "only_funcs" list.
extern void add_func_analysis_pattern(AnalyOpt& opts, const char* pat);

View file

@ -171,7 +171,7 @@ void IfStmt::Inline(Inliner* inl) {
}
bool IfStmt::IsReduced(Reducer* c) const {
if ( ! e->IsReducedConditional(c) )
if ( e->IsConst() || ! e->IsReducedConditional(c) )
return NonReduced(e.get());
return s1->IsReduced(c) && s2->IsReduced(c);
@ -707,7 +707,7 @@ bool StmtList::ReduceStmt(unsigned int& s_i, std::vector<StmtPtr>& f_stmts, Redu
if ( e->Tag() != EXPR_ASSIGN ) {
f_stmts.push_back(std::move(stmt));
return false;
return did_change;
}
auto a = e->AsAssignExpr();
@ -715,7 +715,7 @@ bool StmtList::ReduceStmt(unsigned int& s_i, std::vector<StmtPtr>& f_stmts, Redu
if ( lhs->Tag() != EXPR_NAME ) {
f_stmts.push_back(std::move(stmt));
return false;
return did_change;
}
auto var = lhs->AsNameExpr();

View file

@ -2089,7 +2089,7 @@ macro BuildWhen(timeout)
if ( v )
local_aggrs.push_back(v);
}
(void)make_intrusive<trigger::Trigger>(wi, wi->WhenExprGlobals(), local_aggrs, timeout, f, z.loc);
(void)make_intrusive<trigger::Trigger>(wi, wi->WhenExprGlobals(), local_aggrs, timeout, f, z.loc.get());
########################################
# Internal

View file

@ -77,8 +77,8 @@ void ZAM_run_time_error(const char* msg) {
ZAM_error = true;
}
void ZAM_run_time_error(const Location* loc, const char* msg) {
reporter->RuntimeError(loc, "%s", msg);
void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg) {
reporter->RuntimeError(loc.get(), "%s", msg);
ZAM_error = true;
}
@ -87,12 +87,12 @@ void ZAM_run_time_error(const char* msg, const Obj* o) {
ZAM_error = true;
}
void ZAM_run_time_error(const Location* loc, const char* msg, const Obj* o) {
reporter->RuntimeError(loc, "%s (%s)", msg, obj_desc(o).c_str());
void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg, const Obj* o) {
reporter->RuntimeError(loc.get(), "%s (%s)", msg, obj_desc(o).c_str());
ZAM_error = true;
}
void ZAM_run_time_warning(const Location* loc, const char* msg) {
void ZAM_run_time_warning(std::shared_ptr<Location> loc, const char* msg) {
ODesc d;
loc->Describe(&d);

View file

@ -35,14 +35,14 @@ extern TypePtr log_ID_enum_type;
extern TypePtr any_base_type;
extern void ZAM_run_time_error(const char* msg);
extern void ZAM_run_time_error(const Location* loc, const char* msg);
extern void ZAM_run_time_error(const Location* loc, const char* msg, const Obj* o);
extern void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg);
extern void ZAM_run_time_error(std::shared_ptr<Location> loc, const char* msg, const Obj* o);
extern void ZAM_run_time_error(const Stmt* stmt, const char* msg);
extern void ZAM_run_time_error(const char* msg, const Obj* o);
extern bool ZAM_error;
extern void ZAM_run_time_warning(const Location* loc, const char* msg);
extern void ZAM_run_time_warning(std::shared_ptr<Location> loc, const char* msg);
extern StringVal* ZAM_to_lower(const StringVal* sv);
extern StringVal* ZAM_sub_bytes(const StringVal* s, zeek_uint_t start, zeek_int_t n);

View file

@ -194,8 +194,12 @@ void ZBody::SetInsts(vector<ZInstI*>& instsI) {
for ( auto i = 0U; i < end_pc; ++i ) {
auto& iI = *instsI[i];
insts_copy[i] = iI;
if ( iI.stmt )
insts_copy[i].loc = iI.stmt->Original()->GetLocationInfo();
if ( iI.stmt ) {
auto l = iI.stmt->Original()->GetLocationInfo();
if ( l != &no_location )
insts_copy[i].loc = std::make_shared<Location>(util::copy_string(l->filename), l->first_line,
l->last_line, l->first_column, l->last_column);
}
}
insts = insts_copy;
@ -358,7 +362,8 @@ void ZBody::ProfileExecution() const {
}
}
bool ZBody::CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type, const Location* loc) const {
bool ZBody::CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type,
const std::shared_ptr<Location>& loc) const {
if ( IsAny(expected_type) )
return true;
@ -377,7 +382,7 @@ bool ZBody::CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type,
char buf[8192];
snprintf(buf, sizeof buf, "run-time type clash (%s/%s)", type_name(at), type_name(et));
reporter->RuntimeError(loc, "%s", buf);
reporter->RuntimeError(loc.get(), "%s", buf);
return false;
}

View file

@ -58,7 +58,8 @@ protected:
// Run-time checking for "any" type being consistent with
// expected typed. Returns true if the type match is okay.
bool CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type, const Location* loc) const;
bool CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type,
const std::shared_ptr<Location>& loc) const;
StmtPtr Duplicate() override { return {NewRef{}, this}; }

View file

@ -121,7 +121,7 @@ public:
ZInstAux* aux = nullptr;
// Location associated with this instruction, for error reporting.
const Location* loc = nullptr;
std::shared_ptr<Location> loc;
// Interpreter call expression associated with this instruction,
// for error reporting and stack backtraces.

View file

@ -923,7 +923,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) {
exit(reporter->Errors() != 0);
}
auto init_stmts = stmts ? analyze_global_stmts(stmts) : nullptr;
auto init_stmts_handle = stmts ? analyze_global_stmts(stmts) : 0;
analyze_scripts(options.no_unused_warnings);
@ -1025,13 +1025,14 @@ SetupResult setup(int argc, char** argv, Options* zopts) {
// cause more severe problems.
ZEEK_LSAN_ENABLE();
if ( init_stmts ) {
if ( stmts ) {
auto& init_stmts = get_global_stmts(init_stmts_handle);
StmtFlowType flow;
Frame f(init_stmts->Scope()->Length(), nullptr, nullptr);
Frame f(init_stmts.Scope()->Length(), nullptr, nullptr);
g_frame_stack.push_back(&f);
try {
init_stmts->Body()->Exec(&f, flow);
init_stmts.Body()->Exec(&f, flow);
} catch ( InterpreterException& ) {
reporter->FatalError("failed to execute script statements at top-level scope");
}