1 #ifndef MSP_GL_SL_OPTIMIZE_H_
2 #define MSP_GL_SL_OPTIMIZE_H_
13 /** Finds functions which are candidates for inlining. Currently this means
14 functions which have no parameters, contain no more than one return statement,
15 and are only called once. */
16 class InlineableFunctionLocator: private TraversingVisitor
19 std::map<FunctionDeclaration *, unsigned> refcounts;
20 std::set<FunctionDeclaration *> inlineable;
21 FunctionDeclaration *current_function;
22 unsigned return_count;
25 InlineableFunctionLocator();
27 const std::set<FunctionDeclaration *> &apply(Stage &s) { s.content.visit(*this); return inlineable; }
30 virtual void visit(FunctionCall &);
31 virtual void visit(FunctionDeclaration &);
32 virtual void visit(Conditional &);
33 virtual void visit(Iteration &);
34 virtual void visit(Return &);
37 /** Injects statements from one function into another. Local variables are
38 renamed to avoid conflicts. After inlining, uses NodeReorderer to cause
39 dependencies of the inlined statements to appear before the target function. */
40 class InlineContentInjector: private TraversingVisitor
43 FunctionDeclaration *source_func;
45 std::map<std::string, VariableDeclaration *> variable_map;
48 RefPtr<Statement> r_inlined_statement;
49 std::set<Node *> dependencies;
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;
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 /** Removes conditional statements and loops where the condition can be
139 determined as constant at compile time. */
140 class ConstantConditionEliminator: private TraversingVisitor
143 NodeList<Statement>::iterator insert_point;
144 std::set<Node *> nodes_to_remove;
150 virtual void visit(Block &);
151 virtual void visit(Conditional &);
152 virtual void visit(Iteration &);
155 /** Removes types which are not used anywhere. */
156 class UnusedTypeRemover: private TraversingVisitor
159 std::set<Node *> unused_nodes;
165 virtual void visit(Literal &);
166 virtual void visit(UnaryExpression &);
167 virtual void visit(BinaryExpression &);
168 virtual void visit(TernaryExpression &);
169 virtual void visit(FunctionCall &);
170 virtual void visit(BasicTypeDeclaration &);
171 virtual void visit(ImageTypeDeclaration &);
172 virtual void visit(StructDeclaration &);
173 virtual void visit(VariableDeclaration &);
174 virtual void visit(InterfaceBlock &);
175 virtual void visit(FunctionDeclaration &);
178 /** Removes variable declarations with no references to them. Assignment
179 statements where the result is not used are also removed. */
180 class UnusedVariableRemover: private TraversingVisitor
183 struct AssignmentInfo
186 Assignment::Target target;
187 std::vector<Node *> used_by;
189 AssignmentInfo(): node(0) { }
194 InterfaceBlock *interface_block;
195 std::vector<AssignmentInfo *> assignments;
200 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
203 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
206 BlockVariableMap variables;
207 std::list<AssignmentInfo> assignments;
208 InterfaceBlock *interface_block;
209 Assignment *r_assignment;
210 bool assignment_target;
212 std::set<Node *> unused_nodes;
215 UnusedVariableRemover();
220 void referenced(const Assignment::Target &, Node &);
221 virtual void visit(VariableReference &);
222 virtual void visit(InterfaceBlockReference &);
223 virtual void visit(UnaryExpression &);
224 virtual void visit(BinaryExpression &);
225 virtual void visit(Assignment &);
226 virtual void visit(FunctionCall &);
227 void record_assignment(const Assignment::Target &, Node &);
228 virtual void visit(ExpressionStatement &);
229 // Ignore structs because their members can't be accessed directly.
230 virtual void visit(StructDeclaration &) { }
231 virtual void visit(VariableDeclaration &);
232 virtual void visit(InterfaceBlock &);
233 void merge_variables(const BlockVariableMap &);
234 virtual void visit(FunctionDeclaration &);
235 virtual void visit(Conditional &);
236 virtual void visit(Iteration &);
239 /** Removes function declarations with no references to them. */
240 class UnusedFunctionRemover: private TraversingVisitor
243 std::set<Node *> unused_nodes;
244 std::set<FunctionDeclaration *> used_definitions;
247 bool apply(Stage &s);
250 virtual void visit(FunctionCall &);
251 virtual void visit(FunctionDeclaration &);