]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programcompiler.cpp
Remove unused functions from the shader source
[libs/gl.git] / source / programcompiler.cpp
index 9b3266755b0b4f36c7bdc1ebe3471ebba48e8d40..937639a49157bf6f73cda381d306585e1c05b482 100644 (file)
@@ -159,6 +159,7 @@ void ProgramCompiler::generate(Stage &stage)
 {
        inject_block(stage.content, module->shared.content);
 
+       apply<FunctionResolver>(stage);
        apply<VariableResolver>(stage);
        apply<InterfaceGenerator>(stage);
        apply<VariableResolver>(stage);
@@ -171,6 +172,8 @@ bool ProgramCompiler::optimize(Stage &stage)
        apply<VariableResolver>(stage);
 
        set<Node *> unused = apply<UnusedVariableLocator>(stage);
+       set<Node *> unused2 = apply<UnusedFunctionLocator>(stage);
+       unused.insert(unused2.begin(), unused2.end());
        apply<NodeRemover>(stage, unused);
 
        return !unused.empty();
@@ -616,6 +619,34 @@ void ProgramCompiler::VariableResolver::visit(InterfaceBlock &iface)
 }
 
 
+void ProgramCompiler::FunctionResolver::visit(FunctionCall &call)
+{
+       map<string, vector<FunctionDeclaration *> >::iterator i = functions.find(call.name);
+       if(i!=functions.end())
+               call.declaration = i->second.back();
+
+       TraversingVisitor::visit(call);
+}
+
+void ProgramCompiler::FunctionResolver::visit(FunctionDeclaration &func)
+{
+       vector<FunctionDeclaration *> &decls = functions[func.name];
+       if(func.definition)
+       {
+               for(vector<FunctionDeclaration *>::iterator i=decls.begin(); i!=decls.end(); ++i)
+                       (*i)->definition = func.definition;
+               decls.clear();
+               decls.push_back(&func);
+       }
+       else if(!decls.empty() && decls.back()->definition)
+               func.definition = decls.back()->definition;
+       else
+               decls.push_back(&func);
+
+       TraversingVisitor::visit(func);
+}
+
+
 ProgramCompiler::InterfaceGenerator::InterfaceGenerator():
        scope_level(0),
        remove_node(false)
@@ -1198,6 +1229,24 @@ void ProgramCompiler::UnusedVariableLocator::visit(Iteration &iter)
 }
 
 
+void ProgramCompiler::UnusedFunctionLocator::visit(FunctionCall &call)
+{
+       TraversingVisitor::visit(call);
+
+       unused_nodes.erase(call.declaration);
+       if(call.declaration && call.declaration->definition!=call.declaration)
+               used_definitions.insert(call.declaration->definition);
+}
+
+void ProgramCompiler::UnusedFunctionLocator::visit(FunctionDeclaration &func)
+{
+       TraversingVisitor::visit(func);
+
+       if(func.name!="main" && !used_definitions.count(&func))
+               unused_nodes.insert(&func);
+}
+
+
 ProgramCompiler::NodeRemover::NodeRemover(const set<Node *> &r):
        to_remove(r)
 { }