diff --git a/src/Expr.cc b/src/Expr.cc index 049c0981dd..31e3bedeb0 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -249,18 +249,6 @@ NameExpr::~NameExpr() Unref(id); } -Expr* NameExpr::Simplify(SimplifyType simp_type) - { - if ( simp_type != SIMPLIFY_LHS && id->IsConst() ) - { - Val* v = Eval(0); - if ( v ) - return new ConstExpr(v); - } - - return this; - } - Val* NameExpr::Eval(Frame* f) const { Val* v; @@ -410,11 +398,6 @@ void ConstExpr::ExprDescribe(ODesc* d) const val->Describe(d); } -Expr* ConstExpr::Simplify(SimplifyType /* simp_type */) - { - return this; - } - Val* ConstExpr::Eval(Frame* /* f */) const { return Value()->Ref(); @@ -457,16 +440,6 @@ UnaryExpr::~UnaryExpr() Unref(op); } -Expr* UnaryExpr::Simplify(SimplifyType simp_type) - { - if ( IsError() ) - return this; - - op = simplify_expr(op, simp_type); - Canonicize(); - return DoSimplify(); - } - Val* UnaryExpr::Eval(Frame* f) const { if ( IsError() ) @@ -516,11 +489,6 @@ TraversalCode UnaryExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -Expr* UnaryExpr::DoSimplify() - { - return this; - } - Val* UnaryExpr::Fold(Val* v) const { return v->Ref(); @@ -573,19 +541,6 @@ BinaryExpr::~BinaryExpr() Unref(op2); } -Expr* BinaryExpr::Simplify(SimplifyType /* simp_type */) - { - if ( IsError() ) - return this; - - SimplifyOps(); - - if ( BothConst() ) - return new ConstExpr(Fold(op1->ExprVal(), op2->ExprVal())); - else - return DoSimplify(); - } - Val* BinaryExpr::Eval(Frame* f) const { if ( IsError() ) @@ -687,11 +642,6 @@ TraversalCode BinaryExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } -Expr* BinaryExpr::DoSimplify() - { - return this; - } - void BinaryExpr::ExprDescribe(ODesc* d) const { op1->Describe(d); @@ -703,13 +653,6 @@ void BinaryExpr::ExprDescribe(ODesc* d) const op2->Describe(d); } -void BinaryExpr::SimplifyOps() - { - op1 = simplify_expr(op1, SIMPLIFY_GENERAL); - op2 = simplify_expr(op2, SIMPLIFY_GENERAL); - Canonicize(); - } - Val* BinaryExpr::Fold(Val* v1, Val* v2) const { InternalTypeTag it = v1->Type()->InternalType(); @@ -1147,21 +1090,6 @@ NotExpr::NotExpr(Expr* arg_op) : UnaryExpr(EXPR_NOT, arg_op) SetType(base_type(TYPE_BOOL)); } -Expr* NotExpr::DoSimplify() - { - op = simplify_expr(op, SIMPLIFY_GENERAL); - Canonicize(); - - if ( op->Tag() == EXPR_NOT ) - // !!x == x - return ((NotExpr*) op)->Op()->Ref(); - - if ( op->IsConst() ) - return new ConstExpr(Fold(op->ExprVal())); - - return this; - } - Val* NotExpr::Fold(Val* v) const { return new Val(! v->InternalInt(), type->Tag()); @@ -1207,22 +1135,6 @@ PosExpr::PosExpr(Expr* arg_op) : UnaryExpr(EXPR_POSITIVE, arg_op) SetType(base_result_type); } -Expr* PosExpr::DoSimplify() - { - op = simplify_expr(op, SIMPLIFY_GENERAL); - Canonicize(); - - TypeTag t = op->Type()->Tag(); - - if ( t == TYPE_DOUBLE || t == TYPE_INTERVAL || t == TYPE_INT ) - return op->Ref(); - - if ( op->IsConst() && ! is_vector(op->ExprVal()) ) - return new ConstExpr(Fold(op->ExprVal())); - - return this; - } - Val* PosExpr::Fold(Val* v) const { TypeTag t = v->Type()->Tag(); @@ -1273,27 +1185,6 @@ NegExpr::NegExpr(Expr* arg_op) : UnaryExpr(EXPR_NEGATE, arg_op) SetType(base_result_type); } -Expr* NegExpr::DoSimplify() - { - op = simplify_expr(op, SIMPLIFY_GENERAL); - Canonicize(); - - if ( op->Tag() == EXPR_NEGATE ) - // -(-x) == x - return ((NegExpr*) op)->Op()->Ref(); - - if ( op->IsConst() && ! is_vector(op->ExprVal()) ) - return new ConstExpr(Fold(op->ExprVal())); - - if ( op->Tag() == EXPR_SUB ) - { // -(a-b) == b-a - SubExpr* s = (SubExpr*) op; - return new SubExpr(s->Op2()->Ref(), s->Op1()->Ref()); - } - - return this; - } - Val* NegExpr::Fold(Val* v) const { if ( v->Type()->Tag() == TYPE_DOUBLE ) @@ -1396,24 +1287,6 @@ AddExpr::AddExpr(Expr* arg_op1, Expr* arg_op2) } } -Expr* AddExpr::DoSimplify() - { - // If there's a constant, then it's in op1, since Canonicize() - // makes sure of that. - if ( op1->IsZero() ) - return op2->Ref(); - - else if ( op1->Tag() == EXPR_NEGATE ) - // (-a)+b = b-a - return new AddExpr(op2->Ref(), ((NegExpr*) op1)->Op()->Ref()); - - else if ( op2->Tag() == EXPR_NEGATE ) - // a+(-b) == a-b - return new SubExpr(op1->Ref(), ((NegExpr*) op2)->Op()->Ref()); - - return this; - } - void AddExpr::Canonicize() { if ( expr_greater(op2, op1) || @@ -1532,21 +1405,6 @@ SubExpr::SubExpr(Expr* arg_op1, Expr* arg_op2) } } -Expr* SubExpr::DoSimplify() - { - if ( op1->IsZero() ) - return new NegExpr(op2->Ref()); - - else if ( op2->IsZero() ) - return op1->Ref(); - - else if ( op2->Tag() == EXPR_NEGATE ) - // a-(-b) = a+b - return new AddExpr(op1->Ref(), ((NegExpr*) op2)->Op()->Ref()); - - return this; - } - IMPLEMENT_SERIAL(SubExpr, SER_SUB_EXPR); bool SubExpr::DoSerialize(SerialInfo* info) const @@ -1648,27 +1506,6 @@ TimesExpr::TimesExpr(Expr* arg_op1, Expr* arg_op2) ExprError("requires arithmetic operands"); } -Expr* TimesExpr::DoSimplify() - { - // If there's a constant, then it's in op1, since Canonicize() - // makes sure of that. - if ( op1->IsConst() ) - { - if ( op1->IsZero() ) - { - if ( IsVector(op2->Type()->Tag()) ) - return this; - else - return make_zero(type); - } - - else if ( op1->IsOne() ) - return op2->Ref(); - } - - return this; - } - void TimesExpr::Canonicize() { if ( expr_greater(op2, op1) || op2->Type()->Tag() == TYPE_INTERVAL || @@ -1741,31 +1578,6 @@ Val* DivideExpr::AddrFold(Val* v1, Val* v2) const return new SubNetVal(v1->AsAddr(), mask); } -Expr* DivideExpr::DoSimplify() - { - if ( IsError() ) - return this; - - if ( op1->Type()->Tag() == TYPE_ADDR ) - return this; - - if ( is_vector(op1) || is_vector(op2) ) - return this; - - if ( op2->IsConst() ) - { - if ( op2->IsOne() ) - return op1->Ref(); - else if ( op2->IsZero() ) - Error("zero divisor"); - } - - else if ( same_expr(op1, op2) ) - return make_one(type); - - return this; - } - IMPLEMENT_SERIAL(DivideExpr, SER_DIVIDE_EXPR); bool DivideExpr::DoSerialize(SerialInfo* info) const @@ -1800,31 +1612,6 @@ ModExpr::ModExpr(Expr* arg_op1, Expr* arg_op2) ExprError("requires integral operands"); } -Expr* ModExpr::DoSimplify() - { - if ( IsError() ) - return this; - - TypeTag bt1 = op1->Type()->Tag(); - TypeTag bt2 = op2->Type()->Tag(); - - if ( IsVector(bt1) || IsVector(bt2) ) - return this; - - if ( op2->IsConst() ) - { - if ( op2->IsOne() ) - return make_zero(type); - else if ( op2->IsZero() ) - Error("zero modulus"); - } - - else if ( same_expr(op1, op2) ) - return make_zero(type); - - return this; - } - IMPLEMENT_SERIAL(ModExpr, SER_MOD_EXPR); bool ModExpr::DoSerialize(SerialInfo* info) const @@ -2011,37 +1798,6 @@ Val* BoolExpr::Eval(Frame* f) const return result; } -Expr* BoolExpr::DoSimplify() - { - if ( op1->IsConst() && ! is_vector(op1) ) - { - if ( op1->IsZero() ) - // F && x or F || x - return (tag == EXPR_AND) ? make_zero(type) : op2->Ref(); - else - // T && x or T || x - return (tag == EXPR_AND) ? op2->Ref() : make_one(type); - } - - else if ( op2->IsConst() && ! is_vector(op2) ) - { - if ( op1->IsZero() ) - // x && F or x || F - return (tag == EXPR_AND) ? make_zero(type) : op1->Ref(); - else - // x && T or x || T - return (tag == EXPR_AND) ? op1->Ref() : make_one(type); - } - - else if ( same_expr(op1, op2) ) - { - Warn("redundant boolean operation"); - return op1->Ref(); - } - - return this; - } - IMPLEMENT_SERIAL(BoolExpr, SER_BOOL_EXPR); bool BoolExpr::DoSerialize(SerialInfo* info) const @@ -2128,22 +1884,6 @@ void EqExpr::Canonicize() SwapOps(); } -Expr* EqExpr::DoSimplify() - { - if ( same_expr(op1, op2) && ! is_vector(op1) ) - { - if ( ! optimize ) - Warn("redundant comparison"); - - if ( tag == EXPR_EQ ) - return make_one(type); - else - return make_zero(type); - } - - return this; - } - Val* EqExpr::Fold(Val* v1, Val* v2) const { if ( op1->Type()->Tag() == TYPE_PATTERN ) @@ -2207,22 +1947,6 @@ RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2) ExprError("illegal comparison"); } -Expr* RelExpr::DoSimplify() - { - if ( same_expr(op1, op2) ) - { - Warn("redundant comparison"); - // Here we use the fact that the canonical form of - // a RelExpr only uses EXPR_LE or EXPR_LT. - if ( tag == EXPR_LE ) - return make_one(type); - else - return make_zero(type); - } - - return this; - } - void RelExpr::Canonicize() { if ( tag == EXPR_GT ) @@ -2314,25 +2038,6 @@ CondExpr::~CondExpr() Unref(op3); } -Expr* CondExpr::Simplify(SimplifyType /* simp_type */) - { - op1 = simplify_expr(op1, SIMPLIFY_GENERAL); - op2 = simplify_expr(op2, SIMPLIFY_GENERAL); - op3 = simplify_expr(op3, SIMPLIFY_GENERAL); - - if ( op1->IsConst() && ! is_vector(op1) ) - { - Val* v = op1->ExprVal(); - return (v->IsZero() ? op3 : op2)->Ref(); - } - - if ( op1->Tag() == EXPR_NOT ) - return new CondExpr(((NotExpr*) op1)->Op()->Ref(), - op3->Ref(), op2->Ref()); - - return this; - } - Val* CondExpr::Eval(Frame* f) const { if ( ! is_vector(op1) ) @@ -2684,13 +2389,6 @@ bool AssignExpr::TypeCheckArithmetics(TypeTag bt1, TypeTag bt2) } -Expr* AssignExpr::Simplify(SimplifyType /* simp_type */) - { - op1 = simplify_expr(op1, SIMPLIFY_LHS); - op2 = simplify_expr(op2, SIMPLIFY_GENERAL); - return this; - } - Val* AssignExpr::Eval(Frame* f) const { if ( is_init ) @@ -3006,13 +2704,6 @@ Expr* IndexExpr::MakeLvalue() return new RefExpr(this); } -Expr* IndexExpr::Simplify(SimplifyType simp_type) - { - op1 = simplify_expr(op1, simp_type); - op2 = simplify_expr(op2, SIMPLIFY_GENERAL); - return this; - } - Val* IndexExpr::Eval(Frame* f) const { Val* v1 = op1->Eval(f); @@ -3264,12 +2955,6 @@ Expr* FieldExpr::MakeLvalue() return new RefExpr(this); } -Expr* FieldExpr::Simplify(SimplifyType simp_type) - { - op = simplify_expr(op, simp_type); - return this; - } - int FieldExpr::CanDel() const { return td->FindAttr(ATTR_DEFAULT) || td->FindAttr(ATTR_OPTIONAL); @@ -3995,73 +3680,6 @@ ArithCoerceExpr::ArithCoerceExpr(Expr* arg_op, TypeTag t) ExprError("bad coercion value"); } -Expr* ArithCoerceExpr::DoSimplify() - { - if ( is_vector(op) ) - return this; - - InternalTypeTag my_int = type->InternalType(); - InternalTypeTag op_int = op->Type()->InternalType(); - - if ( my_int == TYPE_INTERNAL_UNSIGNED ) - my_int = TYPE_INTERNAL_INT; - if ( op_int == TYPE_INTERNAL_UNSIGNED ) - op_int = TYPE_INTERNAL_INT; - - if ( my_int == op_int ) - return op->Ref(); - - if ( op->IsConst() ) - { - if ( my_int == TYPE_INTERNAL_INT ) - { - if ( op_int != TYPE_INTERNAL_DOUBLE ) - Internal("bad coercion in CoerceExpr::DoSimplify"); - double d = op->ExprVal()->InternalDouble(); - bro_int_t i = bro_int_t(d); - - if ( i < 0 && - type->InternalType() == TYPE_INTERNAL_UNSIGNED ) - Warn("coercion produces negative count value"); - - if ( d != double(i) ) - Warn("coercion loses precision"); - - return new ConstExpr(new Val(i, type->Tag())); - } - - if ( my_int == TYPE_INTERNAL_DOUBLE ) - { - if ( op_int == TYPE_INTERNAL_INT ) - { - bro_int_t i = op->ExprVal()->InternalInt(); - double d = double(i); - - if ( i != bro_int_t(d) ) - Warn("coercion loses precision"); - - return new ConstExpr(new Val(d, type->Tag())); - } - - if ( op_int == TYPE_INTERNAL_UNSIGNED ) - { - bro_uint_t u = op->ExprVal()->InternalUnsigned(); - double d = double(u); - - if ( u != (bro_uint_t) (d) ) - Warn("coercion loses precision"); - - return new ConstExpr(new Val(d, type->Tag())); - } - - } - - Internal("bad coercion in CoerceExpr::DoSimplify"); - } - - return this; - } - Val* ArithCoerceExpr::FoldSingleVal(Val* v, InternalTypeTag t) const { switch ( t ) { @@ -4550,22 +4168,6 @@ int ScheduleExpr::IsPure() const return 0; } -Expr* ScheduleExpr::Simplify(SimplifyType simp_type) - { - when = when->Simplify(simp_type); - Expr* generic_event = event->Simplify(simp_type); - - if ( ! generic_event ) - return 0; - - if ( generic_event->Tag() != EXPR_CALL ) - Internal("bad event type in ScheduleExpr::Simplify"); - - event = (EventExpr*) generic_event; - - return this; - } - Val* ScheduleExpr::Eval(Frame* f) const { if ( terminating ) @@ -4898,20 +4500,6 @@ int CallExpr::IsPure() const return pure; } -Expr* CallExpr::Simplify(SimplifyType /* simp_type */) - { - if ( IsError() ) - return this; - - func = simplify_expr(func, SIMPLIFY_GENERAL); - args = simplify_expr_list(args, SIMPLIFY_GENERAL); - - if ( IsPure() ) - return new ConstExpr(Eval(0)); - else - return this; - } - Val* CallExpr::Eval(Frame* f) const { if ( IsError() ) @@ -5064,14 +4652,6 @@ EventExpr::~EventExpr() Unref(args); } -Expr* EventExpr::Simplify(SimplifyType /* simp_type */) - { - if ( ! IsError() ) - args = simplify_expr_list(args, SIMPLIFY_GENERAL); - - return this; - } - Val* EventExpr::Eval(Frame* f) const { if ( IsError() ) @@ -5178,17 +4758,6 @@ int ListExpr::AllConst() const return 1; } -Expr* ListExpr::Simplify(SimplifyType /* simp_type */) - { - loop_over_list(exprs, i) - exprs.replace(i, simplify_expr(exprs[i], SIMPLIFY_GENERAL)); - - // Note that we do *not* simplify a list with one element - // to just that element. The assumption that simplify_expr(ListExpr*) - // returns a ListExpr* is widespread. - return this; - } - Val* ListExpr::Eval(Frame* f) const { ListVal* v = new ListVal(TYPE_ANY); @@ -5820,25 +5389,6 @@ int check_and_promote_exprs_to_type(ListExpr*& elements, BroType* type) return 1; } -Expr* simplify_expr(Expr* e, SimplifyType simp_type) - { - if ( ! e ) - return 0; - - for ( Expr* s = e->Simplify(simp_type); s != e; s = e->Simplify(simp_type) ) - { - Unref(e); - e = s; - } - - return e; - } - -ListExpr* simplify_expr_list(ListExpr* l, SimplifyType simp_type) - { - return (ListExpr*) simplify_expr(l, simp_type); - } - val_list* eval_list(Frame* f, const ListExpr* l) { const expr_list& e = l->Exprs(); @@ -5864,129 +5414,6 @@ val_list* eval_list(Frame* f, const ListExpr* l) return v; } -int same_expr(const Expr* e1, const Expr* e2) - { - if ( e1 == e2 ) - return 1; - - if ( e1->Tag() != e2->Tag() || ! same_type(e1->Type(), e2->Type()) ) - return 0; - - if ( e1->IsError() || e2->IsError() ) - return 0; - - switch ( e1->Tag() ) { - case EXPR_NAME: - { - const NameExpr* n1 = (NameExpr*) e1; - const NameExpr* n2 = (NameExpr*) e2; - return n1->Id() == n2->Id(); - } - - case EXPR_CONST: - { - const ConstExpr* c1 = (ConstExpr*) e1; - const ConstExpr* c2 = (ConstExpr*) e2; - return same_val(c1->Value(), c2->Value()); - } - - case EXPR_INCR: - case EXPR_DECR: - case EXPR_NOT: - case EXPR_NEGATE: - case EXPR_POSITIVE: - case EXPR_REF: - case EXPR_RECORD_CONSTRUCTOR: - case EXPR_TABLE_CONSTRUCTOR: - case EXPR_SET_CONSTRUCTOR: - case EXPR_VECTOR_CONSTRUCTOR: - case EXPR_FIELD_ASSIGN: - case EXPR_ARITH_COERCE: - case EXPR_RECORD_COERCE: - case EXPR_TABLE_COERCE: - case EXPR_FLATTEN: - { - const UnaryExpr* u1 = (UnaryExpr*) e1; - const UnaryExpr* u2 = (UnaryExpr*) e2; - return same_expr(u1->Op(), u2->Op()); - } - - case EXPR_FIELD: - { - const FieldExpr* f1 = (FieldExpr*) e1; - const FieldExpr* f2 = (FieldExpr*) e2; - return same_expr(f1->Op(), f2->Op()) && - f1->Field() == f2->Field(); - } - - case EXPR_SCHEDULE: - { - const ScheduleExpr* s1 = (ScheduleExpr*) e1; - const ScheduleExpr* s2 = (ScheduleExpr*) e2; - return same_expr(s1->When(), s2->When()) && - same_expr(s1->Event(), s2->Event()); - } - - case EXPR_ADD: - case EXPR_ADD_TO: - case EXPR_SUB: - case EXPR_REMOVE_FROM: - case EXPR_TIMES: - case EXPR_DIVIDE: - case EXPR_MOD: - case EXPR_AND: - case EXPR_OR: - case EXPR_LT: - case EXPR_LE: - case EXPR_EQ: - case EXPR_NE: - case EXPR_GE: - case EXPR_GT: - case EXPR_ASSIGN: - case EXPR_MATCH: - case EXPR_INDEX: - case EXPR_IN: - { - const BinaryExpr* b1 = (BinaryExpr*) e1; - const BinaryExpr* b2 = (BinaryExpr*) e2; - return same_expr(b1->Op1(), b2->Op1()) && - same_expr(b1->Op2(), b2->Op2()); - } - - case EXPR_LIST: - { - const ListExpr* l1 = (ListExpr*) e1; - const ListExpr* l2 = (ListExpr*) e2; - - const expr_list& le1 = l1->Exprs(); - const expr_list& le2 = l2->Exprs(); - - if ( le1.length() != le2.length() ) - return 0; - - loop_over_list(le1, i) - if ( ! same_expr(le1[i], le2[i]) ) - return 0; - - return 1; - } - - case EXPR_CALL: - { - const CallExpr* c1 = (CallExpr*) e1; - const CallExpr* c2 = (CallExpr*) e2; - - return same_expr(c1->Func(), c2->Func()) && - c1->IsPure() && same_expr(c1->Args(), c2->Args()); - } - - default: - reporter->InternalError("bad tag in same_expr()"); - } - - return 0; - } - int expr_greater(const Expr* e1, const Expr* e2) { return int(e1->Tag()) > int(e2->Tag()); diff --git a/src/Expr.h b/src/Expr.h index b726697803..97092c1315 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -47,11 +47,6 @@ typedef enum { #define NUM_EXPRS (int(EXPR_FLATTEN) + 1) } BroExprTag; -typedef enum { - SIMPLIFY_GENERAL, // regular simplification - SIMPLIFY_LHS, // simplify as the LHS of an assignment -} SimplifyType; - extern const char* expr_name(BroExprTag t); class Stmt; @@ -72,11 +67,6 @@ public: Expr* Ref() { ::Ref(this); return this; } - // Returns a fully simplified version of the expression (this - // may be the same expression, or a newly created one). simp_type - // gives the context of the simplification. - virtual Expr* Simplify(SimplifyType simp_type) = 0; - // Evaluates the expression and returns a corresponding Val*, // or nil if the expression's value isn't fixed. virtual Val* Eval(Frame* f) const = 0; @@ -230,7 +220,6 @@ public: ID* Id() const { return id; } - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN); Expr* MakeLvalue(); @@ -257,7 +246,6 @@ public: Val* Value() const { return val; } - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; TraversalCode Traverse(TraversalCallback* cb) const; @@ -276,9 +264,6 @@ class UnaryExpr : public Expr { public: Expr* Op() const { return op; } - // Simplifies the operand and calls DoSimplify(). - virtual Expr* Simplify(SimplifyType simp_type); - // UnaryExpr::Eval correctly handles vector types. Any child // class that overrides Eval() should be modified to handle // vectors correctly as necessary. @@ -297,10 +282,6 @@ protected: void ExprDescribe(ODesc* d) const; - // Can be overridden by subclasses that want to take advantage - // of UnaryExpr's Simplify() method. - virtual Expr* DoSimplify(); - // Returns the expression folded using the given constant. virtual Val* Fold(Val* v) const; @@ -314,9 +295,6 @@ public: Expr* Op1() const { return op1; } Expr* Op2() const { return op2; } - // Simplifies both operands, folds them if constant, - // otherwise calls DoSimplify(). - virtual Expr* Simplify(SimplifyType simp_type); int IsPure() const; // BinaryExpr::Eval correctly handles vector types. Any child @@ -340,10 +318,6 @@ protected: } virtual ~BinaryExpr(); - // Can be overridden by subclasses that want to take advantage - // of BinaryExpr's Simplify() method. - virtual Expr* DoSimplify(); - // Returns the expression folded using the given constants. virtual Val* Fold(Val* v1, Val* v2) const; @@ -356,9 +330,6 @@ protected: int BothConst() const { return op1->IsConst() && op2->IsConst(); } - // Simplify both operands and canonicize. - void SimplifyOps(); - // Exchange op1 and op2. void SwapOps(); @@ -414,7 +385,6 @@ protected: friend class Expr; NotExpr() { } - Expr* DoSimplify(); Val* Fold(Val* v) const; DECLARE_SERIAL(NotExpr); @@ -428,7 +398,6 @@ protected: friend class Expr; PosExpr() { } - Expr* DoSimplify(); Val* Fold(Val* v) const; DECLARE_SERIAL(PosExpr); @@ -442,7 +411,6 @@ protected: friend class Expr; NegExpr() { } - Expr* DoSimplify(); Val* Fold(Val* v) const; DECLARE_SERIAL(NegExpr); @@ -470,8 +438,6 @@ protected: friend class Expr; AddExpr() { } - Expr* DoSimplify(); - DECLARE_SERIAL(AddExpr); }; @@ -508,8 +474,6 @@ protected: friend class Expr; SubExpr() { } - Expr* DoSimplify(); - DECLARE_SERIAL(SubExpr); }; @@ -523,8 +487,6 @@ protected: friend class Expr; TimesExpr() { } - Expr* DoSimplify(); - DECLARE_SERIAL(TimesExpr); }; @@ -538,7 +500,6 @@ protected: DivideExpr() { } Val* AddrFold(Val* v1, Val* v2) const; - Expr* DoSimplify(); DECLARE_SERIAL(DivideExpr); @@ -552,8 +513,6 @@ protected: friend class Expr; ModExpr() { } - Expr* DoSimplify(); - DECLARE_SERIAL(ModExpr); }; @@ -568,8 +527,6 @@ protected: friend class Expr; BoolExpr() { } - Expr* DoSimplify(); - DECLARE_SERIAL(BoolExpr); }; @@ -582,8 +539,6 @@ protected: friend class Expr; EqExpr() { } - Expr* DoSimplify(); - Val* Fold(Val* v1, Val* v2) const; DECLARE_SERIAL(EqExpr); @@ -598,8 +553,6 @@ protected: friend class Expr; RelExpr() { } - Expr* DoSimplify(); - DECLARE_SERIAL(RelExpr); }; @@ -612,7 +565,6 @@ public: const Expr* Op2() const { return op2; } const Expr* Op3() const { return op3; } - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; int IsPure() const; @@ -652,7 +604,6 @@ public: AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0); virtual ~AssignExpr() { Unref(val); } - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const; BroType* InitType() const; @@ -683,7 +634,6 @@ public: void Add(Frame* f); void Delete(Frame* f); - Expr* Simplify(SimplifyType simp_type); void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN); Expr* MakeLvalue(); @@ -714,7 +664,6 @@ public: int CanDel() const; - Expr* Simplify(SimplifyType simp_type); void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN); void Delete(Frame* f); @@ -866,8 +815,6 @@ protected: friend class Expr; ArithCoerceExpr() { } - Expr* DoSimplify(); - Val* FoldSingleVal(Val* v, InternalTypeTag t) const; Val* Fold(Val* v) const; @@ -962,8 +909,6 @@ public: int IsPure() const; - Expr* Simplify(SimplifyType simp_type); - Val* Eval(Frame* f) const; Expr* When() const { return when; } @@ -1007,7 +952,6 @@ public: int IsPure() const; - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; TraversalCode Traverse(TraversalCallback* cb) const; @@ -1033,7 +977,6 @@ public: ListExpr* Args() const { return args; } EventHandlerPtr Handler() const { return handler; } - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; TraversalCode Traverse(TraversalCallback* cb) const; @@ -1068,7 +1011,6 @@ public: // True if the entire list represents constant values. int AllConst() const; - Expr* Simplify(SimplifyType simp_type); Val* Eval(Frame* f) const; BroType* InitType() const; @@ -1127,21 +1069,10 @@ extern int check_and_promote_exprs(ListExpr*& elements, TypeList* types); extern int check_and_promote_args(ListExpr*& args, RecordType* types); extern int check_and_promote_exprs_to_type(ListExpr*& elements, BroType* type); -// Returns a fully simplified form of the expression. Note that passed -// expression and its subexpressions may be modified, Unref()'d, etc. -Expr* simplify_expr(Expr* e, SimplifyType simp_type); - -// Returns a simplified ListExpr - guaranteed to still be a ListExpr, -// even if it only contains one expr. -ListExpr* simplify_expr_list(ListExpr* l, SimplifyType simp_type); - // Returns a ListExpr simplified down to a list a values, or a nil // pointer if they couldn't all be reduced. val_list* eval_list(Frame* f, const ListExpr* l); -// Returns true if two expressions are identical. -extern int same_expr(const Expr* e1, const Expr* e2); - // Returns true if e1 is "greater" than e2 - here "greater" is just // a heuristic, used with commutative operators to put them into // a canonical form. diff --git a/src/Stmt.cc b/src/Stmt.cc index d2f8c48cee..932943803c 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -79,11 +79,6 @@ bool Stmt::SetLocationInfo(const Location* start, const Location* end) return true; } -Stmt* Stmt::Simplify() - { - return this; - } - int Stmt::IsPure() const { return 0; @@ -201,18 +196,6 @@ Val* ExprListStmt::Exec(Frame* f, stmt_flow_type& flow) const return 0; } -Stmt* ExprListStmt::Simplify() - { - l = simplify_expr_list(l, SIMPLIFY_GENERAL); - DoSimplify(); - return this; - } - -Stmt* ExprListStmt::DoSimplify() - { - return this; - } - void ExprListStmt::Describe(ODesc* d) const { Stmt::Describe(d); @@ -383,17 +366,6 @@ Val* ExprStmt::DoExec(Frame* /* f */, Val* /* v */, stmt_flow_type& /* flow */) return 0; } -Stmt* ExprStmt::Simplify() - { - e = simplify_expr(e, SIMPLIFY_GENERAL); - return DoSimplify(); - } - -Stmt* ExprStmt::DoSimplify() - { - return this; - } - int ExprStmt::IsPure() const { return ! e || e->IsPure(); @@ -490,33 +462,6 @@ Val* IfStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const return result; } -Stmt* IfStmt::DoSimplify() - { - s1 = simplify_stmt(s1); - s2 = simplify_stmt(s2); - - if ( e->IsConst() ) - { - if ( ! optimize ) - Warn("constant in conditional"); - - return e->IsZero() ? s2->Ref() : s1->Ref(); - } - - if ( e->Tag() == EXPR_NOT ) - { - Stmt* t = s1; - s1 = s2; - s2 = t; - - e = new NotExpr(e); - - return Simplify(); - } - - return this; - } - int IfStmt::IsPure() const { return e->IsPure() && s1->IsPure() && s2->IsPure(); @@ -602,7 +547,7 @@ static BroStmtTag get_last_stmt_tag(const Stmt* stmt) } Case::Case(ListExpr* c, Stmt* arg_s) - : cases(simplify_expr_list(c, SIMPLIFY_GENERAL)), s(arg_s) + : cases(c), s(arg_s) { BroStmtTag t = get_last_stmt_tag(Body()); @@ -729,8 +674,8 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) : loop_over_list(*cases, i) { - const Case* c = (*cases)[i]; - const ListExpr* le = c->Cases(); + Case* c = (*cases)[i]; + ListExpr* le = c->Cases(); if ( le ) { @@ -740,10 +685,53 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) : continue; } - const expr_list& exprs = le->Exprs(); + expr_list& exprs = le->Exprs(); loop_over_list(exprs, j) { + if ( ! exprs[j]->IsConst() ) + { + Expr* expr = exprs[j]; + + switch ( expr->Tag() ) { + // Simplify trivial unary plus/minus expressions on consts. + case EXPR_NEGATE: + { + NegExpr* ne = (NegExpr*)(expr); + + if ( ne->Op()->IsConst() ) + Unref(exprs.replace(j, new ConstExpr(ne->Eval(0)))); + } + break; + + case EXPR_POSITIVE: + { + PosExpr* pe = (PosExpr*)(expr); + + if ( pe->Op()->IsConst() ) + Unref(exprs.replace(j, new ConstExpr(pe->Eval(0)))); + } + break; + + case EXPR_NAME: + { + NameExpr* ne = (NameExpr*)(expr); + + if ( ne->Id()->IsConst() ) + { + Val* v = ne->Eval(0); + + if ( v ) + Unref(exprs.replace(j, new ConstExpr(v))); + } + } + break; + + default: + break; + } + } + if ( ! exprs[j]->IsConst() ) exprs[j]->Error("case label expression isn't constant"); else @@ -845,36 +833,6 @@ Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const return rval; } -Stmt* SwitchStmt::DoSimplify() - { - loop_over_list(*cases, i) - { - Case* c = (*cases)[i]; - ListExpr* new_cases = simplify_expr_list(c->Cases(), SIMPLIFY_GENERAL); - Stmt* new_body = simplify_stmt(c->Body()); - - if ( new_cases != c->Cases() || new_body != c->Body() ) - { - cases->replace(i, new Case(new_cases, new_body)); - Unref(c); - } - } - - if ( e->IsConst() ) - { - // Could possibly remove all case labels before the one - // that will match, but may be tricky to tell if any - // subsequent ones can also be removed since it depends - // on the evaluation of the body executing a break/return - // statement. Then still need a way to bypass the lookup - // DoExec for it to be beneficial. - if ( ! optimize ) - Warn("constant in switch"); - } - - return this; - } - int SwitchStmt::IsPure() const { if ( ! e->IsPure() ) @@ -1212,17 +1170,6 @@ Val* WhileStmt::Exec(Frame* f, stmt_flow_type& flow) const return rval; } -Stmt* WhileStmt::Simplify() - { - loop_condition = simplify_expr(loop_condition, SIMPLIFY_GENERAL); - - if ( loop_condition->IsConst() && loop_condition->IsZero() ) - return new NullStmt(); - - body = simplify_stmt(body); - return this; - } - IMPLEMENT_SERIAL(WhileStmt, SER_WHILE_STMT); bool WhileStmt::DoSerialize(SerialInfo* info) const @@ -1416,21 +1363,6 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const return ret; } -Stmt* ForStmt::DoSimplify() - { - body = simplify_stmt(body); - - if ( e->IsConst() ) - { - const PDict(TableEntryVal)* vt = e->ExprVal()->AsTable(); - - if ( vt->Length() == 0 ) - return new NullStmt(); - } - - return this; - } - int ForStmt::IsPure() const { return e->IsPure() && body->IsPure(); @@ -1774,20 +1706,6 @@ Val* StmtList::Exec(Frame* f, stmt_flow_type& flow) const return 0; } -Stmt* StmtList::Simplify() - { - if ( stmts.length() == 0 ) - return new NullStmt(); - - if ( stmts.length() == 1 ) - return stmts[0]->Ref(); - - loop_over_list(stmts, i) - stmts.replace(i, simplify_stmt(stmts[i])); - - return this; - } - int StmtList::IsPure() const { loop_over_list(stmts, i) @@ -1909,17 +1827,6 @@ Val* EventBodyList::Exec(Frame* f, stmt_flow_type& flow) const return 0; } -Stmt* EventBodyList::Simplify() - { - if ( stmts.length() <= 1 ) - // Don't simplify these, we don't want to lose our - // "execute even across returns" property. - return this; - - else - return StmtList::Simplify(); - } - void EventBodyList::Describe(ODesc* d) const { if ( d->IsReadable() && stmts.length() > 0 ) @@ -2168,19 +2075,6 @@ Val* WhenStmt::Exec(Frame* f, stmt_flow_type& flow) const return 0; } -Stmt* WhenStmt::Simplify() - { - cond = simplify_expr(cond, SIMPLIFY_GENERAL); - s1 = simplify_stmt(s1); - if ( s2 ) - s2 = simplify_stmt(s2); - - if ( cond->IsPure() ) - Warn("non-varying expression in when clause"); - - return this; - } - int WhenStmt::IsPure() const { return cond->IsPure() && s1->IsPure() && (! s2 || s2->IsPure()); @@ -2276,172 +2170,3 @@ bool WhenStmt::DoUnserialize(UnserialInfo* info) return true; } - -Stmt* simplify_stmt(Stmt* s) - { - for ( Stmt* ss = s->Simplify(); ss != s; ss = s->Simplify() ) - { - Unref(s); - s = ss; - } - - return s; - } - -int same_stmt(const Stmt* s1, const Stmt* s2) - { - if ( s1 == s2 ) - return 1; - - if ( s1->Tag() != s2->Tag() ) - return 0; - - switch ( s1->Tag() ) { - case STMT_PRINT: - { - const ListExpr* l1 = ((const ExprListStmt*) s1)->ExprList(); - const ListExpr* l2 = ((const ExprListStmt*) s2)->ExprList(); - return same_expr(l1, l2); - } - - case STMT_ADD: - case STMT_DELETE: - case STMT_RETURN: - case STMT_EXPR: - case STMT_EVENT: - { - const ExprStmt* e1 = (const ExprStmt*) s1; - const ExprStmt* e2 = (const ExprStmt*) s2; - return same_expr(e1->StmtExpr(), e2->StmtExpr()); - } - - case STMT_FOR: - { - const ForStmt* f1 = (const ForStmt*) s1; - const ForStmt* f2 = (const ForStmt*) s2; - - return f1->LoopVar() == f2->LoopVar() && - same_expr(f1->LoopExpr(), f2->LoopExpr()) && - same_stmt(f1->LoopBody(), f2->LoopBody()); - } - - case STMT_IF: - { - const IfStmt* i1 = (const IfStmt*) s1; - const IfStmt* i2 = (const IfStmt*) s2; - - if ( ! same_expr(i1->StmtExpr(), i2->StmtExpr()) ) - return 0; - - if ( i1->TrueBranch() || i2->TrueBranch() ) - { - if ( ! i1->TrueBranch() || ! i2->TrueBranch() ) - return 0; - if ( ! same_stmt(i1->TrueBranch(), i2->TrueBranch()) ) - return 0; - } - - if ( i1->FalseBranch() || i2->FalseBranch() ) - { - if ( ! i1->FalseBranch() || ! i2->FalseBranch() ) - return 0; - if ( ! same_stmt(i1->FalseBranch(), i2->FalseBranch()) ) - return 0; - } - - return 1; - } - - case STMT_SWITCH: - { - const SwitchStmt* sw1 = (const SwitchStmt*) s1; - const SwitchStmt* sw2 = (const SwitchStmt*) s2; - - if ( ! same_expr(sw1->StmtExpr(), sw2->StmtExpr()) ) - return 0; - - const case_list* c1 = sw1->Cases(); - const case_list* c2 = sw1->Cases(); - - if ( c1->length() != c2->length() ) - return 0; - - loop_over_list(*c1, i) - { - if ( ! same_expr((*c1)[i]->Cases(), (*c2)[i]->Cases()) ) - return 0; - if ( ! same_stmt((*c1)[i]->Body(), (*c2)[i]->Body()) ) - return 0; - } - - return 1; - } - - case STMT_LIST: - case STMT_EVENT_BODY_LIST: - { - const stmt_list& l1 = ((const StmtList*) s1)->Stmts(); - const stmt_list& l2 = ((const StmtList*) s2)->Stmts(); - - if ( l1.length() != l2.length() ) - return 0; - - loop_over_list(l1, i) - if ( ! same_stmt(l1[i], l2[i]) ) - return 0; - - return 1; - } - - case STMT_INIT: - { - const id_list* i1 = ((const InitStmt*) s1)->Inits(); - const id_list* i2 = ((const InitStmt*) s2)->Inits(); - - if ( i1->length() != i2->length() ) - return 0; - - loop_over_list(*i1, i) - if ( (*i1)[i] != (*i2)[i] ) - return 0; - - return 1; - } - - case STMT_WHEN: - { - const WhenStmt* w1 = (const WhenStmt*) s1; - const WhenStmt* w2 = (const WhenStmt*) s2; - - if ( ! same_expr(w1->Cond(), w2->Cond()) ) - return 0; - - if ( ! same_stmt(w1->Body(), w2->Body()) ) - return 0; - - if ( w1->TimeoutBody() || w2->TimeoutBody() ) - { - if ( ! w1->TimeoutBody() || ! w2->TimeoutBody() ) - return 0; - - if ( ! same_expr(w1->TimeoutExpr(), w2->TimeoutExpr()) ) - return 0; - - if ( ! same_stmt(w1->TimeoutBody(), w2->TimeoutBody()) ) - return 0; - } - - return 1; - } - - case STMT_NEXT: - case STMT_BREAK: - case STMT_NULL: - return 1; - - default: - reporter->Error("bad tag in same_stmt()"); - } - - return 0; - } diff --git a/src/Stmt.h b/src/Stmt.h index 9f0621e567..36fe624e68 100644 --- a/src/Stmt.h +++ b/src/Stmt.h @@ -33,10 +33,6 @@ public: { return Stmt::SetLocationInfo(loc, loc); } bool SetLocationInfo(const Location* start, const Location* end); - // Returns a fully simplified version of the statement (this - // may be the same statement, or a newly created one). - virtual Stmt* Simplify(); - // True if the statement has no side effects, false otherwise. virtual int IsPure() const; @@ -112,9 +108,6 @@ protected: Val* Exec(Frame* f, stmt_flow_type& flow) const; virtual Val* DoExec(val_list* vals, stmt_flow_type& flow) const = 0; - Stmt* Simplify(); - virtual Stmt* DoSimplify(); - void Describe(ODesc* d) const; void PrintVals(ODesc* d, val_list* vals, int offset) const; @@ -156,12 +149,8 @@ protected: virtual Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const; - Stmt* Simplify(); int IsPure() const; - // Called by Simplify(), after the expression's been simplified. - virtual Stmt* DoSimplify(); - DECLARE_SERIAL(ExprStmt); Expr* e; @@ -184,7 +173,6 @@ protected: IfStmt() { s1 = s2 = 0; } Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const; - Stmt* DoSimplify(); int IsPure() const; DECLARE_SERIAL(IfStmt); @@ -237,7 +225,6 @@ protected: SwitchStmt() { cases = 0; default_case_idx = -1; comp_hash = 0; } Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const; - Stmt* DoSimplify(); int IsPure() const; DECLARE_SERIAL(SwitchStmt); @@ -329,7 +316,6 @@ protected: { loop_condition = 0; body = 0; } Val* Exec(Frame* f, stmt_flow_type& flow) const; - Stmt* Simplify(); DECLARE_SERIAL(WhileStmt); @@ -359,7 +345,6 @@ protected: ForStmt() { loop_vars = 0; body = 0; } Val* DoExec(Frame* f, Val* v, stmt_flow_type& flow) const; - Stmt* DoSimplify(); DECLARE_SERIAL(ForStmt); @@ -442,7 +427,6 @@ public: TraversalCode Traverse(TraversalCallback* cb) const; protected: - Stmt* Simplify(); int IsPure() const; DECLARE_SERIAL(StmtList); @@ -464,7 +448,6 @@ public: // bool IsTopmost() { return topmost; } protected: - Stmt* Simplify(); DECLARE_SERIAL(EventBodyList); @@ -522,7 +505,6 @@ public: Val* Exec(Frame* f, stmt_flow_type& flow) const; int IsPure() const; - Stmt* Simplify(); const Expr* Cond() const { return cond; } const Stmt* Body() const { return s1; } @@ -545,7 +527,4 @@ protected: bool is_return; }; -extern Stmt* simplify_stmt(Stmt* s); -extern int same_stmt(const Stmt* s1, const Stmt* s2); - #endif diff --git a/src/Var.cc b/src/Var.cc index 95ec5802ef..ed0f486875 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -64,9 +64,6 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init, } } - if ( init && optimize ) - init = init->Simplify(SIMPLIFY_GENERAL); - if ( t && t->IsSet() ) { // Check for set with explicit elements. SetType* st = t->AsTableType()->AsSetType(); diff --git a/src/input.h b/src/input.h index d07a82f2ee..f0f402b23b 100644 --- a/src/input.h +++ b/src/input.h @@ -46,6 +46,4 @@ extern vector params; class Stmt; extern Stmt* stmts; // global statements -extern int optimize; - #endif diff --git a/src/main.cc b/src/main.cc index fb6dceb396..34923325b4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -115,7 +115,6 @@ ProfileLogger* profiling_logger = 0; ProfileLogger* segment_logger = 0; SampleLogger* sample_logger = 0; int signal_val = 0; -int optimize = 0; int do_notice_analysis = 0; extern char version[]; char* command_line_policy = 0; @@ -192,7 +191,6 @@ void usage() fprintf(stderr, " -I|--print-id | print out given ID\n"); fprintf(stderr, " -K|--md5-hashkey | set key for MD5-keyed hashing\n"); fprintf(stderr, " -N|--print-plugins | print available plugins and exit (-NN for verbose)\n"); - fprintf(stderr, " -O|--optimize | optimize policy script\n"); fprintf(stderr, " -P|--prime-dns | prime DNS\n"); fprintf(stderr, " -Q|--time | print execution time summary to stderr\n"); fprintf(stderr, " -R|--replay | replay events\n"); @@ -496,7 +494,6 @@ int main(int argc, char** argv) {"set-seed", required_argument, 0, 'J'}, {"md5-hashkey", required_argument, 0, 'K'}, {"print-plugins", no_argument, 0, 'N'}, - {"optimize", no_argument, 0, 'O'}, {"prime-dns", no_argument, 0, 'P'}, {"replay", required_argument, 0, 'R'}, {"debug-rules", no_argument, 0, 'S'}, @@ -659,10 +656,6 @@ int main(int argc, char** argv) ++print_plugins; break; - case 'O': - optimize = 1; - break; - case 'P': if ( dns_type != DNS_DEFAULT ) usage(); diff --git a/src/parse.y b/src/parse.y index 8054718d45..c67732835f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -272,9 +272,6 @@ static bool has_attr(const attr_list* al, attr_tag tag) bro: decl_list stmt_list { - if ( optimize ) - $2 = $2->Simplify(); - if ( stmts ) stmts->AsStmtList()->Stmts().append($2); else @@ -1173,9 +1170,6 @@ func_body: '}' { - if ( optimize ) - $4 = $4->Simplify(); - end_func($4, $1); } ;