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 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 const 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
66 FunctionDeclaration *source_func;
69 RefPtr<Statement> r_inlined_statement;
70 std::set<Node *> dependencies;
71 std::set<std::string> referenced_names;
72 std::string r_result_name;
75 InlineContentInjector();
77 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionCall &);
80 virtual void visit(VariableReference &);
81 virtual void visit(InterfaceBlockReference &);
82 virtual void visit(FunctionCall &);
83 virtual void visit(VariableDeclaration &);
84 virtual void visit(Return &);
87 /** Inlines functions. Internally uses InlineableFunctionLocator to find
88 candidate functions. Only functions which consist of a single return statement
90 class FunctionInliner: private TraversingVisitor
94 std::set<FunctionDeclaration *> inlineable;
95 FunctionDeclaration *current_function;
96 NodeList<Statement>::iterator insert_point;
97 RefPtr<Expression> r_inline_result;
107 virtual void visit(RefPtr<Expression> &);
108 virtual void visit(Block &);
109 virtual void visit(FunctionCall &);
110 virtual void visit(FunctionDeclaration &);
111 virtual void visit(Iteration &);
114 /** Inlines variables into expressions. Variables with trivial values (those
115 consisting of a single literal or variable reference) are always inlined.
116 Variables which are only referenced once are also inlined. */
117 class ExpressionInliner: private TraversingVisitor
120 struct ExpressionInfo
122 Expression *expression;
124 RefPtr<Expression> *inline_point;
131 std::map<Assignment::Target, ExpressionInfo> expressions;
132 ExpressionInfo *r_ref_info;
137 Block *iteration_body;
138 const Operator *r_oper;
146 void inline_expression(Expression &, RefPtr<Expression> &);
147 virtual void visit(Block &);
148 virtual void visit(RefPtr<Expression> &);
149 virtual void visit(VariableReference &);
150 virtual void visit(MemberAccess &);
151 virtual void visit(Swizzle &);
152 virtual void visit(UnaryExpression &);
153 virtual void visit(BinaryExpression &);
154 virtual void visit(Assignment &);
155 virtual void visit(TernaryExpression &);
156 virtual void visit(FunctionCall &);
157 virtual void visit(VariableDeclaration &);
158 virtual void visit(Iteration &);
161 /** Replaces expressions consisting entirely of literals with the results of
162 evaluating the expression.*/
163 class ConstantFolder: private TraversingVisitor
166 VariableDeclaration *iteration_var;
167 Variant iter_init_value;
168 Variant r_constant_value;
172 bool r_uses_iter_var;
176 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
179 static BasicTypeDeclaration::Kind get_value_kind(const Variant &);
181 static T evaluate_logical(char, T, T);
183 static bool evaluate_relation(const char *, T, T);
185 static T evaluate_arithmetic(char, T, T);
186 void set_result(const Variant &, bool = false);
188 virtual void visit(RefPtr<Expression> &);
189 virtual void visit(Literal &);
190 virtual void visit(VariableReference &);
191 virtual void visit(MemberAccess &);
192 virtual void visit(Swizzle &);
193 virtual void visit(UnaryExpression &);
194 virtual void visit(BinaryExpression &);
195 virtual void visit(Assignment &);
196 virtual void visit(TernaryExpression &);
197 virtual void visit(FunctionCall &);
198 virtual void visit(VariableDeclaration &);
199 virtual void visit(Iteration &);
202 /** Removes conditional statements and loops where the condition can be
203 determined as constant at compile time. */
204 class ConstantConditionEliminator: private TraversingVisitor
214 NodeList<Statement>::iterator insert_point;
215 std::set<Node *> nodes_to_remove;
216 RefPtr<Expression> r_ternary_result;
222 ConstantStatus check_constant_condition(const Expression &);
224 virtual void visit(Block &);
225 virtual void visit(RefPtr<Expression> &);
226 virtual void visit(TernaryExpression &);
227 virtual void visit(Conditional &);
228 virtual void visit(Iteration &);
231 /** Removes types which are not used anywhere. */
232 class UnusedTypeRemover: private TraversingVisitor
235 std::set<Node *> unused_nodes;
241 virtual void visit(Literal &);
242 virtual void visit(UnaryExpression &);
243 virtual void visit(BinaryExpression &);
244 virtual void visit(TernaryExpression &);
245 virtual void visit(FunctionCall &);
246 virtual void visit(BasicTypeDeclaration &);
247 virtual void visit(ImageTypeDeclaration &);
248 virtual void visit(StructDeclaration &);
249 virtual void visit(VariableDeclaration &);
250 virtual void visit(InterfaceBlock &);
251 virtual void visit(FunctionDeclaration &);
254 /** Removes variable declarations with no references to them. Assignment
255 statements where the result is not used are also removed. */
256 class UnusedVariableRemover: private TraversingVisitor
259 struct AssignmentInfo
262 Assignment::Target target;
263 std::vector<Node *> used_by;
265 AssignmentInfo(): node(0) { }
270 InterfaceBlock *interface_block;
271 std::vector<AssignmentInfo *> assignments;
276 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
279 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
282 BlockVariableMap variables;
283 std::list<AssignmentInfo> assignments;
284 InterfaceBlock *interface_block;
285 Assignment *r_assignment;
286 bool assignment_target;
288 std::set<Node *> unused_nodes;
291 UnusedVariableRemover();
296 void referenced(const Assignment::Target &, Node &);
297 virtual void visit(VariableReference &);
298 virtual void visit(InterfaceBlockReference &);
299 virtual void visit(UnaryExpression &);
300 virtual void visit(BinaryExpression &);
301 virtual void visit(Assignment &);
302 virtual void visit(FunctionCall &);
303 void record_assignment(const Assignment::Target &, Node &);
304 virtual void visit(ExpressionStatement &);
305 // Ignore structs because their members can't be accessed directly.
306 virtual void visit(StructDeclaration &) { }
307 virtual void visit(VariableDeclaration &);
308 virtual void visit(InterfaceBlock &);
309 void merge_variables(const BlockVariableMap &);
310 virtual void visit(FunctionDeclaration &);
311 virtual void visit(Conditional &);
312 virtual void visit(Iteration &);
315 /** Removes function declarations with no references to them. */
316 class UnusedFunctionRemover: private TraversingVisitor
319 std::set<Node *> unused_nodes;
320 std::set<FunctionDeclaration *> used_definitions;
323 bool apply(Stage &s);
326 virtual void visit(FunctionCall &);
327 virtual void visit(FunctionDeclaration &);