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 std::string create_unused_name(const std::string &, bool);
60 virtual void visit(VariableReference &);
61 virtual void visit(InterfaceBlockReference &);
62 virtual void visit(FunctionCall &);
63 virtual void visit(VariableDeclaration &);
64 virtual void visit(Return &);
67 /** Inlines functions. Internally uses InlineableFunctionLocator to find
68 candidate functions. Only functions which consist of a single return statement
70 class FunctionInliner: private TraversingVisitor
74 std::set<FunctionDeclaration *> inlineable;
75 FunctionDeclaration *current_function;
76 NodeList<Statement>::iterator insert_point;
77 RefPtr<Expression> r_inline_result;
86 void visit_and_inline(RefPtr<Expression> &);
88 virtual void visit(Block &);
89 virtual void visit(UnaryExpression &);
90 virtual void visit(BinaryExpression &);
91 virtual void visit(Assignment &a) { visit(static_cast<BinaryExpression &>(a)); }
92 virtual void visit(MemberAccess &);
93 virtual void visit(Swizzle &);
94 virtual void visit(FunctionCall &);
95 virtual void visit(ExpressionStatement &);
96 virtual void visit(VariableDeclaration &);
97 virtual void visit(FunctionDeclaration &);
98 virtual void visit(Conditional &);
99 virtual void visit(Iteration &);
100 virtual void visit(Return &);
103 /** Inlines variables into expressions. Variables with trivial values (those
104 consisting of a single literal or variable reference) are always inlined.
105 Variables which are only referenced once are also inlined. */
106 class ExpressionInliner: private TraversingVisitor
109 struct ExpressionInfo
111 Expression *expression;
113 RefPtr<Expression> *inline_point;
114 const Operator *inner_oper;
115 const Operator *outer_oper;
123 std::map<Assignment::Target, ExpressionInfo> expressions;
124 ExpressionInfo *r_ref_info;
129 Block *iteration_body;
130 const Operator *r_oper;
138 void visit_and_record(RefPtr<Expression> &, const Operator *, bool);
139 void inline_expression(Expression &, RefPtr<Expression> &, const Operator *, const Operator *, bool);
140 virtual void visit(Block &);
141 virtual void visit(VariableReference &);
142 virtual void visit(MemberAccess &);
143 virtual void visit(Swizzle &);
144 virtual void visit(UnaryExpression &);
145 virtual void visit(BinaryExpression &);
146 virtual void visit(Assignment &);
147 virtual void visit(FunctionCall &);
148 virtual void visit(VariableDeclaration &);
149 virtual void visit(Conditional &);
150 virtual void visit(Iteration &);
151 virtual void visit(Return &);
154 /** Removes conditional statements and loops where the condition can be
155 determined as constant at compile time. */
156 class ConstantConditionEliminator: private TraversingVisitor
159 NodeList<Statement>::iterator insert_point;
160 std::set<Node *> nodes_to_remove;
166 virtual void visit(Block &);
167 virtual void visit(Conditional &);
168 virtual void visit(Iteration &);
171 /** Removes types which are not used anywhere. */
172 class UnusedTypeRemover: private TraversingVisitor
175 std::set<Node *> unused_nodes;
181 virtual void visit(Literal &);
182 virtual void visit(UnaryExpression &);
183 virtual void visit(BinaryExpression &);
184 virtual void visit(FunctionCall &);
185 virtual void visit(BasicTypeDeclaration &);
186 virtual void visit(ImageTypeDeclaration &);
187 virtual void visit(StructDeclaration &);
188 virtual void visit(VariableDeclaration &);
189 virtual void visit(InterfaceBlock &);
190 virtual void visit(FunctionDeclaration &);
193 /** Removes variable declarations with no references to them. Assignment
194 statements where the result is not used are also removed. */
195 class UnusedVariableRemover: private TraversingVisitor
200 std::vector<Node *> assignments;
203 bool conditionally_assigned;
205 InterfaceBlock *interface_block;
210 typedef std::map<Assignment::Target, VariableInfo> BlockVariableMap;
213 std::set<Node *> unused_nodes;
214 std::vector<BlockVariableMap> variables;
215 InterfaceBlock *interface_block;
216 Assignment *r_assignment;
217 bool assignment_target;
221 UnusedVariableRemover();
226 void reference_used(Statement &);
227 virtual void visit(VariableReference &);
228 virtual void visit(InterfaceBlockReference &);
229 virtual void visit(UnaryExpression &);
230 virtual void visit(BinaryExpression &);
231 virtual void visit(Assignment &);
232 void record_assignment(const Assignment::Target &, Node &, bool);
233 void clear_assignments(VariableInfo &, bool);
234 virtual void visit(FunctionCall &);
235 virtual void visit(ExpressionStatement &);
236 // Ignore structs because their members can't be accessed directly.
237 virtual void visit(StructDeclaration &) { }
238 virtual void visit(VariableDeclaration &);
239 virtual void visit(InterfaceBlock &);
240 virtual void visit(FunctionDeclaration &);
241 void merge_down_variables();
242 virtual void visit(Conditional &);
243 virtual void visit(Iteration &);
246 /** Removes function declarations with no references to them. */
247 class UnusedFunctionRemover: private TraversingVisitor
250 std::set<Node *> unused_nodes;
251 std::set<FunctionDeclaration *> used_definitions;
254 bool apply(Stage &s);
257 virtual void visit(FunctionCall &);
258 virtual void visit(FunctionDeclaration &);