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;
46 std::string remap_prefix;
49 RefPtr<Statement> r_inlined_statement;
50 std::set<Node *> dependencies;
51 std::set<std::string> referenced_names;
52 std::string r_result_name;
55 InlineContentInjector();
57 const std::string &apply(Stage &, FunctionDeclaration &, Block &, const NodeList<Statement>::iterator &, FunctionDeclaration &);
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 virtual void visit(RefPtr<Expression> &);
87 virtual void visit(Block &);
88 virtual void visit(FunctionCall &);
89 virtual void visit(FunctionDeclaration &);
90 virtual void visit(Iteration &);
93 /** Inlines variables into expressions. Variables with trivial values (those
94 consisting of a single literal or variable reference) are always inlined.
95 Variables which are only referenced once are also inlined. */
96 class ExpressionInliner: private TraversingVisitor
101 Expression *expression;
103 RefPtr<Expression> *inline_point;
110 std::map<Assignment::Target, ExpressionInfo> expressions;
111 ExpressionInfo *r_ref_info;
116 Block *iteration_body;
117 const Operator *r_oper;
125 void inline_expression(Expression &, RefPtr<Expression> &);
126 virtual void visit(Block &);
127 virtual void visit(RefPtr<Expression> &);
128 virtual void visit(VariableReference &);
129 virtual void visit(MemberAccess &);
130 virtual void visit(Swizzle &);
131 virtual void visit(UnaryExpression &);
132 virtual void visit(BinaryExpression &);
133 virtual void visit(Assignment &);
134 virtual void visit(TernaryExpression &);
135 virtual void visit(FunctionCall &);
136 virtual void visit(VariableDeclaration &);
137 virtual void visit(Iteration &);
140 /** Removes conditional statements and loops where the condition can be
141 determined as constant at compile time. */
142 class ConstantConditionEliminator: private TraversingVisitor
145 NodeList<Statement>::iterator insert_point;
146 std::set<Node *> nodes_to_remove;
152 virtual void visit(Block &);
153 virtual void visit(Conditional &);
154 virtual void visit(Iteration &);
157 /** Removes types which are not used anywhere. */
158 class UnusedTypeRemover: private TraversingVisitor
161 std::set<Node *> unused_nodes;
167 virtual void visit(Literal &);
168 virtual void visit(UnaryExpression &);
169 virtual void visit(BinaryExpression &);
170 virtual void visit(TernaryExpression &);
171 virtual void visit(FunctionCall &);
172 virtual void visit(BasicTypeDeclaration &);
173 virtual void visit(ImageTypeDeclaration &);
174 virtual void visit(StructDeclaration &);
175 virtual void visit(VariableDeclaration &);
176 virtual void visit(InterfaceBlock &);
177 virtual void visit(FunctionDeclaration &);
180 /** Removes variable declarations with no references to them. Assignment
181 statements where the result is not used are also removed. */
182 class UnusedVariableRemover: private TraversingVisitor
185 struct AssignmentInfo
188 Assignment::Target target;
189 std::vector<Node *> used_by;
191 AssignmentInfo(): node(0) { }
196 InterfaceBlock *interface_block;
197 std::vector<AssignmentInfo *> assignments;
202 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
205 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
208 BlockVariableMap variables;
209 std::list<AssignmentInfo> assignments;
210 InterfaceBlock *interface_block;
211 Assignment *r_assignment;
212 bool assignment_target;
214 std::set<Node *> unused_nodes;
217 UnusedVariableRemover();
222 void referenced(const Assignment::Target &, Node &);
223 virtual void visit(VariableReference &);
224 virtual void visit(InterfaceBlockReference &);
225 virtual void visit(UnaryExpression &);
226 virtual void visit(BinaryExpression &);
227 virtual void visit(Assignment &);
228 virtual void visit(FunctionCall &);
229 void record_assignment(const Assignment::Target &, Node &);
230 virtual void visit(ExpressionStatement &);
231 // Ignore structs because their members can't be accessed directly.
232 virtual void visit(StructDeclaration &) { }
233 virtual void visit(VariableDeclaration &);
234 virtual void visit(InterfaceBlock &);
235 void merge_variables(const BlockVariableMap &);
236 virtual void visit(FunctionDeclaration &);
237 virtual void visit(Conditional &);
238 virtual void visit(Iteration &);
241 /** Removes function declarations with no references to them. */
242 class UnusedFunctionRemover: private TraversingVisitor
245 std::set<Node *> unused_nodes;
246 std::set<FunctionDeclaration *> used_definitions;
249 bool apply(Stage &s);
252 virtual void visit(FunctionCall &);
253 virtual void visit(FunctionDeclaration &);