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
50 FunctionDeclaration *source_func;
52 std::string remap_prefix;
54 RefPtr<Statement> r_inlined_statement;
55 std::set<Node *> dependencies;
56 std::set<std::string> referenced_names;
57 std::string r_result_name;
60 InlineContentInjector();
62 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionDeclaration &);
65 virtual void visit(VariableReference &);
66 virtual void visit(InterfaceBlockReference &);
67 virtual void visit(FunctionCall &);
68 virtual void visit(VariableDeclaration &);
69 virtual void visit(Return &);
72 /** Inlines functions. Internally uses InlineableFunctionLocator to find
73 candidate functions. Only functions which consist of a single return statement
75 class FunctionInliner: private TraversingVisitor
79 std::set<FunctionDeclaration *> inlineable;
80 FunctionDeclaration *current_function;
81 NodeList<Statement>::iterator insert_point;
82 RefPtr<Expression> r_inline_result;
92 virtual void visit(RefPtr<Expression> &);
93 virtual void visit(Block &);
94 virtual void visit(FunctionCall &);
95 virtual void visit(FunctionDeclaration &);
96 virtual void visit(Iteration &);
99 /** Inlines variables into expressions. Variables with trivial values (those
100 consisting of a single literal or variable reference) are always inlined.
101 Variables which are only referenced once are also inlined. */
102 class ExpressionInliner: private TraversingVisitor
105 struct ExpressionInfo
107 Expression *expression;
109 RefPtr<Expression> *inline_point;
116 std::map<Assignment::Target, ExpressionInfo> expressions;
117 ExpressionInfo *r_ref_info;
122 Block *iteration_body;
123 const Operator *r_oper;
131 void inline_expression(Expression &, RefPtr<Expression> &);
132 virtual void visit(Block &);
133 virtual void visit(RefPtr<Expression> &);
134 virtual void visit(VariableReference &);
135 virtual void visit(MemberAccess &);
136 virtual void visit(Swizzle &);
137 virtual void visit(UnaryExpression &);
138 virtual void visit(BinaryExpression &);
139 virtual void visit(Assignment &);
140 virtual void visit(TernaryExpression &);
141 virtual void visit(FunctionCall &);
142 virtual void visit(VariableDeclaration &);
143 virtual void visit(Iteration &);
146 /** Replaces expressions consisting entirely of literals with the results of
147 evaluating the expression.*/
148 class ConstantFolder: private TraversingVisitor
151 VariableDeclaration *iteration_var;
152 Variant iter_init_value;
153 Variant r_constant_value;
157 bool r_uses_iter_var;
161 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
164 static BasicTypeDeclaration::Kind get_value_kind(const Variant &);
166 static T evaluate_logical(char, T, T);
168 static bool evaluate_relation(const char *, T, T);
170 static T evaluate_arithmetic(char, T, T);
171 void set_result(const Variant &, bool = false);
173 virtual void visit(RefPtr<Expression> &);
174 virtual void visit(Literal &);
175 virtual void visit(VariableReference &);
176 virtual void visit(MemberAccess &);
177 virtual void visit(Swizzle &);
178 virtual void visit(UnaryExpression &);
179 virtual void visit(BinaryExpression &);
180 virtual void visit(Assignment &);
181 virtual void visit(TernaryExpression &);
182 virtual void visit(FunctionCall &);
183 virtual void visit(VariableDeclaration &);
184 virtual void visit(Iteration &);
187 /** Removes conditional statements and loops where the condition can be
188 determined as constant at compile time. */
189 class ConstantConditionEliminator: private TraversingVisitor
199 NodeList<Statement>::iterator insert_point;
200 std::set<Node *> nodes_to_remove;
201 RefPtr<Expression> r_ternary_result;
207 ConstantStatus check_constant_condition(const Expression &);
209 virtual void visit(Block &);
210 virtual void visit(RefPtr<Expression> &);
211 virtual void visit(TernaryExpression &);
212 virtual void visit(Conditional &);
213 virtual void visit(Iteration &);
216 /** Removes types which are not used anywhere. */
217 class UnusedTypeRemover: private TraversingVisitor
220 std::set<Node *> unused_nodes;
226 virtual void visit(Literal &);
227 virtual void visit(UnaryExpression &);
228 virtual void visit(BinaryExpression &);
229 virtual void visit(TernaryExpression &);
230 virtual void visit(FunctionCall &);
231 virtual void visit(BasicTypeDeclaration &);
232 virtual void visit(ImageTypeDeclaration &);
233 virtual void visit(StructDeclaration &);
234 virtual void visit(VariableDeclaration &);
235 virtual void visit(InterfaceBlock &);
236 virtual void visit(FunctionDeclaration &);
239 /** Removes variable declarations with no references to them. Assignment
240 statements where the result is not used are also removed. */
241 class UnusedVariableRemover: private TraversingVisitor
244 struct AssignmentInfo
247 Assignment::Target target;
248 std::vector<Node *> used_by;
250 AssignmentInfo(): node(0) { }
255 InterfaceBlock *interface_block;
256 std::vector<AssignmentInfo *> assignments;
261 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
264 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
267 BlockVariableMap variables;
268 std::list<AssignmentInfo> assignments;
269 InterfaceBlock *interface_block;
270 Assignment *r_assignment;
271 bool assignment_target;
273 std::set<Node *> unused_nodes;
276 UnusedVariableRemover();
281 void referenced(const Assignment::Target &, Node &);
282 virtual void visit(VariableReference &);
283 virtual void visit(InterfaceBlockReference &);
284 virtual void visit(UnaryExpression &);
285 virtual void visit(BinaryExpression &);
286 virtual void visit(Assignment &);
287 virtual void visit(FunctionCall &);
288 void record_assignment(const Assignment::Target &, Node &);
289 virtual void visit(ExpressionStatement &);
290 // Ignore structs because their members can't be accessed directly.
291 virtual void visit(StructDeclaration &) { }
292 virtual void visit(VariableDeclaration &);
293 virtual void visit(InterfaceBlock &);
294 void merge_variables(const BlockVariableMap &);
295 virtual void visit(FunctionDeclaration &);
296 virtual void visit(Conditional &);
297 virtual void visit(Iteration &);
300 /** Removes function declarations with no references to them. */
301 class UnusedFunctionRemover: private TraversingVisitor
304 std::set<Node *> unused_nodes;
305 std::set<FunctionDeclaration *> used_definitions;
308 bool apply(Stage &s);
311 virtual void visit(FunctionCall &);
312 virtual void visit(FunctionDeclaration &);