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;
47 RefPtr<Statement> r_inlined_statement;
48 std::set<Node *> dependencies;
49 std::set<std::string> referenced_names;
50 std::string r_result_name;
53 InlineContentInjector();
55 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionDeclaration &);
58 virtual void visit(VariableReference &);
59 virtual void visit(InterfaceBlockReference &);
60 virtual void visit(FunctionCall &);
61 virtual void visit(VariableDeclaration &);
62 virtual void visit(Return &);
65 /** Inlines functions. Internally uses InlineableFunctionLocator to find
66 candidate functions. Only functions which consist of a single return statement
68 class FunctionInliner: private TraversingVisitor
72 std::set<FunctionDeclaration *> inlineable;
73 FunctionDeclaration *current_function;
74 NodeList<Statement>::iterator insert_point;
75 RefPtr<Expression> r_inline_result;
85 virtual void visit(RefPtr<Expression> &);
86 virtual void visit(Block &);
87 virtual void visit(FunctionCall &);
88 virtual void visit(FunctionDeclaration &);
89 virtual void visit(Iteration &);
92 /** Inlines variables into expressions. Variables with trivial values (those
93 consisting of a single literal or variable reference) are always inlined.
94 Variables which are only referenced once are also inlined. */
95 class ExpressionInliner: private TraversingVisitor
100 Expression *expression;
102 RefPtr<Expression> *inline_point;
109 std::map<Assignment::Target, ExpressionInfo> expressions;
110 ExpressionInfo *r_ref_info;
115 Block *iteration_body;
116 const Operator *r_oper;
124 void inline_expression(Expression &, RefPtr<Expression> &);
125 virtual void visit(Block &);
126 virtual void visit(RefPtr<Expression> &);
127 virtual void visit(VariableReference &);
128 virtual void visit(MemberAccess &);
129 virtual void visit(Swizzle &);
130 virtual void visit(UnaryExpression &);
131 virtual void visit(BinaryExpression &);
132 virtual void visit(Assignment &);
133 virtual void visit(TernaryExpression &);
134 virtual void visit(FunctionCall &);
135 virtual void visit(VariableDeclaration &);
136 virtual void visit(Iteration &);
139 /** Replaces expressions consisting entirely of literals with the results of
140 evaluating the expression.*/
141 class ConstantFolder: private TraversingVisitor
144 VariableDeclaration *iteration_var;
145 Variant iter_init_value;
146 Variant r_constant_value;
150 bool r_uses_iter_var;
154 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
157 static BasicTypeDeclaration::Kind get_value_kind(const Variant &);
159 static T evaluate_logical(char, T, T);
161 static bool evaluate_relation(const char *, T, T);
163 static T evaluate_arithmetic(char, T, T);
164 void set_result(const Variant &, bool = false);
166 virtual void visit(RefPtr<Expression> &);
167 virtual void visit(Literal &);
168 virtual void visit(VariableReference &);
169 virtual void visit(MemberAccess &);
170 virtual void visit(Swizzle &);
171 virtual void visit(UnaryExpression &);
172 virtual void visit(BinaryExpression &);
173 virtual void visit(Assignment &);
174 virtual void visit(TernaryExpression &);
175 virtual void visit(FunctionCall &);
176 virtual void visit(VariableDeclaration &);
177 virtual void visit(Iteration &);
180 /** Removes conditional statements and loops where the condition can be
181 determined as constant at compile time. */
182 class ConstantConditionEliminator: private TraversingVisitor
192 NodeList<Statement>::iterator insert_point;
193 std::set<Node *> nodes_to_remove;
194 RefPtr<Expression> r_ternary_result;
200 ConstantStatus check_constant_condition(const Expression &);
202 virtual void visit(Block &);
203 virtual void visit(RefPtr<Expression> &);
204 virtual void visit(TernaryExpression &);
205 virtual void visit(Conditional &);
206 virtual void visit(Iteration &);
209 /** Removes types which are not used anywhere. */
210 class UnusedTypeRemover: private TraversingVisitor
213 std::set<Node *> unused_nodes;
219 virtual void visit(Literal &);
220 virtual void visit(UnaryExpression &);
221 virtual void visit(BinaryExpression &);
222 virtual void visit(TernaryExpression &);
223 virtual void visit(FunctionCall &);
224 virtual void visit(BasicTypeDeclaration &);
225 virtual void visit(ImageTypeDeclaration &);
226 virtual void visit(StructDeclaration &);
227 virtual void visit(VariableDeclaration &);
228 virtual void visit(InterfaceBlock &);
229 virtual void visit(FunctionDeclaration &);
232 /** Removes variable declarations with no references to them. Assignment
233 statements where the result is not used are also removed. */
234 class UnusedVariableRemover: private TraversingVisitor
237 struct AssignmentInfo
240 Assignment::Target target;
241 std::vector<Node *> used_by;
243 AssignmentInfo(): node(0) { }
248 InterfaceBlock *interface_block;
249 std::vector<AssignmentInfo *> assignments;
254 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
257 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
260 BlockVariableMap variables;
261 std::list<AssignmentInfo> assignments;
262 InterfaceBlock *interface_block;
263 Assignment *r_assignment;
264 bool assignment_target;
266 std::set<Node *> unused_nodes;
269 UnusedVariableRemover();
274 void referenced(const Assignment::Target &, Node &);
275 virtual void visit(VariableReference &);
276 virtual void visit(InterfaceBlockReference &);
277 virtual void visit(UnaryExpression &);
278 virtual void visit(BinaryExpression &);
279 virtual void visit(Assignment &);
280 virtual void visit(FunctionCall &);
281 void record_assignment(const Assignment::Target &, Node &);
282 virtual void visit(ExpressionStatement &);
283 // Ignore structs because their members can't be accessed directly.
284 virtual void visit(StructDeclaration &) { }
285 virtual void visit(VariableDeclaration &);
286 virtual void visit(InterfaceBlock &);
287 void merge_variables(const BlockVariableMap &);
288 virtual void visit(FunctionDeclaration &);
289 virtual void visit(Conditional &);
290 virtual void visit(Iteration &);
293 /** Removes function declarations with no references to them. */
294 class UnusedFunctionRemover: private TraversingVisitor
297 std::set<Node *> unused_nodes;
298 std::set<FunctionDeclaration *> used_definitions;
301 bool apply(Stage &s);
304 virtual void visit(FunctionCall &);
305 virtual void visit(FunctionDeclaration &);