mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
helper class checking if common-subexpression elimination opportunity is valid
This commit is contained in:
parent
ec97c9b042
commit
34ccd3e417
2 changed files with 273 additions and 0 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "zeek/Scope.h"
|
||||
#include "zeek/Expr.h"
|
||||
#include "zeek/Stmt.h"
|
||||
#include "zeek/Traverse.h"
|
||||
#include "zeek/script_opt/DefSetsMgr.h"
|
||||
|
||||
namespace zeek::detail {
|
||||
|
@ -214,6 +215,79 @@ protected:
|
|||
const DefSetsMgr* mgr = nullptr;
|
||||
};
|
||||
|
||||
|
||||
// Helper class that walks an AST to determine whether it's safe
|
||||
// to substitute a common subexpression (which at this point is
|
||||
// an assignment to a variable) created using the assignment
|
||||
// expression at position "start_e", at the location specified by
|
||||
// the expression at position "end_e".
|
||||
//
|
||||
// See Reducer::ExprValid for a discussion of what's required
|
||||
// for safety.
|
||||
|
||||
class CSE_ValidityChecker : public TraversalCallback {
|
||||
public:
|
||||
CSE_ValidityChecker(const std::vector<const ID*>& ids,
|
||||
const Expr* start_e, const Expr* end_e);
|
||||
|
||||
TraversalCode PreStmt(const Stmt*) override;
|
||||
TraversalCode PostStmt(const Stmt*) override;
|
||||
TraversalCode PreExpr(const Expr*) override;
|
||||
|
||||
// Returns the ultimate verdict re safety.
|
||||
bool IsValid() const
|
||||
{
|
||||
if ( ! is_valid )
|
||||
return false;
|
||||
|
||||
if ( ! have_end_e )
|
||||
reporter->InternalError("CSE_ValidityChecker: saw start but not end");
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Returns true if an assigment involving the given identifier on
|
||||
// the LHS is in conflict with the given list of identifiers.
|
||||
bool CheckID(const std::vector<const ID*>& ids, const ID* id,
|
||||
bool ignore_orig) const;
|
||||
|
||||
// Returns true if the assignment given by 'e' modifies an aggregate
|
||||
// with the same type as that of one of the identifiers.
|
||||
bool CheckAggrMod(const std::vector<const ID*>& ids,
|
||||
const Expr* e) const;
|
||||
|
||||
// The list of identifiers for which an assignment to one of them
|
||||
// renders the CSE unsafe.
|
||||
const std::vector<const ID*>& ids;
|
||||
|
||||
// Where in the AST to start our analysis. This is the initial
|
||||
// assignment expression.
|
||||
const Expr* start_e;
|
||||
|
||||
// Where in the AST to end our analysis.
|
||||
const Expr* end_e;
|
||||
|
||||
// If what we're analyzing is a record element, then its offset.
|
||||
// -1 if not.
|
||||
int field;
|
||||
|
||||
// The type of that record element, if any.
|
||||
TypePtr field_type;
|
||||
|
||||
// The verdict so far.
|
||||
bool is_valid = true;
|
||||
|
||||
// Whether we've encountered the start/end expression in
|
||||
// the AST traversal.
|
||||
bool have_start_e = false;
|
||||
bool have_end_e = false;
|
||||
|
||||
// Whether analyzed expressions occur in the context of
|
||||
// a statement that modifies an aggregate ("add" or "delete").
|
||||
bool in_aggr_mod_stmt = false;
|
||||
};
|
||||
|
||||
|
||||
extern bool same_DPs(const DefPoints* dp1, const DefPoints* dp2);
|
||||
|
||||
// Used for debugging, to communicate which expression wasn't
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue