]> git.tdb.fi Git - libs/gl.git/commitdiff
Further reduce overhead of applying ProgramCompiler visitors
authorMikko Rasa <tdb@tdb.fi>
Mon, 14 Nov 2016 11:41:46 +0000 (13:41 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 14 Nov 2016 11:45:23 +0000 (13:45 +0200)
source/programcompiler.cpp
source/programcompiler.h

index a730f74348f072fab4edd1398835b380b4295af4..63939409fc4c7d28c6f38cc031925cacb919257f 100644 (file)
@@ -58,11 +58,11 @@ void ProgramCompiler::add_shaders(Program &program)
        for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
        {
                if(i->type==VERTEX)
-                       program.attach_shader_owned(new VertexShader(head+create_source(*i)));
+                       program.attach_shader_owned(new VertexShader(head+apply<Formatter>(*i)));
                else if(i->type==GEOMETRY)
-                       program.attach_shader_owned(new GeometryShader(head+create_source(*i)));
+                       program.attach_shader_owned(new GeometryShader(head+apply<Formatter>(*i)));
                else if(i->type==FRAGMENT)
-                       program.attach_shader_owned(new FragmentShader(head+create_source(*i)));
+                       program.attach_shader_owned(new FragmentShader(head+apply<Formatter>(*i)));
        }
 
        program.bind_attribute(VERTEX4, "vertex");
@@ -125,14 +125,10 @@ void ProgramCompiler::generate(Stage &stage)
 
 bool ProgramCompiler::optimize(Stage &stage)
 {
-       UnusedVariableLocator unused_locator;
-       unused_locator.apply(stage);
+       set<Node *> unused = apply<UnusedVariableLocator>(stage);
+       apply<NodeRemover>(stage, unused);
 
-       NodeRemover remover;
-       remover.to_remove = unused_locator.unused_nodes;
-       remover.apply(stage);
-
-       return !unused_locator.unused_nodes.empty();
+       return !unused.empty();
 }
 
 void ProgramCompiler::inject_block(Block &target, const Block &source)
@@ -143,17 +139,19 @@ void ProgramCompiler::inject_block(Block &target, const Block &source)
 }
 
 template<typename T>
-void ProgramCompiler::apply(Stage &stage)
+typename T::ResultType ProgramCompiler::apply(Stage &stage)
 {
        T visitor;
        visitor.apply(stage);
+       return visitor.get_result();
 }
 
-string ProgramCompiler::create_source(Stage &stage)
+template<typename T, typename A>
+typename T::ResultType ProgramCompiler::apply(Stage &stage, const A &arg)
 {
-       Formatter formatter;
-       formatter.apply(stage);
-       return formatter.formatted;
+       T visitor(arg);
+       visitor.apply(stage);
+       return visitor.get_result();
 }
 
 
@@ -944,6 +942,10 @@ void ProgramCompiler::UnusedVariableLocator::visit(Iteration &iter)
 }
 
 
+ProgramCompiler::NodeRemover::NodeRemover(const set<Node *> &r):
+       to_remove(r)
+{ }
+
 void ProgramCompiler::NodeRemover::visit(Block &block)
 {
        for(list<NodePtr<Node> >::iterator i=block.body.begin(); i!=block.body.end(); )
index a2dd9401256a34c7659800765f8cf25ca56a8313..2ef4aa7d9b77c5f853968da6e4e9dbc310c9abec 100644 (file)
@@ -15,15 +15,20 @@ class ProgramCompiler
 private:
        struct Visitor: ProgramSyntax::TraversingVisitor
        {
+               typedef void ResultType;
+
                ProgramSyntax::Stage *stage;
 
                Visitor();
 
                virtual void apply(ProgramSyntax::Stage &);
+               void get_result() const { }
        };
 
        struct Formatter: Visitor
        {
+               typedef std::string ResultType;
+
                std::string formatted;
                unsigned indent;
                bool parameter_list;
@@ -32,6 +37,7 @@ private:
 
                Formatter();
 
+               const std::string &get_result() const { return formatted; }
                virtual void visit(ProgramSyntax::Block &);
                virtual void visit(ProgramSyntax::Literal &);
                virtual void visit(ProgramSyntax::ParenthesizedExpression &);
@@ -112,6 +118,7 @@ private:
                        bool self_referencing;
                };
 
+               typedef std::set<ProgramSyntax::Node *> ResultType;
                typedef std::map<ProgramSyntax::VariableDeclaration *, AssignmentList> BlockAssignmentMap;
 
                std::set<ProgramSyntax::Node *> unused_nodes;
@@ -124,6 +131,7 @@ private:
                UnusedVariableLocator();
 
                virtual void apply(ProgramSyntax::Stage &);
+               const ResultType &get_result() const { return unused_nodes; }
                virtual void visit(ProgramSyntax::VariableReference &);
                virtual void visit(ProgramSyntax::MemberAccess &);
                virtual void visit(ProgramSyntax::BinaryExpression &);
@@ -143,6 +151,9 @@ private:
        {
                std::set<ProgramSyntax::Node *> to_remove;
 
+               NodeRemover() { }
+               NodeRemover(const std::set<ProgramSyntax::Node *> &);
+
                virtual void visit(ProgramSyntax::Block &);
                virtual void visit(ProgramSyntax::VariableDeclaration &);
        };
@@ -166,8 +177,9 @@ private:
        bool optimize(ProgramSyntax::Stage &);
        static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
        template<typename T>
-       static void apply(ProgramSyntax::Stage &);
-       std::string create_source(ProgramSyntax::Stage &);
+       static typename T::ResultType apply(ProgramSyntax::Stage &);
+       template<typename T, typename A>
+       static typename T::ResultType apply(ProgramSyntax::Stage &, const A &);
 };
 
 } // namespace GL