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 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;
104 const Operator *inner_oper;
105 const Operator *outer_oper;
113 std::map<Assignment::Target, ExpressionInfo> expressions;
114 ExpressionInfo *r_ref_info;
119 Block *iteration_body;
120 const Operator *r_oper;
128 void visit_and_record(RefPtr<Expression> &, const Operator *, bool);
129 void inline_expression(Expression &, RefPtr<Expression> &, const Operator *, const Operator *, bool);
130 virtual void visit(Block &);
131 virtual void visit(RefPtr<Expression> &);
132 virtual void visit(VariableReference &);
133 virtual void visit(MemberAccess &);
134 virtual void visit(Swizzle &);
135 virtual void visit(UnaryExpression &);
136 virtual void visit(BinaryExpression &);
137 virtual void visit(Assignment &);
138 virtual void visit(TernaryExpression &);
139 virtual void visit(FunctionCall &);
140 virtual void visit(VariableDeclaration &);
141 virtual void visit(Iteration &);
144 /** Removes conditional statements and loops where the condition can be
145 determined as constant at compile time. */
146 class ConstantConditionEliminator: private TraversingVisitor
149 NodeList<Statement>::iterator insert_point;
150 std::set<Node *> nodes_to_remove;
156 virtual void visit(Block &);
157 virtual void visit(Conditional &);
158 virtual void visit(Iteration &);
161 /** Removes types which are not used anywhere. */
162 class UnusedTypeRemover: private TraversingVisitor
165 std::set<Node *> unused_nodes;
171 virtual void visit(Literal &);
172 virtual void visit(UnaryExpression &);
173 virtual void visit(BinaryExpression &);
174 virtual void visit(TernaryExpression &);
175 virtual void visit(FunctionCall &);
176 virtual void visit(BasicTypeDeclaration &);
177 virtual void visit(ImageTypeDeclaration &);
178 virtual void visit(StructDeclaration &);
179 virtual void visit(VariableDeclaration &);
180 virtual void visit(InterfaceBlock &);
181 virtual void visit(FunctionDeclaration &);
184 /** Removes variable declarations with no references to them. Assignment
185 statements where the result is not used are also removed. */
186 class UnusedVariableRemover: private TraversingVisitor
189 struct AssignmentInfo
192 Assignment::Target target;
193 std::vector<Node *> used_by;
195 AssignmentInfo(): node(0) { }
200 InterfaceBlock *interface_block;
201 std::vector<AssignmentInfo *> assignments;
206 VariableInfo(): interface_block(0), initialized(false), output(false), referenced(false) { }
209 typedef std::map<Statement *, VariableInfo> BlockVariableMap;
212 BlockVariableMap variables;
213 std::list<AssignmentInfo> assignments;
214 InterfaceBlock *interface_block;
215 Assignment *r_assignment;
216 bool assignment_target;
218 std::set<Node *> unused_nodes;
221 UnusedVariableRemover();
226 void referenced(const Assignment::Target &, Node &);
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 virtual void visit(FunctionCall &);
233 void record_assignment(const Assignment::Target &, Node &);
234 virtual void visit(ExpressionStatement &);
235 // Ignore structs because their members can't be accessed directly.
236 virtual void visit(StructDeclaration &) { }
237 virtual void visit(VariableDeclaration &);
238 virtual void visit(InterfaceBlock &);
239 void merge_variables(const BlockVariableMap &);
240 virtual void visit(FunctionDeclaration &);
241 virtual void visit(Conditional &);
242 virtual void visit(Iteration &);
245 /** Removes function declarations with no references to them. */
246 class UnusedFunctionRemover: private TraversingVisitor
249 std::set<Node *> unused_nodes;
250 std::set<FunctionDeclaration *> used_definitions;
253 bool apply(Stage &s);
256 virtual void visit(FunctionCall &);
257 virtual void visit(FunctionDeclaration &);