X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=40d1c26f97f5f4886c2c3db4d28c9627aa499eb6;hb=518f751d385b733adbf43fe4056403740709edec;hp=1ebb87c5c2ea23360c33917104745273de6d8da0;hpb=bd8816692056230c36504dcccd76c6946dff47b1;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 1ebb87c5..40d1c26f 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -14,7 +14,7 @@ InlineableFunctionLocator::InlineableFunctionLocator(): void InlineableFunctionLocator::visit(FunctionCall &call) { FunctionDeclaration *def = call.declaration; - if(def && def->definition!=def) + if(def) def = def->definition; if(def) @@ -39,14 +39,54 @@ void InlineableFunctionLocator::visit(FunctionDeclaration &func) } +void InlineDependencyCollector::visit(VariableReference &var) +{ + if(var.declaration) + { + dependencies.insert(var.declaration); + var.declaration->visit(*this); + } +} + +void InlineDependencyCollector::visit(InterfaceBlockReference &iface) +{ + if(iface.declaration) + { + dependencies.insert(iface.declaration); + iface.declaration->visit(*this); + } +} + +void InlineDependencyCollector::visit(FunctionCall &call) +{ + if(call.declaration) + dependencies.insert(call.declaration); + TraversingVisitor::visit(call); +} + +void InlineDependencyCollector::visit(VariableDeclaration &var) +{ + if(var.type_declaration) + { + dependencies.insert(var.type_declaration); + var.type_declaration->visit(*this); + } +} + + FunctionInliner::FunctionInliner(): - extract_result(0) + current_function(0), + extract_result(0), + any_inlined(false) { } -void FunctionInliner::apply(Stage &stage) +bool FunctionInliner::apply(Stage &s) { - inlineable = InlineableFunctionLocator().apply(stage); - stage.content.visit(*this); + stage = &s; + inlineable = InlineableFunctionLocator().apply(s); + any_inlined = false; + s.content.visit(*this); + return any_inlined; } void FunctionInliner::visit_and_inline(RefPtr &ptr) @@ -54,7 +94,10 @@ void FunctionInliner::visit_and_inline(RefPtr &ptr) inline_result = 0; ptr->visit(*this); if(inline_result) + { ptr = inline_result; + any_inlined = true; + } } void FunctionInliner::visit(Block &block) @@ -95,13 +138,16 @@ void FunctionInliner::visit(FunctionCall &call) visit_and_inline(*i); FunctionDeclaration *def = call.declaration; - if(def && def->definition!=def) + if(def) def = def->definition; if(def && inlineable.count(def)) { extract_result = 2; def->visit(*this); + + if(inline_result) + NodeReorderer().apply(*stage, *current_function, InlineDependencyCollector().apply(*def)); } else inline_result = 0; @@ -114,6 +160,12 @@ void FunctionInliner::visit(VariableDeclaration &var) inline_result = 0; } +void FunctionInliner::visit(FunctionDeclaration &func) +{ + SetForScope set_func(current_function, &func); + TraversingVisitor::visit(func); +} + void FunctionInliner::visit(Return &ret) { TraversingVisitor::visit(ret); @@ -160,7 +212,13 @@ void ConstantConditionEliminator::visit(Assignment &assign) void ConstantConditionEliminator::visit(VariableDeclaration &var) { - if((var.constant || current_block->parent) && var.init_expression) + bool constant = var.constant; + if(constant && var.layout) + { + for(vector::const_iterator i=var.layout->qualifiers.begin(); (constant && i!=var.layout->qualifiers.end()); ++i) + constant = (i->name!="constant_id"); + } + if((constant || current_block->parent) && var.init_expression) variable_values[&var] = var.init_expression.get(); } @@ -259,7 +317,7 @@ void UnusedVariableRemover::visit(VariableReference &var) if(var.declaration && !assignment_target) { VariableInfo &var_info = variables.back()[var.declaration]; - var_info.assignments.clear(); + clear_assignments(var_info, false); var_info.referenced = true; } } @@ -441,7 +499,7 @@ void UnusedVariableRemover::visit(Iteration &iter) BlockVariableMap &block_variables = variables.back(); for(BlockVariableMap::iterator i=block_variables.begin(); i!=block_variables.end(); ++i) if(!i->second.local && i->second.referenced) - i->second.assignments.clear(); + clear_assignments(i->second, false); merge_down_variables(); }