1 #ifndef MSP_GL_SL_OPTIMIZE_H_
2 #define MSP_GL_SL_OPTIMIZE_H_
12 /** Finds functions which are candidates for inlining. Currently this means
13 functions which have no flow control statements, no more than one return
14 statement, and are only called once. */
15 class InlineableFunctionLocator: private TraversingVisitor
18 std::map<FunctionDeclaration *, unsigned> refcounts;
19 std::set<FunctionDeclaration *> inlineable;
20 FunctionDeclaration *current_function;
21 unsigned return_count;
24 InlineableFunctionLocator();
26 const std::set<FunctionDeclaration *> &apply(Stage &s) { s.content.visit(*this); return inlineable; }
29 virtual void visit(FunctionCall &);
30 virtual void visit(FunctionDeclaration &);
31 virtual void visit(Conditional &);
32 virtual void visit(Iteration &);
33 virtual void visit(Return &);
36 /** Injects statements from one function into another. Local variables are
37 renamed to avoid conflicts. After inlining, uses NodeReorderer to cause
38 dependencies of the inlined statements to appear before the target function. */
39 class InlineContentInjector: private TraversingVisitor
50 FunctionDeclaration *source_func;
53 RefPtr<Statement> r_inlined_statement;
54 std::set<Node *> dependencies;
55 std::set<std::string> referenced_names;
56 std::string r_result_name;
59 InlineContentInjector();
61 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionCall &);
64 virtual void visit(VariableReference &);
65 virtual void visit(InterfaceBlockReference &);
66 virtual void visit(FunctionCall &);
67 virtual void visit(VariableDeclaration &);
68 virtual void visit(Return &);
71 /** Inlines functions. Internally uses InlineableFunctionLocator to find
72 candidate functions. Only functions which consist of a single return statement
74 class FunctionInliner: private TraversingVisitor
78 std::set<FunctionDeclaration *> inlineable;
79 FunctionDeclaration *current_function;
80 NodeList<Statement>::iterator insert_point;
81 RefPtr<Expression> r_inline_result;
91 virtual void visit(RefPtr<Expression> &);
92 virtual void visit(Block &);
93 virtual void visit(FunctionCall &);
94 virtual void visit(FunctionDeclaration &);
95 virtual void visit(Iteration &);
98 /** Inlines variables into expressions. Variables with trivial values (those
99 consisting of a single literal or variable reference) are always inlined.
100 Variables which are only referenced once are also inlined. */
101 class ExpressionInliner: private TraversingVisitor
104 struct ExpressionInfo
106 Expression *expression;
108 RefPtr<Expression> *inline_point;
115 std::map<Assignment::Target, ExpressionInfo> expressions;
116 ExpressionInfo *r_ref_info;
121 Block *iteration_body;
122 const Operator *r_oper;
130 void inline_expression(Expression &, RefPtr<Expression> &);
131 virtual void visit(Block &);
132 virtual void visit(RefPtr<Expression> &);
133 virtual void visit(VariableReference &);
134 virtual void visit(MemberAccess &);
135 virtual void visit(Swizzle &);
136 virtual void visit(UnaryExpression &);
137 virtual void visit(BinaryExpression &);
138 virtual void visit(Assignment &);
139 virtual void visit(TernaryExpression &);
140 virtual void visit(FunctionCall &);
141 virtual void visit(VariableDeclaration &);
142 virtual void visit(Iteration &);
145 /** Replaces expressions consisting entirely of literals with the results of
146 evaluating the expression.*/
147 class ConstantFolder: private TraversingVisitor
150 VariableDeclaration *iteration_var;
151 Variant iter_init_value;
152 Variant r_constant_value;
156 bool r_uses_iter_var;
160 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
163 static BasicTypeDeclaration::Kind get_value_kind(const Variant &);
165 static T evaluate_logical(char, T, T);
167 static bool evaluate_relation(const char *, T, T);
169 static T evaluate_arithmetic(char, T, T);
170 void set_result(const Variant &, bool = false);
172 virtual void visit(RefPtr<Expression> &);
173 virtual void visit(Literal &);
174 virtual void visit(VariableReference &);
175 virtual void visit(MemberAccess &);
176 virtual void visit(Swizzle &);
177 virtual void visit(UnaryExpression &);
178 virtual void visit(BinaryExpression &);
179 virtual void visit(Assignment &);
180 virtual void visit(TernaryExpression &);
181 virtual void visit(FunctionCall &);
182 virtual void visit(VariableDeclaration &);
183 virtual void visit(Iteration &);
186 /** Removes conditional statements and loops where the condition can be
187 determined as constant at compile time. */
188 class ConstantConditionEliminator: private TraversingVisitor
198 NodeList<Statement>::iterator insert_point;
199 std::set<Node *> nodes_to_remove;
200 RefPtr<Expression> r_ternary_result;
206 ConstantStatus check_constant_condition(const Expression &);
208 virtual void visit(Block &);
209 virtual void visit(RefPtr<Expression> &);
210 virtual void visit(TernaryExpression &);
211 virtual void visit(Conditional &);
212 virtual void visit(Iteration &);
215 /** Removes types which are not used anywhere. */
216 class UnusedTypeRemover: private TraversingVisitor
219 std::set<Node *> unused_nodes;
225 virtual void visit(Literal &);
226 virtual void visit(UnaryExpression &);
227 virtual void visit(BinaryExpression &);
228 virtual void visit(TernaryExpression &);
229 virtual void visit(FunctionCall &);
230 virtual void visit(BasicTypeDeclaration &);
231 virtual void visit(ImageTypeDeclaration &);
232 virtual void visit(StructDeclaration &);
233 virtual void visit(VariableDeclaration &);
234 virtual void visit(InterfaceBlock &);
235 virtual void visit(FunctionDeclaration &);
238 /** Removes variable declarations with no references to them. Assignment
239 statements where the result is not used are also removed. */
240 class UnusedVariableRemover: private TraversingVisitor
243 struct AssignmentInfo
246 Assignment::Target target;
247 std::vector<Node *> used_by;
249 AssignmentInfo(): node(0) { }
254 InterfaceBlock *interface_block;
255 std::vector<AssignmentInfo *> assignments;
260 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
263 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
266 BlockVariableMap variables;
267 std::list<AssignmentInfo> assignments;
268 InterfaceBlock *interface_block;
269 Assignment *r_assignment;
270 bool assignment_target;
272 std::set<Node *> unused_nodes;
275 UnusedVariableRemover();
280 void referenced(const Assignment::Target &, Node &);
281 virtual void visit(VariableReference &);
282 virtual void visit(InterfaceBlockReference &);
283 virtual void visit(UnaryExpression &);
284 virtual void visit(BinaryExpression &);
285 virtual void visit(Assignment &);
286 virtual void visit(FunctionCall &);
287 void record_assignment(const Assignment::Target &, Node &);
288 virtual void visit(ExpressionStatement &);
289 // Ignore structs because their members can't be accessed directly.
290 virtual void visit(StructDeclaration &) { }
291 virtual void visit(VariableDeclaration &);
292 virtual void visit(InterfaceBlock &);
293 void merge_variables(const BlockVariableMap &);
294 virtual void visit(FunctionDeclaration &);
295 virtual void visit(Conditional &);
296 virtual void visit(Iteration &);
299 /** Removes function declarations with no references to them. */
300 class UnusedFunctionRemover: private TraversingVisitor
303 std::set<Node *> unused_nodes;
304 std::set<FunctionDeclaration *> used_definitions;
307 bool apply(Stage &s);
310 virtual void visit(FunctionCall &);
311 virtual void visit(FunctionDeclaration &);