X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fprogramcompiler.cpp;h=f7d231615618178cecbcaf68ecf49caa2ae5835b;hb=02c1541c20adf36ea09825dc7bc745f8487c4bc8;hp=79031e41eeda0cc970162d3632c31eaadd253ae5;hpb=b3e71de19f35773c22391151ebb02062d6894bc9;p=libs%2Fgl.git diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 79031e41..f7d23161 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -55,8 +55,13 @@ void ProgramCompiler::process() { for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) generate(*i); - for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) - optimize(*i); + for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ) + { + if(optimize(*i)) + i = module->stages.begin(); + else + ++i; + } } void ProgramCompiler::generate(Stage &stage) @@ -69,20 +74,16 @@ void ProgramCompiler::generate(Stage &stage) apply(stage); } -void ProgramCompiler::optimize(Stage &stage) +bool ProgramCompiler::optimize(Stage &stage) { - while(1) - { - UnusedVariableLocator unused_locator; - unused_locator.apply(stage); + UnusedVariableLocator unused_locator; + unused_locator.apply(stage); - NodeRemover remover; - remover.to_remove = unused_locator.unused_nodes; - remover.apply(stage); + NodeRemover remover; + remover.to_remove = unused_locator.unused_nodes; + remover.apply(stage); - if(!remover.n_removed) - break; - } + return !unused_locator.unused_nodes.empty(); } void ProgramCompiler::inject_block(Block &target, const Block &source) @@ -625,24 +626,41 @@ void ProgramCompiler::VariableRenamer::visit(VariableDeclaration &var) ProgramCompiler::UnusedVariableLocator::UnusedVariableLocator(): + aggregate(0), assignment(false), - assignment_target(0) + record_target(false), + assignment_target(0), + indeterminate_target(false), + self_referencing(false) { } void ProgramCompiler::UnusedVariableLocator::visit(VariableReference &var) { - if(assignment) - assignment_target = var.declaration; + if(record_target) + { + if(assignment_target) + indeterminate_target = true; + else + assignment_target = var.declaration; + } else { unused_nodes.erase(var.declaration); + map::iterator i = assignments.find(var.declaration); if(i!=assignments.end()) { unused_nodes.erase(i->second); assignments.erase(i); } + + if(assignment && var.declaration==assignment_target) + self_referencing = true; } + + map::iterator i = aggregates.find(var.declaration); + if(i!=aggregates.end()) + unused_nodes.erase(i->second); } void ProgramCompiler::UnusedVariableLocator::visit(MemberAccess &memacc) @@ -655,9 +673,20 @@ void ProgramCompiler::UnusedVariableLocator::visit(BinaryExpression &binary) { if(binary.assignment) { - binary.right->visit(*this); assignment = true; + { + SetFlag set(record_target); + binary.left->visit(*this); + } + if(binary.oper!="=") + self_referencing = true; + binary.right->visit(*this); + } + else if(record_target && binary.oper=="[") + { binary.left->visit(*this); + SetForScope set(record_target, false); + binary.right->visit(*this); } else TraversingVisitor::visit(binary); @@ -667,60 +696,69 @@ void ProgramCompiler::UnusedVariableLocator::visit(ExpressionStatement &expr) { assignment = false; assignment_target = 0; + indeterminate_target = false; + self_referencing = false; TraversingVisitor::visit(expr); - if(assignment && assignment_target) + if(assignment && assignment_target && !indeterminate_target) { Node *&assign = assignments[assignment_target]; - if(assign) + if(self_referencing) + unused_nodes.erase(assign); + else if(assign) unused_nodes.insert(assign); assign = &expr; - if(assignment_target->interface!="out" || (stage->type!=FRAGMENT && !assignment_target->linked_declaration)) - unused_nodes.insert(&expr); - else + if(assignment_target->interface=="out" && (stage->type==FRAGMENT || assignment_target->linked_declaration)) unused_nodes.erase(assignment_target); + else + unused_nodes.insert(&expr); } assignment = false; } +void ProgramCompiler::UnusedVariableLocator::visit(StructDeclaration &strct) +{ + SetForScope set(aggregate, &strct); + unused_nodes.insert(&strct); + TraversingVisitor::visit(strct); +} + void ProgramCompiler::UnusedVariableLocator::visit(VariableDeclaration &var) { - unused_nodes.insert(&var); + if(aggregate) + aggregates[&var] = aggregate; + else + { + unused_nodes.insert(&var); + if(var.init_expression) + { + unused_nodes.insert(&*var.init_expression); + assignments[&var] = &*var.init_expression; + } + } + unused_nodes.erase(var.type_declaration); TraversingVisitor::visit(var); } +void ProgramCompiler::UnusedVariableLocator::visit(InterfaceBlock &iface) +{ + SetForScope set(aggregate, &iface); + unused_nodes.insert(&iface); + TraversingVisitor::visit(iface); +} -ProgramCompiler::NodeRemover::NodeRemover(): - n_removed(0), - immutable_block(false), - remove_block(false) -{ } void ProgramCompiler::NodeRemover::visit(Block &block) { - remove_block = immutable_block; for(list >::iterator i=block.body.begin(); i!=block.body.end(); ) { - bool remove = to_remove.count(&**i); - if(!remove) - remove_block = false; (*i)->visit(*this); - - if(remove ? !immutable_block : remove_block) - { + if(to_remove.count(&**i)) block.body.erase(i++); - ++n_removed; - } else ++i; } } -void ProgramCompiler::NodeRemover::visit(StructDeclaration &strct) -{ - SetFlag set(immutable_block); - TraversingVisitor::visit(strct); -} - void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) { if(to_remove.count(&var)) @@ -730,12 +768,8 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) if(var.linked_declaration) var.linked_declaration->linked_declaration = 0; } -} - -void ProgramCompiler::NodeRemover::visit(InterfaceBlock &iface) -{ - SetFlag set(immutable_block); - TraversingVisitor::visit(iface); + else if(var.init_expression && to_remove.count(&*var.init_expression)) + var.init_expression = 0; } } // namespace GL