]> git.tdb.fi Git - libs/gl.git/blob - source/programcompiler.h
Further reduce overhead of applying ProgramCompiler visitors
[libs/gl.git] / source / programcompiler.h
1 #ifndef MSP_GL_PROGRAMCOMPILER_H_
2 #define MSP_GL_PROGRAMCOMPILER_H_
3
4 #include <set>
5 #include "programparser.h"
6 #include "programsyntax.h"
7
8 namespace Msp {
9 namespace GL {
10
11 class Program;
12
13 class ProgramCompiler
14 {
15 private:
16         struct Visitor: ProgramSyntax::TraversingVisitor
17         {
18                 typedef void ResultType;
19
20                 ProgramSyntax::Stage *stage;
21
22                 Visitor();
23
24                 virtual void apply(ProgramSyntax::Stage &);
25                 void get_result() const { }
26         };
27
28         struct Formatter: Visitor
29         {
30                 typedef std::string ResultType;
31
32                 std::string formatted;
33                 unsigned indent;
34                 bool parameter_list;
35                 unsigned else_if;
36                 std::string block_interface;
37
38                 Formatter();
39
40                 const std::string &get_result() const { return formatted; }
41                 virtual void visit(ProgramSyntax::Block &);
42                 virtual void visit(ProgramSyntax::Literal &);
43                 virtual void visit(ProgramSyntax::ParenthesizedExpression &);
44                 virtual void visit(ProgramSyntax::VariableReference &);
45                 virtual void visit(ProgramSyntax::MemberAccess &);
46                 virtual void visit(ProgramSyntax::UnaryExpression &);
47                 virtual void visit(ProgramSyntax::BinaryExpression &);
48                 virtual void visit(ProgramSyntax::Assignment &);
49                 virtual void visit(ProgramSyntax::FunctionCall &);
50                 virtual void visit(ProgramSyntax::ExpressionStatement &);
51                 virtual void visit(ProgramSyntax::Layout &);
52                 virtual void visit(ProgramSyntax::StructDeclaration &);
53                 virtual void visit(ProgramSyntax::VariableDeclaration &);
54                 virtual void visit(ProgramSyntax::InterfaceBlock &);
55                 virtual void visit(ProgramSyntax::FunctionDeclaration &);
56                 virtual void visit(ProgramSyntax::Conditional &);
57                 virtual void visit(ProgramSyntax::Iteration &);
58                 virtual void visit(ProgramSyntax::Return &);
59         };
60
61         struct VariableResolver: Visitor
62         {
63                 std::vector<ProgramSyntax::Block *> blocks;
64                 ProgramSyntax::StructDeclaration *type;
65                 bool anonymous;
66                 std::string block_interface;
67                 bool record_target;
68                 ProgramSyntax::VariableDeclaration *assignment_target;
69                 bool self_referencing;
70
71                 VariableResolver();
72
73                 virtual void apply(ProgramSyntax::Stage &);
74                 virtual void visit(ProgramSyntax::Block &);
75                 virtual void visit(ProgramSyntax::VariableReference &);
76                 virtual void visit(ProgramSyntax::MemberAccess &);
77                 virtual void visit(ProgramSyntax::BinaryExpression &);
78                 virtual void visit(ProgramSyntax::Assignment &);
79                 virtual void visit(ProgramSyntax::StructDeclaration &);
80                 virtual void visit(ProgramSyntax::VariableDeclaration &);
81                 virtual void visit(ProgramSyntax::InterfaceBlock &);
82         };
83
84         struct InterfaceGenerator: Visitor
85         {
86                 std::string in_prefix;
87                 std::string out_prefix;
88                 unsigned scope_level;
89                 std::map<std::string, ProgramSyntax::VariableDeclaration *> iface_declarations;
90                 bool remove_node;
91                 std::list<ProgramSyntax::Node *> insert_nodes;
92
93                 InterfaceGenerator();
94
95                 static std::string get_out_prefix(ProgramSyntax::StageType);
96                 virtual void apply(ProgramSyntax::Stage &);
97                 virtual void visit(ProgramSyntax::Block &);
98                 std::string change_prefix(const std::string &, const std::string &) const;
99                 bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &);
100                 void insert_assignment(const std::string &, ProgramSyntax::Expression *);
101                 virtual void visit(ProgramSyntax::VariableReference &);
102                 virtual void visit(ProgramSyntax::VariableDeclaration &);
103                 virtual void visit(ProgramSyntax::Passthrough &);
104         };
105
106         struct VariableRenamer: Visitor
107         {
108                 virtual void visit(ProgramSyntax::VariableReference &);
109                 virtual void visit(ProgramSyntax::VariableDeclaration &);
110         };
111
112         struct UnusedVariableLocator: Visitor
113         {
114                 struct AssignmentList
115                 {
116                         std::vector<ProgramSyntax::Node *> nodes;
117                         bool conditional;
118                         bool self_referencing;
119                 };
120
121                 typedef std::set<ProgramSyntax::Node *> ResultType;
122                 typedef std::map<ProgramSyntax::VariableDeclaration *, AssignmentList> BlockAssignmentMap;
123
124                 std::set<ProgramSyntax::Node *> unused_nodes;
125                 std::map<ProgramSyntax::VariableDeclaration *, ProgramSyntax::Node *> aggregates;
126                 ProgramSyntax::Node *aggregate;
127                 std::vector<BlockAssignmentMap> assignments;
128                 ProgramSyntax::Assignment *assignment;
129                 bool assignment_target;
130
131                 UnusedVariableLocator();
132
133                 virtual void apply(ProgramSyntax::Stage &);
134                 const ResultType &get_result() const { return unused_nodes; }
135                 virtual void visit(ProgramSyntax::VariableReference &);
136                 virtual void visit(ProgramSyntax::MemberAccess &);
137                 virtual void visit(ProgramSyntax::BinaryExpression &);
138                 virtual void visit(ProgramSyntax::Assignment &);
139                 void record_assignment(ProgramSyntax::VariableDeclaration &, ProgramSyntax::Node &, bool);
140                 virtual void visit(ProgramSyntax::ExpressionStatement &);
141                 virtual void visit(ProgramSyntax::StructDeclaration &);
142                 virtual void visit(ProgramSyntax::VariableDeclaration &);
143                 virtual void visit(ProgramSyntax::InterfaceBlock &);
144                 virtual void visit(ProgramSyntax::FunctionDeclaration &);
145                 void merge_down_assignments();
146                 virtual void visit(ProgramSyntax::Conditional &);
147                 virtual void visit(ProgramSyntax::Iteration &);
148         };
149
150         struct NodeRemover: Visitor
151         {
152                 std::set<ProgramSyntax::Node *> to_remove;
153
154                 NodeRemover() { }
155                 NodeRemover(const std::set<ProgramSyntax::Node *> &);
156
157                 virtual void visit(ProgramSyntax::Block &);
158                 virtual void visit(ProgramSyntax::VariableDeclaration &);
159         };
160
161         ProgramParser parser;
162         ProgramSyntax::Module *module;
163
164 public:
165         ProgramCompiler();
166
167         void compile(const std::string &);
168         void compile(IO::Base &);
169         void add_shaders(Program &);
170
171 private:
172         static ProgramSyntax::Module *create_builtins_module();
173         static ProgramSyntax::Module &get_builtins_module();
174         static ProgramSyntax::Stage *get_builtins(ProgramSyntax::StageType);
175         void process();
176         void generate(ProgramSyntax::Stage &);
177         bool optimize(ProgramSyntax::Stage &);
178         static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
179         template<typename T>
180         static typename T::ResultType apply(ProgramSyntax::Stage &);
181         template<typename T, typename A>
182         static typename T::ResultType apply(ProgramSyntax::Stage &, const A &);
183 };
184
185 } // namespace GL
186 } // namespace Msp
187
188 #endif