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::string remap_prefix;
46 RefPtr<Statement> r_inlined_statement;
47 std::set<Node *> dependencies;
48 std::set<std::string> referenced_names;
49 std::string r_result_name;
52 InlineContentInjector();
54 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionDeclaration &);
57 virtual void visit(VariableReference &);
58 virtual void visit(InterfaceBlockReference &);
59 virtual void visit(FunctionCall &);
60 virtual void visit(VariableDeclaration &);
61 virtual void visit(Return &);
64 /** Inlines functions. Internally uses InlineableFunctionLocator to find
65 candidate functions. Only functions which consist of a single return statement
67 class FunctionInliner: private TraversingVisitor
71 std::set<FunctionDeclaration *> inlineable;
72 FunctionDeclaration *current_function;
73 NodeList<Statement>::iterator insert_point;
74 RefPtr<Expression> r_inline_result;
84 virtual void visit(RefPtr<Expression> &);
85 virtual void visit(Block &);
86 virtual void visit(FunctionCall &);
87 virtual void visit(FunctionDeclaration &);
88 virtual void visit(Iteration &);
91 /** Inlines variables into expressions. Variables with trivial values (those
92 consisting of a single literal or variable reference) are always inlined.
93 Variables which are only referenced once are also inlined. */
94 class ExpressionInliner: private TraversingVisitor
99 Expression *expression;
101 RefPtr<Expression> *inline_point;
108 std::map<Assignment::Target, ExpressionInfo> expressions;
109 ExpressionInfo *r_ref_info;
114 Block *iteration_body;
115 const Operator *r_oper;
123 void inline_expression(Expression &, RefPtr<Expression> &);
124 virtual void visit(Block &);
125 virtual void visit(RefPtr<Expression> &);
126 virtual void visit(VariableReference &);
127 virtual void visit(MemberAccess &);
128 virtual void visit(Swizzle &);
129 virtual void visit(UnaryExpression &);
130 virtual void visit(BinaryExpression &);
131 virtual void visit(Assignment &);
132 virtual void visit(TernaryExpression &);
133 virtual void visit(FunctionCall &);
134 virtual void visit(VariableDeclaration &);
135 virtual void visit(Iteration &);
138 /** Replaces expressions consisting entirely of literals with the results of
139 evaluating the expression.*/
140 class ConstantFolder: private TraversingVisitor
143 VariableDeclaration *iteration_var;
144 Variant iter_init_value;
145 Variant r_constant_value;
149 bool r_uses_iter_var;
153 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
156 static BasicTypeDeclaration::Kind get_value_kind(const Variant &);
158 static T evaluate_logical(char, T, T);
160 static bool evaluate_relation(const char *, T, T);
162 static T evaluate_arithmetic(char, T, T);
163 void set_result(const Variant &, bool = false);
165 virtual void visit(RefPtr<Expression> &);
166 virtual void visit(Literal &);
167 virtual void visit(VariableReference &);
168 virtual void visit(MemberAccess &);
169 virtual void visit(Swizzle &);
170 virtual void visit(UnaryExpression &);
171 virtual void visit(BinaryExpression &);
172 virtual void visit(Assignment &);
173 virtual void visit(TernaryExpression &);
174 virtual void visit(FunctionCall &);
175 virtual void visit(VariableDeclaration &);
176 virtual void visit(Iteration &);
179 /** Removes conditional statements and loops where the condition can be
180 determined as constant at compile time. */
181 class ConstantConditionEliminator: private TraversingVisitor
191 NodeList<Statement>::iterator insert_point;
192 std::set<Node *> nodes_to_remove;
193 RefPtr<Expression> r_ternary_result;
199 ConstantStatus check_constant_condition(const Expression &);
201 virtual void visit(Block &);
202 virtual void visit(RefPtr<Expression> &);
203 virtual void visit(TernaryExpression &);
204 virtual void visit(Conditional &);
205 virtual void visit(Iteration &);
208 /** Removes types which are not used anywhere. */
209 class UnusedTypeRemover: private TraversingVisitor
212 std::set<Node *> unused_nodes;
218 virtual void visit(Literal &);
219 virtual void visit(UnaryExpression &);
220 virtual void visit(BinaryExpression &);
221 virtual void visit(TernaryExpression &);
222 virtual void visit(FunctionCall &);
223 virtual void visit(BasicTypeDeclaration &);
224 virtual void visit(ImageTypeDeclaration &);
225 virtual void visit(StructDeclaration &);
226 virtual void visit(VariableDeclaration &);
227 virtual void visit(InterfaceBlock &);
228 virtual void visit(FunctionDeclaration &);
231 /** Removes variable declarations with no references to them. Assignment
232 statements where the result is not used are also removed. */
233 class UnusedVariableRemover: private TraversingVisitor
236 struct AssignmentInfo
239 Assignment::Target target;
240 std::vector<Node *> used_by;
242 AssignmentInfo(): node(0) { }
247 InterfaceBlock *interface_block;
248 std::vector<AssignmentInfo *> assignments;
253 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
256 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
259 BlockVariableMap variables;
260 std::list<AssignmentInfo> assignments;
261 InterfaceBlock *interface_block;
262 Assignment *r_assignment;
263 bool assignment_target;
265 std::set<Node *> unused_nodes;
268 UnusedVariableRemover();
273 void referenced(const Assignment::Target &, Node &);
274 virtual void visit(VariableReference &);
275 virtual void visit(InterfaceBlockReference &);
276 virtual void visit(UnaryExpression &);
277 virtual void visit(BinaryExpression &);
278 virtual void visit(Assignment &);
279 virtual void visit(FunctionCall &);
280 void record_assignment(const Assignment::Target &, Node &);
281 virtual void visit(ExpressionStatement &);
282 // Ignore structs because their members can't be accessed directly.
283 virtual void visit(StructDeclaration &) { }
284 virtual void visit(VariableDeclaration &);
285 virtual void visit(InterfaceBlock &);
286 void merge_variables(const BlockVariableMap &);
287 virtual void visit(FunctionDeclaration &);
288 virtual void visit(Conditional &);
289 virtual void visit(Iteration &);
292 /** Removes function declarations with no references to them. */
293 class UnusedFunctionRemover: private TraversingVisitor
296 std::set<Node *> unused_nodes;
297 std::set<FunctionDeclaration *> used_definitions;
300 bool apply(Stage &s);
303 virtual void visit(FunctionCall &);
304 virtual void visit(FunctionDeclaration &);