]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/optimize.h
Refactor FunctionInliner to do any necessary declaration reordering
[libs/gl.git] / source / glsl / optimize.h
1 #ifndef MSP_GL_SL_OPTIMIZE_H_
2 #define MSP_GL_SL_OPTIMIZE_H_
3
4 #include <map>
5 #include <set>
6 #include "evaluate.h"
7 #include "visitor.h"
8
9 namespace Msp {
10 namespace GL {
11 namespace SL {
12
13 /** Finds functions which are candidates for inlining.  Currently this means
14 functions which have no parameters and are only called once. */
15 class InlineableFunctionLocator: private TraversingVisitor
16 {
17 private:
18         std::map<FunctionDeclaration *, unsigned> refcounts;
19         std::set<FunctionDeclaration *> inlineable;
20         FunctionDeclaration *in_function;
21
22 public:
23         InlineableFunctionLocator();
24
25         const std::set<FunctionDeclaration *> &apply(Stage &s) { s.content.visit(*this); return inlineable; }
26
27 private:
28         virtual void visit(FunctionCall &);
29         virtual void visit(FunctionDeclaration &);
30 };
31
32 /** Collects declarations referenced by a function. */
33 class InlineDependencyCollector: private TraversingVisitor
34 {
35 private:
36         std::set<Node *> dependencies;
37
38 public:
39         const std::set<Node *> &apply(FunctionDeclaration &f) { f.visit(*this); return dependencies; }
40
41 private:
42         virtual void visit(VariableReference &);
43         virtual void visit(InterfaceBlockReference &);
44         virtual void visit(FunctionCall &);
45         virtual void visit(VariableDeclaration &);
46 };
47
48 /** Inlines functions.  Internally uses InlineableFunctionLocator to find
49 candidate functions.  Only functions which consist of a single return statement
50 are inlined. */
51 class FunctionInliner: private TraversingVisitor
52 {
53 private:
54         Stage *stage;
55         std::set<FunctionDeclaration *> inlineable;
56         FunctionDeclaration *current_function;
57         unsigned extract_result;
58         RefPtr<Expression> inline_result;
59         bool any_inlined;
60
61 public:
62         FunctionInliner();
63
64         bool apply(Stage &);
65
66 private:
67         void visit_and_inline(RefPtr<Expression> &);
68
69         virtual void visit(Block &);
70         virtual void visit(UnaryExpression &);
71         virtual void visit(BinaryExpression &);
72         virtual void visit(MemberAccess &);
73         virtual void visit(FunctionCall &);
74         virtual void visit(VariableDeclaration &);
75         virtual void visit(FunctionDeclaration &);
76         virtual void visit(Return &);
77 };
78
79 /** Removes conditional statements and loops where the condition can be
80 determined as constant at compile time. */
81 class ConstantConditionEliminator: private TraversingVisitor
82 {
83 private:
84         bool record_only;
85         ExpressionEvaluator::ValueMap variable_values;
86         NodeList<Statement>::iterator insert_point;
87         std::set<Node *> nodes_to_remove;
88
89 public:
90         ConstantConditionEliminator();
91
92         void apply(Stage &);
93
94 private:
95         virtual void visit(Block &);
96         virtual void visit(UnaryExpression &);
97         virtual void visit(Assignment &);
98         virtual void visit(VariableDeclaration &);
99         virtual void visit(Conditional &);
100         virtual void visit(Iteration &);
101 };
102
103 /** Removes variable declarations with no references to them.  Assignment
104 statements where the result is not used are also removed. */
105 class UnusedVariableRemover: private TraversingVisitor
106 {
107 private:
108         struct VariableInfo
109         {
110                 bool local;
111                 std::vector<Node *> assignments;
112                 bool conditionally_assigned;
113                 bool referenced;
114
115                 VariableInfo();
116         };
117
118         typedef std::map<VariableDeclaration *, VariableInfo> BlockVariableMap;
119
120         std::set<Node *> unused_nodes;
121         std::map<VariableDeclaration *, Node *> aggregates;
122         Node *aggregate;
123         std::vector<BlockVariableMap> variables;
124         Assignment *assignment;
125         bool assignment_target;
126         bool assign_to_subscript;
127
128 public:
129         UnusedVariableRemover();
130
131         bool apply(Stage &);
132
133 private:
134         virtual void visit(VariableReference &);
135         virtual void visit(InterfaceBlockReference &);
136         virtual void visit(MemberAccess &);
137         virtual void visit(BinaryExpression &);
138         virtual void visit(Assignment &);
139         void record_assignment(VariableDeclaration &, Node &, bool);
140         void clear_assignments(VariableInfo &, bool);
141         virtual void visit(ExpressionStatement &);
142         virtual void visit(StructDeclaration &);
143         virtual void visit(VariableDeclaration &);
144         virtual void visit(InterfaceBlock &);
145         virtual void visit(FunctionDeclaration &);
146         void merge_down_variables();
147         virtual void visit(Conditional &);
148         virtual void visit(Iteration &);
149 };
150
151 /** Removes function declarations with no references to them. */
152 class UnusedFunctionRemover: private TraversingVisitor
153 {
154 private:
155         std::set<Node *> unused_nodes;
156         std::set<FunctionDeclaration *> used_definitions;
157
158 public:
159         bool apply(Stage &s);
160
161 private:
162         virtual void visit(FunctionCall &);
163         virtual void visit(FunctionDeclaration &);
164 };
165
166 } // namespace SL
167 } // namespace GL
168 } // namespace Msp
169
170 #endif