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(MemberAccess &);
92 virtual void visit(FunctionCall &);
93 virtual void visit(ExpressionStatement &);
94 virtual void visit(VariableDeclaration &);
95 virtual void visit(FunctionDeclaration &);
96 virtual void visit(Conditional &);
97 virtual void visit(Iteration &);
98 virtual void visit(Return &);
101 /** Inlines variables into expressions. Variables with trivial values (those
102 consisting of a single literal or variable reference) are always inlined.
103 Variables which are only referenced once are also inlined. */
104 class ExpressionInliner: private TraversingVisitor
107 struct ExpressionInfo
109 Expression *expression;
111 RefPtr<Expression> *inline_point;
112 const Operator *inner_oper;
113 const Operator *outer_oper;
121 std::map<VariableDeclaration *, ExpressionInfo> expressions;
122 ExpressionInfo *r_ref_info;
127 Block *iteration_body;
128 const Operator *r_oper;
136 void visit_and_record(RefPtr<Expression> &, const Operator *, bool);
137 void inline_expression(Expression &, RefPtr<Expression> &, const Operator *, const Operator *, bool);
138 virtual void visit(Block &);
139 virtual void visit(VariableReference &);
140 virtual void visit(MemberAccess &);
141 virtual void visit(UnaryExpression &);
142 virtual void visit(BinaryExpression &);
143 virtual void visit(Assignment &);
144 virtual void visit(FunctionCall &);
145 virtual void visit(VariableDeclaration &);
146 virtual void visit(Conditional &);
147 virtual void visit(Iteration &);
148 virtual void visit(Return &);
151 /** Removes conditional statements and loops where the condition can be
152 determined as constant at compile time. */
153 class ConstantConditionEliminator: private TraversingVisitor
156 NodeList<Statement>::iterator insert_point;
157 std::set<Node *> nodes_to_remove;
163 virtual void visit(Block &);
164 virtual void visit(Conditional &);
165 virtual void visit(Iteration &);
168 /** Removes variable declarations with no references to them. Assignment
169 statements where the result is not used are also removed. */
170 class UnusedVariableRemover: private TraversingVisitor
176 std::vector<Node *> assignments;
177 bool conditionally_assigned;
183 typedef std::map<VariableDeclaration *, VariableInfo> BlockVariableMap;
185 std::set<Node *> unused_nodes;
186 std::map<VariableDeclaration *, Node *> aggregates;
188 std::vector<BlockVariableMap> variables;
189 Assignment *r_assignment;
190 bool assignment_target;
191 bool r_assign_to_subfield;
195 UnusedVariableRemover();
200 virtual void visit(VariableReference &);
201 virtual void visit(InterfaceBlockReference &);
202 virtual void visit(MemberAccess &);
203 virtual void visit(UnaryExpression &);
204 virtual void visit(BinaryExpression &);
205 virtual void visit(Assignment &);
206 void record_assignment(VariableDeclaration &, Node &, bool);
207 void clear_assignments(VariableInfo &, bool);
208 virtual void visit(FunctionCall &);
209 virtual void visit(ExpressionStatement &);
210 virtual void visit(StructDeclaration &);
211 virtual void visit(VariableDeclaration &);
212 virtual void visit(InterfaceBlock &);
213 virtual void visit(FunctionDeclaration &);
214 void merge_down_variables();
215 virtual void visit(Conditional &);
216 virtual void visit(Iteration &);
219 /** Removes function declarations with no references to them. */
220 class UnusedFunctionRemover: private TraversingVisitor
223 std::set<Node *> unused_nodes;
224 std::set<FunctionDeclaration *> used_definitions;
227 bool apply(Stage &s);
230 virtual void visit(FunctionCall &);
231 virtual void visit(FunctionDeclaration &);