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
119 struct ExpressionInfo
121 Expression *expression;
123 RefPtr<Expression> *inline_point;
127 ExpressionInfo(): expression(0), assign_scope(0), inline_point(0), trivial(false), available(true) { }
130 std::map<Assignment::Target, ExpressionInfo> expressions;
131 ExpressionInfo *r_ref_info;
136 Block *iteration_body;
137 const Operator *r_oper;
145 void inline_expression(Expression &, RefPtr<Expression> &);
146 virtual void visit(Block &);
147 virtual void visit(RefPtr<Expression> &);
148 virtual void visit(VariableReference &);
149 virtual void visit(MemberAccess &);
150 virtual void visit(Swizzle &);
151 virtual void visit(UnaryExpression &);
152 virtual void visit(BinaryExpression &);
153 virtual void visit(Assignment &);
154 virtual void visit(TernaryExpression &);
155 virtual void visit(FunctionCall &);
156 virtual void visit(VariableDeclaration &);
157 virtual void visit(Iteration &);
160 /** Replaces expressions consisting entirely of literals with the results of
161 evaluating the expression.*/
162 class ConstantFolder: private TraversingVisitor
165 VariableDeclaration *iteration_var;
166 Variant iter_init_value;
167 Variant r_constant_value;
171 bool r_uses_iter_var;
175 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
179 static T evaluate_logical(char, T, T);
181 static bool evaluate_relation(const char *, T, T);
183 static T evaluate_arithmetic(char, T, T);
185 static T evaluate_int_special_op(char, T, T);
187 void convert_to_result(const Variant &);
188 void set_result(const Variant &, bool = false);
190 virtual void visit(RefPtr<Expression> &);
191 virtual void visit(Literal &);
192 virtual void visit(VariableReference &);
193 virtual void visit(MemberAccess &);
194 virtual void visit(Swizzle &);
195 virtual void visit(UnaryExpression &);
196 virtual void visit(BinaryExpression &);
197 virtual void visit(Assignment &);
198 virtual void visit(TernaryExpression &);
199 virtual void visit(FunctionCall &);
200 virtual void visit(VariableDeclaration &);
201 virtual void visit(Iteration &);
204 /** Removes conditional statements and loops where the condition can be
205 determined as constant at compile time. */
206 class ConstantConditionEliminator: private TraversingVisitor
216 NodeList<Statement>::iterator insert_point;
217 std::set<Node *> nodes_to_remove;
218 RefPtr<Expression> r_ternary_result;
224 ConstantStatus check_constant_condition(const Expression &);
226 virtual void visit(Block &);
227 virtual void visit(RefPtr<Expression> &);
228 virtual void visit(TernaryExpression &);
229 virtual void visit(Conditional &);
230 virtual void visit(Iteration &);
233 class UnreachableCodeRemover: private TraversingVisitor
237 std::set<Node *> unreachable_nodes;
240 UnreachableCodeRemover();
242 virtual bool apply(Stage &);
245 virtual void visit(Block &);
246 virtual void visit(FunctionDeclaration &);
247 virtual void visit(Conditional &);
248 virtual void visit(Iteration &);
249 virtual void visit(Return &) { reachable = false; }
250 virtual void visit(Jump &) { reachable = false; }
253 /** Removes types which are not used anywhere. */
254 class UnusedTypeRemover: private TraversingVisitor
257 std::set<Node *> unused_nodes;
263 virtual void visit(RefPtr<Expression> &);
264 virtual void visit(BasicTypeDeclaration &);
265 virtual void visit(ImageTypeDeclaration &);
266 virtual void visit(StructDeclaration &);
267 virtual void visit(VariableDeclaration &);
268 virtual void visit(InterfaceBlock &);
269 virtual void visit(FunctionDeclaration &);
272 /** Removes variable declarations with no references to them. Assignment
273 statements where the result is not used are also removed. */
274 class UnusedVariableRemover: private TraversingVisitor
277 struct AssignmentInfo
280 Assignment::Target target;
281 std::vector<Node *> used_by;
284 AssignmentInfo(): node(0) { }
289 InterfaceBlock *interface_block;
290 std::vector<AssignmentInfo *> assignments;
295 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
298 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
301 BlockVariableMap variables;
302 std::list<AssignmentInfo> assignments;
303 InterfaceBlock *interface_block;
304 Assignment *r_assignment;
305 bool assignment_target;
308 bool composite_reference;
310 std::vector<Node *> loop_ext_refs;
311 Assignment::Target r_reference;
312 std::set<Node *> unused_nodes;
315 UnusedVariableRemover();
320 void referenced(const Assignment::Target &, Node &);
321 virtual void visit(VariableReference &);
322 virtual void visit(InterfaceBlockReference &);
323 void visit_composite(Expression &);
324 virtual void visit(MemberAccess &);
325 virtual void visit(Swizzle &);
326 virtual void visit(UnaryExpression &);
327 virtual void visit(BinaryExpression &);
328 virtual void visit(Assignment &);
329 virtual void visit(TernaryExpression &);
330 virtual void visit(FunctionCall &);
331 void record_assignment(const Assignment::Target &, Node &);
332 virtual void visit(ExpressionStatement &);
333 virtual void visit(StructDeclaration &);
334 virtual void visit(VariableDeclaration &);
335 virtual void visit(InterfaceBlock &);
336 void merge_variables(const BlockVariableMap &);
337 virtual void visit(FunctionDeclaration &);
338 virtual void visit(Conditional &);
339 virtual void visit(Iteration &);
342 /** Removes function declarations with no references to them. */
343 class UnusedFunctionRemover: private TraversingVisitor
346 std::set<Node *> unused_nodes;
347 std::set<FunctionDeclaration *> used_definitions;
350 bool apply(Stage &s);
353 virtual void visit(FunctionCall &);
354 virtual void visit(FunctionDeclaration &);