X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=1f5b5d317c720993b91f2dbc5dd8fb880417cd7c;hb=5c33b56c3b97ca0381ac216a603c7553f4bea499;hp=25115a5975674485afb4f0b8e1368250419be451;hpb=696a97bd7411d69953c1a9e4b5f3dfb4c1d848f1;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 25115a59..1f5b5d31 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -43,10 +43,11 @@ FunctionInliner::FunctionInliner(): extract_result(0) { } -FunctionInliner::FunctionInliner(const set &in): - inlineable(in), - extract_result(0) -{ } +void FunctionInliner::apply(Stage &stage) +{ + inlineable = InlineableFunctionLocator().apply(stage); + stage.content.visit(*this); +} void FunctionInliner::visit_and_inline(RefPtr &ptr) { @@ -123,14 +124,23 @@ void FunctionInliner::visit(Return &ret) ConstantConditionEliminator::ConstantConditionEliminator(): - scope_level(0), record_only(false) { } +void ConstantConditionEliminator::apply(Stage &stage) +{ + stage.content.visit(*this); + NodeRemover().apply(stage, nodes_to_remove); +} + void ConstantConditionEliminator::visit(Block &block) { - SetForScope set(scope_level, scope_level+1); - BlockModifier::visit(block); + SetForScope set_block(current_block, &block); + for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) + { + insert_point = i; + (*i)->visit(*this); + } for(map::const_iterator i=block.variables.begin(); i!=block.variables.end(); ++i) variable_values.erase(i->second); @@ -150,7 +160,7 @@ void ConstantConditionEliminator::visit(Assignment &assign) void ConstantConditionEliminator::visit(VariableDeclaration &var) { - if(var.constant || scope_level>1) + if(var.constant || current_block->parent) variable_values[&var] = var.init_expression.get(); } @@ -162,7 +172,9 @@ void ConstantConditionEliminator::visit(Conditional &cond) cond.condition->visit(eval); if(eval.is_result_valid()) { - flatten_block(eval.get_result() ? cond.body : cond.else_body); + Block &block = (eval.get_result() ? cond.body : cond.else_body); + current_block->body.splice(insert_point, block.body); + nodes_to_remove.insert(&cond); return; } } @@ -184,7 +196,7 @@ void ConstantConditionEliminator::visit(Iteration &iter) iter.condition->visit(eval); if(eval.is_result_valid() && !eval.get_result()) { - remove_node = true; + nodes_to_remove.insert(&iter); return; } } @@ -202,29 +214,28 @@ void ConstantConditionEliminator::visit(Iteration &iter) } -UnusedVariableLocator::VariableInfo::VariableInfo(): +UnusedVariableRemover::VariableInfo::VariableInfo(): local(false), conditionally_assigned(false), referenced(false) { } -UnusedVariableLocator::UnusedVariableLocator(): +UnusedVariableRemover::UnusedVariableRemover(): aggregate(0), assignment(0), assignment_target(false), - assign_to_subscript(false), - global_scope(true) + assign_to_subscript(false) { } -void UnusedVariableLocator::apply(Stage &s) +bool UnusedVariableRemover::apply(Stage &stage) { variables.push_back(BlockVariableMap()); - StageVisitor::apply(s); + stage.content.visit(*this); BlockVariableMap &global_variables = variables.back(); for(BlockVariableMap::iterator i=global_variables.begin(); i!=global_variables.end(); ++i) { - if(i->first->interface=="out" && (s.type==FRAGMENT || i->first->linked_declaration || !i->first->name.compare(0, 3, "gl_"))) + if(i->first->interface=="out" && (stage.type==Stage::FRAGMENT || i->first->linked_declaration || !i->first->name.compare(0, 3, "gl_"))) continue; if(!i->second.referenced) { @@ -233,9 +244,13 @@ void UnusedVariableLocator::apply(Stage &s) } } variables.pop_back(); + + NodeRemover().apply(stage, unused_nodes); + + return !unused_nodes.empty(); } -void UnusedVariableLocator::visit(VariableReference &var) +void UnusedVariableRemover::visit(VariableReference &var) { map::iterator i = aggregates.find(var.declaration); if(i!=aggregates.end()) @@ -249,13 +264,13 @@ void UnusedVariableLocator::visit(VariableReference &var) } } -void UnusedVariableLocator::visit(MemberAccess &memacc) +void UnusedVariableRemover::visit(MemberAccess &memacc) { TraversingVisitor::visit(memacc); unused_nodes.erase(memacc.declaration); } -void UnusedVariableLocator::visit(BinaryExpression &binary) +void UnusedVariableRemover::visit(BinaryExpression &binary) { if(binary.oper=="[") { @@ -269,7 +284,7 @@ void UnusedVariableLocator::visit(BinaryExpression &binary) TraversingVisitor::visit(binary); } -void UnusedVariableLocator::visit(Assignment &assign) +void UnusedVariableRemover::visit(Assignment &assign) { { assign_to_subscript = false; @@ -280,7 +295,7 @@ void UnusedVariableLocator::visit(Assignment &assign) assignment = &assign; } -void UnusedVariableLocator::record_assignment(VariableDeclaration &var, Node &node, bool chained) +void UnusedVariableRemover::record_assignment(VariableDeclaration &var, Node &node, bool chained) { VariableInfo &var_info = variables.back()[&var]; if(!chained) @@ -289,7 +304,7 @@ void UnusedVariableLocator::record_assignment(VariableDeclaration &var, Node &no var_info.conditionally_assigned = false; } -void UnusedVariableLocator::clear_assignments(VariableInfo &var_info, bool mark_unused) +void UnusedVariableRemover::clear_assignments(VariableInfo &var_info, bool mark_unused) { if(mark_unused) { @@ -299,7 +314,7 @@ void UnusedVariableLocator::clear_assignments(VariableInfo &var_info, bool mark_ var_info.assignments.clear(); } -void UnusedVariableLocator::visit(ExpressionStatement &expr) +void UnusedVariableRemover::visit(ExpressionStatement &expr) { assignment = 0; TraversingVisitor::visit(expr); @@ -307,14 +322,14 @@ void UnusedVariableLocator::visit(ExpressionStatement &expr) record_assignment(*assignment->target_declaration, expr, (assignment->self_referencing || assign_to_subscript)); } -void UnusedVariableLocator::visit(StructDeclaration &strct) +void UnusedVariableRemover::visit(StructDeclaration &strct) { SetForScope set(aggregate, &strct); unused_nodes.insert(&strct); TraversingVisitor::visit(strct); } -void UnusedVariableLocator::visit(VariableDeclaration &var) +void UnusedVariableRemover::visit(VariableDeclaration &var) { if(aggregate) aggregates[&var] = aggregate; @@ -328,23 +343,20 @@ void UnusedVariableLocator::visit(VariableDeclaration &var) TraversingVisitor::visit(var); } -void UnusedVariableLocator::visit(InterfaceBlock &iface) +void UnusedVariableRemover::visit(InterfaceBlock &iface) { SetForScope set(aggregate, &iface); unused_nodes.insert(&iface); TraversingVisitor::visit(iface); } -void UnusedVariableLocator::visit(FunctionDeclaration &func) +void UnusedVariableRemover::visit(FunctionDeclaration &func) { variables.push_back(BlockVariableMap()); - { - SetForScope set(global_scope, false); - for(NodeArray::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) - (*i)->visit(*this); - func.body.visit(*this); - } + for(NodeArray::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) + (*i)->visit(*this); + func.body.visit(*this); BlockVariableMap &block_variables = variables.back(); for(BlockVariableMap::iterator i=block_variables.begin(); i!=block_variables.end(); ++i) @@ -354,7 +366,7 @@ void UnusedVariableLocator::visit(FunctionDeclaration &func) merge_down_variables(); } -void UnusedVariableLocator::merge_down_variables() +void UnusedVariableRemover::merge_down_variables() { BlockVariableMap &parent_variables = variables[variables.size()-2]; BlockVariableMap &block_variables = variables.back(); @@ -383,7 +395,7 @@ void UnusedVariableLocator::merge_down_variables() variables.pop_back(); } -void UnusedVariableLocator::visit(Conditional &cond) +void UnusedVariableRemover::visit(Conditional &cond) { cond.condition->visit(*this); variables.push_back(BlockVariableMap()); @@ -416,7 +428,7 @@ void UnusedVariableLocator::visit(Conditional &cond) merge_down_variables(); } -void UnusedVariableLocator::visit(Iteration &iter) +void UnusedVariableRemover::visit(Iteration &iter) { variables.push_back(BlockVariableMap()); TraversingVisitor::visit(iter); @@ -430,7 +442,14 @@ void UnusedVariableLocator::visit(Iteration &iter) } -void UnusedFunctionLocator::visit(FunctionCall &call) +bool UnusedFunctionRemover::apply(Stage &stage) +{ + stage.content.visit(*this); + NodeRemover().apply(stage, unused_nodes); + return !unused_nodes.empty(); +} + +void UnusedFunctionRemover::visit(FunctionCall &call) { TraversingVisitor::visit(call); @@ -439,7 +458,7 @@ void UnusedFunctionLocator::visit(FunctionCall &call) used_definitions.insert(call.declaration->definition); } -void UnusedFunctionLocator::visit(FunctionDeclaration &func) +void UnusedFunctionRemover::visit(FunctionDeclaration &func) { TraversingVisitor::visit(func);