1 #ifndef MSP_GL_SL_OPTIMIZE_H_
2 #define MSP_GL_SL_OPTIMIZE_H_
12 /** Assigns values to specialization constants, turning them into normal
14 class ConstantSpecializer: private TraversingVisitor
17 const std::map<std::string, int> *values;
20 ConstantSpecializer();
22 void apply(Stage &, const std::map<std::string, int> &);
25 virtual void visit(VariableDeclaration &);
28 /** Finds functions which are candidates for inlining. Currently this means
29 functions which have no flow control statements, no more than one return
30 statement, and are either builtins or only called once. */
31 class InlineableFunctionLocator: private TraversingVisitor
34 std::map<FunctionDeclaration *, unsigned> refcounts;
35 std::set<FunctionDeclaration *> inlineable;
36 FunctionDeclaration *current_function;
37 unsigned return_count;
40 InlineableFunctionLocator();
42 std::set<FunctionDeclaration *> apply(Stage &s) { s.content.visit(*this); return inlineable; }
45 virtual void visit(FunctionCall &);
46 virtual void visit(FunctionDeclaration &);
47 virtual void visit(Conditional &);
48 virtual void visit(Iteration &);
49 virtual void visit(Return &);
52 /** Injects statements from one function into another. Local variables are
53 renamed to avoid conflicts. After inlining, uses NodeReorderer to cause
54 dependencies of the inlined statements to appear before the target function. */
55 class InlineContentInjector: private TraversingVisitor
65 FunctionDeclaration *source_func;
68 RefPtr<Statement> r_inlined_statement;
69 std::set<Node *> dependencies;
70 std::set<std::string> referenced_names;
71 std::string r_result_name;
74 InlineContentInjector();
76 std::string apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionCall &);
79 virtual void visit(VariableReference &);
80 virtual void visit(InterfaceBlockReference &);
81 virtual void visit(FunctionCall &);
82 virtual void visit(VariableDeclaration &);
83 virtual void visit(Return &);
86 /** Inlines functions. Internally uses InlineableFunctionLocator to find
87 candidate functions. Only functions which consist of a single return statement
89 class FunctionInliner: private TraversingVisitor
93 std::set<FunctionDeclaration *> inlineable;
94 FunctionDeclaration *current_function;
95 NodeList<Statement>::iterator insert_point;
96 RefPtr<Expression> r_inline_result;
106 virtual void visit(RefPtr<Expression> &);
107 virtual void visit(Block &);
108 virtual void visit(FunctionCall &);
109 virtual void visit(FunctionDeclaration &);
110 virtual void visit(Iteration &);
113 /** Inlines variables into expressions. Variables with trivial values (those
114 consisting of a single literal or variable reference) are always inlined.
115 Variables which are only referenced once are also inlined. */
116 class ExpressionInliner: private TraversingVisitor
121 RefPtr<Expression> *reference;
125 ExpressionUse(): reference(0), ref_scope(0), blocked(false) { }
128 struct ExpressionInfo
130 Assignment::Target target;
131 RefPtr<Expression> expression;
133 std::vector<ExpressionUse> uses;
136 ExpressionInfo(): expression(0), assign_scope(0), trivial(false) { }
139 std::list<ExpressionInfo> expressions;
140 std::map<Assignment::Target, ExpressionInfo *> assignments;
141 ExpressionInfo *r_ref_info;
146 Block *iteration_body;
147 const Operator *r_oper;
155 virtual void visit(RefPtr<Expression> &);
156 virtual void visit(VariableReference &);
157 virtual void visit(MemberAccess &);
158 virtual void visit(Swizzle &);
159 virtual void visit(UnaryExpression &);
160 virtual void visit(BinaryExpression &);
161 virtual void visit(Assignment &);
162 virtual void visit(TernaryExpression &);
163 virtual void visit(FunctionCall &);
164 virtual void visit(VariableDeclaration &);
165 virtual void visit(Iteration &);
168 /** Replaces expressions consisting entirely of literals with the results of
169 evaluating the expression.*/
170 class ConstantFolder: private TraversingVisitor
173 VariableDeclaration *iteration_var;
174 Variant iter_init_value;
175 Variant r_constant_value;
179 bool r_uses_iter_var;
183 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
187 static T evaluate_logical(char, T, T);
189 static bool evaluate_relation(const char *, T, T);
191 static T evaluate_arithmetic(char, T, T);
193 static T evaluate_int_special_op(char, T, T);
195 void convert_to_result(const Variant &);
196 void set_result(const Variant &, bool = false);
198 virtual void visit(RefPtr<Expression> &);
199 virtual void visit(Literal &);
200 virtual void visit(VariableReference &);
201 virtual void visit(MemberAccess &);
202 virtual void visit(Swizzle &);
203 virtual void visit(UnaryExpression &);
204 virtual void visit(BinaryExpression &);
205 virtual void visit(Assignment &);
206 virtual void visit(TernaryExpression &);
207 virtual void visit(FunctionCall &);
208 virtual void visit(VariableDeclaration &);
209 virtual void visit(Iteration &);
212 /** Removes conditional statements and loops where the condition can be
213 determined as constant at compile time. Also removes such statements where
214 the body is empty and the condition has no side effects. */
215 class ConstantConditionEliminator: private TraversingVisitor
225 NodeList<Statement>::iterator insert_point;
226 std::set<Node *> nodes_to_remove;
227 RefPtr<Expression> r_ternary_result;
228 bool r_external_side_effects;
234 ConstantStatus check_constant_condition(const Expression &);
236 virtual void visit(Block &);
237 virtual void visit(RefPtr<Expression> &);
238 virtual void visit(UnaryExpression &);
239 virtual void visit(Assignment &);
240 virtual void visit(TernaryExpression &);
241 virtual void visit(FunctionCall &);
242 virtual void visit(Conditional &);
243 virtual void visit(Iteration &);
246 class UnreachableCodeRemover: private TraversingVisitor
250 std::set<Node *> unreachable_nodes;
253 UnreachableCodeRemover();
255 virtual bool apply(Stage &);
258 virtual void visit(Block &);
259 virtual void visit(FunctionDeclaration &);
260 virtual void visit(Conditional &);
261 virtual void visit(Iteration &);
262 virtual void visit(Return &) { reachable = false; }
263 virtual void visit(Jump &) { reachable = false; }
266 /** Removes types which are not used anywhere. */
267 class UnusedTypeRemover: private TraversingVisitor
270 std::set<Node *> unused_nodes;
276 virtual void visit(RefPtr<Expression> &);
277 virtual void visit(BasicTypeDeclaration &);
278 virtual void visit(ImageTypeDeclaration &);
279 virtual void visit(StructDeclaration &);
280 virtual void visit(VariableDeclaration &);
281 virtual void visit(InterfaceBlock &);
282 virtual void visit(FunctionDeclaration &);
285 /** Removes variable declarations with no references to them. Assignment
286 statements where the result is not used are also removed. */
287 class UnusedVariableRemover: private TraversingVisitor
290 struct AssignmentInfo
293 Assignment::Target target;
294 std::vector<Node *> used_by;
297 AssignmentInfo(): node(0) { }
302 InterfaceBlock *interface_block;
303 std::vector<AssignmentInfo *> assignments;
308 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
311 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
314 BlockVariableMap variables;
315 std::list<AssignmentInfo> assignments;
316 InterfaceBlock *interface_block;
317 Assignment *r_assignment;
318 bool assignment_target;
321 bool composite_reference;
323 std::vector<Node *> loop_ext_refs;
324 Assignment::Target r_reference;
325 std::set<Node *> unused_nodes;
328 UnusedVariableRemover();
333 void referenced(const Assignment::Target &, Node &);
334 virtual void visit(VariableReference &);
335 virtual void visit(InterfaceBlockReference &);
336 void visit_composite(Expression &);
337 virtual void visit(MemberAccess &);
338 virtual void visit(Swizzle &);
339 virtual void visit(UnaryExpression &);
340 virtual void visit(BinaryExpression &);
341 virtual void visit(Assignment &);
342 virtual void visit(TernaryExpression &);
343 virtual void visit(FunctionCall &);
344 void record_assignment(const Assignment::Target &, Node &);
345 virtual void visit(ExpressionStatement &);
346 virtual void visit(StructDeclaration &);
347 virtual void visit(VariableDeclaration &);
348 virtual void visit(InterfaceBlock &);
349 void merge_variables(const BlockVariableMap &);
350 virtual void visit(FunctionDeclaration &);
351 virtual void visit(Conditional &);
352 virtual void visit(Iteration &);
355 /** Removes function declarations with no references to them. */
356 class UnusedFunctionRemover: private TraversingVisitor
359 std::set<Node *> unused_nodes;
360 std::set<FunctionDeclaration *> used_definitions;
363 bool apply(Stage &s);
366 virtual void visit(FunctionCall &);
367 virtual void visit(FunctionDeclaration &);