X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=668f7c5ef2553d399feef9c6c60949990fa54150;hb=d5c38c181cac4da490c96123e5a88a8c06785e55;hp=9cfad86a69d70069fcf6abf2e5877bb99f167000;hpb=5e4204ecaf54f49b63587ef5cd669a1b3838e0e9;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 9cfad86a..668f7c5e 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -66,18 +66,15 @@ void InlineableFunctionLocator::visit(Return &ret) InlineContentInjector::InlineContentInjector(): source_func(0), - remap_names(false), - deps_only(false) + remap_names(0) { } const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_func, Block &tgt_blk, const NodeList::iterator &ins_pt, FunctionDeclaration &src) { - target_block = &tgt_blk; + staging_block.parent = &tgt_blk; source_func = &src; remap_prefix = source_func->name; - vector > inlined; - inlined.reserve(src.body.body.size()); for(NodeList::iterator i=src.body.body.begin(); i!=src.body.body.end(); ++i) { r_inlined_statement = 0; @@ -87,18 +84,15 @@ const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &ta SetForScope set_remap(remap_names, 2); r_inlined_statement->visit(*this); - inlined.push_back(r_inlined_statement); + staging_block.body.push_back(r_inlined_statement); } - // Insert the variables here to enable further inlinings to avoid conflicts. - tgt_blk.variables.insert(variable_map.begin(), variable_map.end()); - SetForScope set_remap(remap_names, 1); SetForScope set_prefix(remap_prefix, target_func.name); - variable_map.clear(); + staging_block.variables.clear(); target_func.visit(*this); - tgt_blk.body.insert(ins_pt, inlined.begin(), inlined.end()); + tgt_blk.body.splice(ins_pt, staging_block.body); NodeReorderer().apply(stage, target_func, dependencies); @@ -109,14 +103,13 @@ void InlineContentInjector::visit(VariableReference &var) { if(remap_names) { - map::const_iterator i = variable_map.find(var.name); - if(i!=variable_map.end()) + map::const_iterator i = staging_block.variables.find(var.name); + if(i!=staging_block.variables.end()) var.name = i->second->name; } else if(var.declaration) { - SetFlag set_deps(deps_only); - if(!variable_map.count(var.name)) + if(!staging_block.variables.count(var.name)) { dependencies.insert(var.declaration); referenced_names.insert(var.name); @@ -129,7 +122,6 @@ void InlineContentInjector::visit(InterfaceBlockReference &iface) { if(!remap_names && iface.declaration) { - SetFlag set_deps(deps_only); dependencies.insert(iface.declaration); referenced_names.insert(iface.name); iface.declaration->visit(*this); @@ -154,14 +146,15 @@ void InlineContentInjector::visit(VariableDeclaration &var) { if(remap_names==2 || referenced_names.count(var.name)) { - string mapped_name = get_unused_variable_name(*target_block, var.name, remap_prefix); - variable_map[var.name] = &var; + string mapped_name = get_unused_variable_name(staging_block, var.name, remap_prefix); + staging_block.variables[var.name] = &var; + if(mapped_name!=var.name) + staging_block.variables[mapped_name] = &var; var.name = mapped_name; } } else if(var.type_declaration) { - SetFlag set_deps(deps_only); dependencies.insert(var.type_declaration); referenced_names.insert(var.type_declaration->name); var.type_declaration->visit(*this); @@ -176,7 +169,7 @@ void InlineContentInjector::visit(Return &ret) { /* Create a new variable to hold the return value of the inlined function. */ - r_result_name = get_unused_variable_name(*target_block, "_return", source_func->name); + r_result_name = get_unused_variable_name(staging_block, "_return", source_func->name); RefPtr var = new VariableDeclaration; var->source = ret.source; var->line = ret.line; @@ -190,7 +183,8 @@ void InlineContentInjector::visit(Return &ret) FunctionInliner::FunctionInliner(): current_function(0), - r_any_inlined(false) + r_any_inlined(false), + r_inlined_here(false) { } bool FunctionInliner::apply(Stage &s) @@ -218,7 +212,7 @@ void FunctionInliner::visit(Block &block) { SetForScope set_block(current_block, &block); SetForScope::iterator> save_insert_point(insert_point, block.body.begin()); - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) + for(NodeList::iterator i=block.body.begin(); (!r_inlined_here && i!=block.body.end()); ++i) { insert_point = i; (*i)->visit(*this); @@ -227,6 +221,9 @@ void FunctionInliner::visit(Block &block) void FunctionInliner::visit(FunctionCall &call) { + if(r_inlined_here) + return; + for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) visit(*i); @@ -249,6 +246,7 @@ void FunctionInliner::visit(FunctionCall &call) /* Inlined variables need to be resolved before this function can be inlined further. */ inlineable.erase(current_function); + r_inlined_here = true; } } @@ -256,6 +254,7 @@ void FunctionInliner::visit(FunctionDeclaration &func) { SetForScope set_func(current_function, &func); TraversingVisitor::visit(func); + r_inlined_here = false; } void FunctionInliner::visit(Iteration &iter) @@ -792,6 +791,24 @@ void ConstantConditionEliminator::visit(Block &block) } } +void ConstantConditionEliminator::visit(RefPtr &expr) +{ + r_ternary_result = 0; + expr->visit(*this); + if(r_ternary_result) + expr = r_ternary_result; + r_ternary_result = 0; +} + +void ConstantConditionEliminator::visit(TernaryExpression &ternary) +{ + ConstantStatus result = check_constant_condition(*ternary.condition); + if(result!=NOT_CONSTANT) + r_ternary_result = (result==CONSTANT_TRUE ? ternary.true_expr : ternary.false_expr); + else + r_ternary_result = 0; +} + void ConstantConditionEliminator::visit(Conditional &cond) { ConstantStatus result = check_constant_condition(*cond.condition);