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 parameters, contain no more than one return statement,
14 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
42 FunctionDeclaration *source_func;
44 std::map<std::string, VariableDeclaration *> variable_map;
45 std::string remap_prefix;
48 RefPtr<Statement> r_inlined_statement;
49 std::set<Node *> dependencies;
50 std::set<std::string> referenced_names;
51 std::string r_result_name;
54 InlineContentInjector();
56 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionDeclaration &);
59 virtual void visit(VariableReference &);
60 virtual void visit(InterfaceBlockReference &);
61 virtual void visit(FunctionCall &);
62 virtual void visit(VariableDeclaration &);
63 virtual void visit(Return &);
66 /** Inlines functions. Internally uses InlineableFunctionLocator to find
67 candidate functions. Only functions which consist of a single return statement
69 class FunctionInliner: private TraversingVisitor
73 std::set<FunctionDeclaration *> inlineable;
74 FunctionDeclaration *current_function;
75 NodeList<Statement>::iterator insert_point;
76 RefPtr<Expression> r_inline_result;
86 virtual void visit(RefPtr<Expression> &);
87 virtual void visit(Block &);
88 virtual void visit(FunctionCall &);
89 virtual void visit(FunctionDeclaration &);
90 virtual void visit(Iteration &);
93 /** Inlines variables into expressions. Variables with trivial values (those
94 consisting of a single literal or variable reference) are always inlined.
95 Variables which are only referenced once are also inlined. */
96 class ExpressionInliner: private TraversingVisitor
101 Expression *expression;
103 RefPtr<Expression> *inline_point;
110 std::map<Assignment::Target, ExpressionInfo> expressions;
111 ExpressionInfo *r_ref_info;
116 Block *iteration_body;
117 const Operator *r_oper;
125 void inline_expression(Expression &, RefPtr<Expression> &);
126 virtual void visit(Block &);
127 virtual void visit(RefPtr<Expression> &);
128 virtual void visit(VariableReference &);
129 virtual void visit(MemberAccess &);
130 virtual void visit(Swizzle &);
131 virtual void visit(UnaryExpression &);
132 virtual void visit(BinaryExpression &);
133 virtual void visit(Assignment &);
134 virtual void visit(TernaryExpression &);
135 virtual void visit(FunctionCall &);
136 virtual void visit(VariableDeclaration &);
137 virtual void visit(Iteration &);
140 /** Replaces expressions consisting entirely of literals with the results of
141 evaluating the expression.*/
142 class ConstantFolder: private TraversingVisitor
145 VariableDeclaration *iteration_var;
146 Variant iter_init_value;
147 Variant r_constant_value;
151 bool r_uses_iter_var;
155 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
158 static BasicTypeDeclaration::Kind get_value_kind(const Variant &);
160 static T evaluate_logical(char, T, T);
162 static bool evaluate_relation(const char *, T, T);
164 static T evaluate_arithmetic(char, T, T);
165 void set_result(const Variant &, bool = false);
167 virtual void visit(RefPtr<Expression> &);
168 virtual void visit(Literal &);
169 virtual void visit(VariableReference &);
170 virtual void visit(MemberAccess &);
171 virtual void visit(Swizzle &);
172 virtual void visit(UnaryExpression &);
173 virtual void visit(BinaryExpression &);
174 virtual void visit(Assignment &);
175 virtual void visit(TernaryExpression &);
176 virtual void visit(FunctionCall &);
177 virtual void visit(VariableDeclaration &);
178 virtual void visit(Iteration &);
181 /** Removes conditional statements and loops where the condition can be
182 determined as constant at compile time. */
183 class ConstantConditionEliminator: private TraversingVisitor
193 NodeList<Statement>::iterator insert_point;
194 std::set<Node *> nodes_to_remove;
195 RefPtr<Expression> r_ternary_result;
201 ConstantStatus check_constant_condition(const Expression &);
203 virtual void visit(Block &);
204 virtual void visit(RefPtr<Expression> &);
205 virtual void visit(TernaryExpression &);
206 virtual void visit(Conditional &);
207 virtual void visit(Iteration &);
210 /** Removes types which are not used anywhere. */
211 class UnusedTypeRemover: private TraversingVisitor
214 std::set<Node *> unused_nodes;
220 virtual void visit(Literal &);
221 virtual void visit(UnaryExpression &);
222 virtual void visit(BinaryExpression &);
223 virtual void visit(TernaryExpression &);
224 virtual void visit(FunctionCall &);
225 virtual void visit(BasicTypeDeclaration &);
226 virtual void visit(ImageTypeDeclaration &);
227 virtual void visit(StructDeclaration &);
228 virtual void visit(VariableDeclaration &);
229 virtual void visit(InterfaceBlock &);
230 virtual void visit(FunctionDeclaration &);
233 /** Removes variable declarations with no references to them. Assignment
234 statements where the result is not used are also removed. */
235 class UnusedVariableRemover: private TraversingVisitor
238 struct AssignmentInfo
241 Assignment::Target target;
242 std::vector<Node *> used_by;
244 AssignmentInfo(): node(0) { }
249 InterfaceBlock *interface_block;
250 std::vector<AssignmentInfo *> assignments;
255 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
258 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
261 BlockVariableMap variables;
262 std::list<AssignmentInfo> assignments;
263 InterfaceBlock *interface_block;
264 Assignment *r_assignment;
265 bool assignment_target;
267 std::set<Node *> unused_nodes;
270 UnusedVariableRemover();
275 void referenced(const Assignment::Target &, Node &);
276 virtual void visit(VariableReference &);
277 virtual void visit(InterfaceBlockReference &);
278 virtual void visit(UnaryExpression &);
279 virtual void visit(BinaryExpression &);
280 virtual void visit(Assignment &);
281 virtual void visit(FunctionCall &);
282 void record_assignment(const Assignment::Target &, Node &);
283 virtual void visit(ExpressionStatement &);
284 // Ignore structs because their members can't be accessed directly.
285 virtual void visit(StructDeclaration &) { }
286 virtual void visit(VariableDeclaration &);
287 virtual void visit(InterfaceBlock &);
288 void merge_variables(const BlockVariableMap &);
289 virtual void visit(FunctionDeclaration &);
290 virtual void visit(Conditional &);
291 virtual void visit(Iteration &);
294 /** Removes function declarations with no references to them. */
295 class UnusedFunctionRemover: private TraversingVisitor
298 std::set<Node *> unused_nodes;
299 std::set<FunctionDeclaration *> used_definitions;
302 bool apply(Stage &s);
305 virtual void visit(FunctionCall &);
306 virtual void visit(FunctionDeclaration &);