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 = 0;
20 void apply(Stage &, const std::map<std::string, int> &);
23 virtual void visit(VariableDeclaration &);
26 /** Finds functions which are candidates for inlining. Currently this means
27 functions which have no flow control statements, no more than one return
28 statement, and are either builtins or only called once. */
29 class InlineableFunctionLocator: private TraversingVisitor
32 std::map<FunctionDeclaration *, unsigned> refcounts;
33 std::set<FunctionDeclaration *> inlineable;
34 FunctionDeclaration *current_function = 0;
35 unsigned return_count = 0;
38 std::set<FunctionDeclaration *> apply(Stage &s) { s.content.visit(*this); return inlineable; }
41 virtual void visit(FunctionCall &);
42 virtual void visit(FunctionDeclaration &);
43 virtual void visit(Conditional &);
44 virtual void visit(Iteration &);
45 virtual void visit(Return &);
48 /** Injects statements from one function into another. Local variables are
49 renamed to avoid conflicts. After inlining, uses NodeReorderer to cause
50 dependencies of the inlined statements to appear before the target function. */
51 class InlineContentInjector: private TraversingVisitor
61 FunctionDeclaration *source_func = 0;
63 Pass pass = REFERENCED;
64 RefPtr<Statement> r_inlined_statement;
65 std::set<Node *> dependencies;
66 std::set<std::string> referenced_names;
67 std::string r_result_name;
70 std::string apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionCall &);
73 virtual void visit(VariableReference &);
74 virtual void visit(InterfaceBlockReference &);
75 virtual void visit(FunctionCall &);
76 virtual void visit(VariableDeclaration &);
77 virtual void visit(Return &);
80 /** Inlines functions. Internally uses InlineableFunctionLocator to find
81 candidate functions. Only functions which consist of a single return statement
83 class FunctionInliner: private TraversingVisitor
87 std::set<FunctionDeclaration *> inlineable;
88 FunctionDeclaration *current_function = 0;
89 NodeList<Statement>::iterator insert_point;
90 RefPtr<Expression> r_inline_result;
91 bool r_any_inlined = false;
92 bool r_inlined_here = false;
98 virtual void visit(RefPtr<Expression> &);
99 virtual void visit(Block &);
100 virtual void visit(FunctionCall &);
101 virtual void visit(FunctionDeclaration &);
102 virtual void visit(Iteration &);
105 /** Inlines variables into expressions. Variables with trivial values (those
106 consisting of a single literal or variable reference) are always inlined.
107 Variables which are only referenced once are also inlined. */
108 class ExpressionInliner: private TraversingVisitor
113 RefPtr<Expression> *reference = 0;
114 Block *ref_scope = 0;
115 bool blocked = false;
118 struct ExpressionInfo
120 Assignment::Target target;
121 RefPtr<Expression> expression;
122 Block *assign_scope = 0;
123 std::vector<ExpressionUse> uses;
124 bool trivial = false;
127 std::list<ExpressionInfo> expressions;
128 std::map<Assignment::Target, ExpressionInfo *> assignments;
129 ExpressionInfo *r_ref_info = 0;
130 bool r_trivial = false;
131 bool access_read = true;
132 bool access_write = false;
133 bool iteration_init = false;
134 Block *iteration_body = 0;
135 const Operator *r_oper = 0;
141 virtual void visit(RefPtr<Expression> &);
142 virtual void visit(VariableReference &);
143 virtual void visit(MemberAccess &);
144 virtual void visit(Swizzle &);
145 virtual void visit(UnaryExpression &);
146 virtual void visit(BinaryExpression &);
147 virtual void visit(Assignment &);
148 virtual void visit(TernaryExpression &);
149 virtual void visit(FunctionCall &);
150 virtual void visit(VariableDeclaration &);
151 virtual void visit(Iteration &);
154 /** Replaces expressions consisting entirely of literals with the results of
155 evaluating the expression.*/
156 class ConstantFolder: private TraversingVisitor
159 VariableDeclaration *iteration_var = 0;
160 Variant iter_init_value;
161 Variant r_constant_value;
162 bool iteration_init = false;
163 bool r_constant = false;
164 bool r_literal = false;
165 bool r_uses_iter_var = false;
166 bool r_any_folded = false;
169 bool apply(Stage &s) { s.content.visit(*this); return r_any_folded; }
173 static T evaluate_logical(char, T, T);
175 static bool evaluate_relation(const char *, T, T);
177 static T evaluate_arithmetic(char, T, T);
179 static T evaluate_int_special_op(char, T, T);
181 void convert_to_result(const Variant &);
182 void set_result(const Variant &, bool = false);
184 virtual void visit(RefPtr<Expression> &);
185 virtual void visit(Literal &);
186 virtual void visit(VariableReference &);
187 virtual void visit(MemberAccess &);
188 virtual void visit(Swizzle &);
189 virtual void visit(UnaryExpression &);
190 virtual void visit(BinaryExpression &);
191 virtual void visit(Assignment &);
192 virtual void visit(TernaryExpression &);
193 virtual void visit(FunctionCall &);
194 virtual void visit(VariableDeclaration &);
195 virtual void visit(Iteration &);
198 /** Removes conditional statements and loops where the condition can be
199 determined as constant at compile time. Also removes such statements where
200 the body is empty and the condition has no side effects. */
201 class ConstantConditionEliminator: private TraversingVisitor
211 NodeList<Statement>::iterator insert_point;
212 std::set<Node *> nodes_to_remove;
213 RefPtr<Expression> r_ternary_result;
214 bool r_external_side_effects = false;
220 ConstantStatus check_constant_condition(const Expression &);
222 virtual void visit(Block &);
223 virtual void visit(RefPtr<Expression> &);
224 virtual void visit(UnaryExpression &);
225 virtual void visit(Assignment &);
226 virtual void visit(TernaryExpression &);
227 virtual void visit(FunctionCall &);
228 virtual void visit(Conditional &);
229 virtual void visit(Iteration &);
232 class UnreachableCodeRemover: private TraversingVisitor
235 bool reachable = true;
236 std::set<Node *> unreachable_nodes;
239 virtual bool apply(Stage &);
242 virtual void visit(Block &);
243 virtual void visit(FunctionDeclaration &);
244 virtual void visit(Conditional &);
245 virtual void visit(Iteration &);
246 virtual void visit(Return &) { reachable = false; }
247 virtual void visit(Jump &) { reachable = false; }
250 /** Removes types which are not used anywhere. */
251 class UnusedTypeRemover: private TraversingVisitor
254 std::set<Node *> unused_nodes;
260 virtual void visit(RefPtr<Expression> &);
261 virtual void visit(BasicTypeDeclaration &);
262 virtual void visit(ImageTypeDeclaration &);
263 virtual void visit(StructDeclaration &);
264 virtual void visit(VariableDeclaration &);
265 virtual void visit(InterfaceBlock &);
266 virtual void visit(FunctionDeclaration &);
269 /** Removes variable declarations with no references to them. Assignment
270 statements where the result is not used are also removed. */
271 class UnusedVariableRemover: private TraversingVisitor
274 struct AssignmentInfo
277 Assignment::Target target;
278 std::vector<Node *> used_by;
279 unsigned in_loop = 0;
284 InterfaceBlock *interface_block = 0;
285 std::vector<AssignmentInfo *> assignments;
286 bool initialized = false;
288 bool referenced = false;
291 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
294 BlockVariableMap variables;
295 std::list<AssignmentInfo> assignments;
296 InterfaceBlock *interface_block = 0;
297 Assignment *r_assignment = 0;
298 bool assignment_target = false;
299 bool r_side_effects = false;
300 bool in_struct = false;
301 bool composite_reference = false;
302 unsigned in_loop = 0;
303 std::vector<Node *> loop_ext_refs;
304 Assignment::Target r_reference;
305 std::set<Node *> unused_nodes;
311 void referenced(const Assignment::Target &, Node &);
312 virtual void visit(VariableReference &);
313 virtual void visit(InterfaceBlockReference &);
314 void visit_composite(Expression &);
315 virtual void visit(MemberAccess &);
316 virtual void visit(Swizzle &);
317 virtual void visit(UnaryExpression &);
318 virtual void visit(BinaryExpression &);
319 virtual void visit(Assignment &);
320 virtual void visit(TernaryExpression &);
321 virtual void visit(FunctionCall &);
322 void record_assignment(const Assignment::Target &, Node &);
323 virtual void visit(ExpressionStatement &);
324 virtual void visit(StructDeclaration &);
325 virtual void visit(VariableDeclaration &);
326 virtual void visit(InterfaceBlock &);
327 void merge_variables(const BlockVariableMap &);
328 virtual void visit(FunctionDeclaration &);
329 virtual void visit(Conditional &);
330 virtual void visit(Iteration &);
333 /** Removes function declarations with no references to them. */
334 class UnusedFunctionRemover: private TraversingVisitor
337 std::set<Node *> unused_nodes;
338 std::set<FunctionDeclaration *> used_definitions;
341 bool apply(Stage &s);
344 virtual void visit(FunctionCall &);
345 virtual void visit(FunctionDeclaration &);