class ExpressionInliner: private TraversingVisitor
{
private:
+ struct ExpressionUse
+ {
+ RefPtr<Expression> *reference;
+ Block *ref_scope;
+ bool blocked;
+
+ ExpressionUse(): reference(0), ref_scope(0), blocked(false) { }
+ };
+
struct ExpressionInfo
{
- Expression *expression;
+ Assignment::Target target;
+ RefPtr<Expression> expression;
Block *assign_scope;
- RefPtr<Expression> *inline_point;
+ std::vector<ExpressionUse> uses;
bool trivial;
- bool available;
- ExpressionInfo(): expression(0), assign_scope(0), inline_point(0), trivial(false), available(true) { }
+ ExpressionInfo(): expression(0), assign_scope(0), trivial(false) { }
};
- std::map<Assignment::Target, ExpressionInfo> expressions;
+ std::list<ExpressionInfo> expressions;
+ std::map<Assignment::Target, ExpressionInfo *> assignments;
ExpressionInfo *r_ref_info;
- bool r_any_inlined;
bool r_trivial;
- bool mutating;
+ bool access_read;
+ bool access_write;
bool iteration_init;
Block *iteration_body;
const Operator *r_oper;
bool apply(Stage &);
private:
- void inline_expression(Expression &, RefPtr<Expression> &);
- virtual void visit(Block &);
virtual void visit(RefPtr<Expression> &);
virtual void visit(VariableReference &);
virtual void visit(MemberAccess &);
static bool evaluate_relation(const char *, T, T);
template<typename T>
static T evaluate_arithmetic(char, T, T);
+ template<typename T>
+ static T evaluate_int_special_op(char, T, T);
+ template<typename T>
+ void convert_to_result(const Variant &);
void set_result(const Variant &, bool = false);
virtual void visit(RefPtr<Expression> &);
};
/** Removes conditional statements and loops where the condition can be
-determined as constant at compile time. */
+determined as constant at compile time. Also removes such statements where
+the body is empty and the condition has no side effects. */
class ConstantConditionEliminator: private TraversingVisitor
{
private:
NodeList<Statement>::iterator insert_point;
std::set<Node *> nodes_to_remove;
RefPtr<Expression> r_ternary_result;
+ bool r_external_side_effects;
public:
void apply(Stage &);
virtual void visit(Block &);
virtual void visit(RefPtr<Expression> &);
+ virtual void visit(UnaryExpression &);
+ virtual void visit(Assignment &);
virtual void visit(TernaryExpression &);
+ virtual void visit(FunctionCall &);
virtual void visit(Conditional &);
virtual void visit(Iteration &);
};
Node *node;
Assignment::Target target;
std::vector<Node *> used_by;
+ unsigned in_loop;
AssignmentInfo(): node(0) { }
};
bool r_side_effects;
bool in_struct;
bool composite_reference;
+ unsigned in_loop;
+ std::vector<Node *> loop_ext_refs;
Assignment::Target r_reference;
std::set<Node *> unused_nodes;