enhancements/changes to the Reduce class in preparation for use-defs

This commit is contained in:
Vern Paxson 2021-02-06 09:52:35 -08:00
parent a067f4c5b0
commit 2114c4a26b
2 changed files with 55 additions and 18 deletions

View file

@ -2,10 +2,10 @@
#pragma once #pragma once
#include "zeek/IntrusivePtr.h"
#include "zeek/Scope.h" #include "zeek/Scope.h"
#include "zeek/Expr.h" #include "zeek/Expr.h"
#include "zeek/Stmt.h" #include "zeek/Stmt.h"
#include "zeek/script_opt/DefSetsMgr.h"
namespace zeek::detail { namespace zeek::detail {
@ -23,6 +23,9 @@ public:
return s->Reduce(this); return s->Reduce(this);
} }
const DefSetsMgr* GetDefSetsMgr() const { return mgr; }
void SetDefSetsMgr(const DefSetsMgr* _mgr) { mgr = _mgr; }
ExprPtr GenTemporaryExpr(const TypePtr& t, ExprPtr rhs); ExprPtr GenTemporaryExpr(const TypePtr& t, ExprPtr rhs);
NameExprPtr UpdateName(NameExprPtr n); NameExprPtr UpdateName(NameExprPtr n);
@ -70,25 +73,50 @@ public:
bool IsTemporary(const ID* id) const bool IsTemporary(const ID* id) const
{ return FindTemporary(id) != nullptr; } { return FindTemporary(id) != nullptr; }
// This is a stub for now, since it's not relevant for AST bool IsConstantVar(const ID* id) const
// reduction by itself. However, many of the Reduce methods { return constant_vars.find(id) != constant_vars.end(); }
// ultimately will call this predicate to control how they
// function during the second traversal used to optimize
// the reduced form, so we provide the hook now.
bool Optimizing() const { return false; }
// A stub for now, but ultimately a predicate that indicates whether // True if the Reducer is being used in the context of a second
// a given reduction pass is being made to prune unused statements. // pass over for AST optimization.
bool IsPruning() const { return false; } bool Optimizing() const
{ return ! IsPruning() && mgr != nullptr; }
// A stub for now, ultimately a predicate that returns true if // A predicate that indicates whether a given reduction pass
// the given statement should be removed due to AST optimization. // is being made to prune unused statements.
bool ShouldOmitStmt(const StmtPtr& s) const { return false; } bool IsPruning() const { return omitted_stmts.size() > 0; }
// A stub for now, ultimately provides a replacement for the // A predicate that returns true if the given statement should
// given statement due to AST optimization, or nil if there's // be removed due to AST optimization.
// no replacement. bool ShouldOmitStmt(const Stmt* s) const
StmtPtr ReplacementStmt(const StmtPtr& s) const { return nullptr; } { return omitted_stmts.find(s) != omitted_stmts.end(); }
// Provides a replacement for the given statement due to
// AST optimization, or nil if there's no replacement.
StmtPtr ReplacementStmt(const StmtPtr& s) const
{
auto repl = replaced_stmts.find(s.get());
if ( repl == replaced_stmts.end() )
return nullptr;
else
return repl->second;
}
// Tells the reducer to prune the given statement during the
// next reduction pass.
void AddStmtToOmit(const Stmt* s) { omitted_stmts.insert(s); }
// Tells the reducer to replace the given statement during the
// next reduction pass.
void AddStmtToReplace(const Stmt* s_old, StmtPtr s_new)
{ replaced_stmts[s_old] = s_new; }
// Tells the reducer that it can reclaim the storage associated
// with the omitted statements.
void ResetAlteredStmts()
{
omitted_stmts.clear();
replaced_stmts.clear();
}
// NOT YET IMPLEMENTED, SO CURRENTLY A STUB: // NOT YET IMPLEMENTED, SO CURRENTLY A STUB:
// Given the LHS and RHS of an assignment, returns true // Given the LHS and RHS of an assignment, returns true
@ -162,6 +190,9 @@ protected:
std::unordered_set<ID*> new_locals; std::unordered_set<ID*> new_locals;
std::unordered_map<const ID*, IDPtr> orig_to_new_locals; std::unordered_map<const ID*, IDPtr> orig_to_new_locals;
std::unordered_set<const Stmt*> omitted_stmts;
std::unordered_map<const Stmt*, StmtPtr> replaced_stmts;
// Tracks whether we're inside an inline block, and if so then // Tracks whether we're inside an inline block, and if so then
// how deeply. // how deeply.
int inline_block_level = 0; int inline_block_level = 0;
@ -172,10 +203,16 @@ protected:
// exponentially. // exponentially.
int bifurcation_level = 0; int bifurcation_level = 0;
// Tracks which (non-temporary) variables had constant
// values used for constant propagation.
std::unordered_set<const ID*> constant_vars;
// For a new expression we've created, map it to the expression // For a new expression we've created, map it to the expression
// it's replacing. This allows us to locate the RDs associated // it's replacing. This allows us to locate the RDs associated
// with the usage. // with the usage.
std::unordered_map<const Expr*, const Expr*> new_expr_to_orig; std::unordered_map<const Expr*, const Expr*> new_expr_to_orig;
const DefSetsMgr* mgr = nullptr;
}; };
// Used for debugging, to communicate which expression wasn't // Used for debugging, to communicate which expression wasn't

View file

@ -27,7 +27,7 @@ StmtPtr Stmt::Reduce(Reducer* c)
if ( repl ) if ( repl )
return repl; return repl;
if ( c->ShouldOmitStmt(this_ptr) ) if ( c->ShouldOmitStmt(this) )
{ {
auto null = make_intrusive<NullStmt>(); auto null = make_intrusive<NullStmt>();
null->SetOriginal(this_ptr); null->SetOriginal(this_ptr);