X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=ea0f96f0e60920cba9dd23523e83c37a07133ffb;hb=0d5ff7918d50092d8cf2e1b8f7af1d7d29b6eb9b;hp=a7f29a16f8991c6342b6e3dcc1de6882da695a7b;hpb=c849969d056972dd976cfa616363f1bc8cbc6291;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index a7f29a16..ea0f96f0 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -114,9 +114,13 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu source_func = call.declaration->definition; /* Populate referenced_names from the target function so we can rename - variables from the inlined function that would conflict. */ + variables from the inlined function that would conflict. Only consider + names which declared in blocks linearly related to the target block. */ pass = REFERENCED; - target_func.visit(*this); + tgt_blk.visit(*this); + for(const Block *b=&tgt_blk; b; b=b->parent) + for(const auto &kvp: b->variables) + referenced_names.insert(kvp.first); /* Inline and rename passes must be interleaved so used variable names are known when inlining the return statement. */ @@ -356,7 +360,7 @@ void ExpressionInliner::visit(RefPtr &expr) ExpressionUse use; use.reference = &expr; use.ref_scope = current_block; - use.blocked = access_write; + use.blocked = access_write || r_ref_info->blocked; if(iteration_body && !r_ref_info->trivial) { @@ -402,7 +406,7 @@ void ExpressionInliner::visit(Swizzle &swizzle) void ExpressionInliner::visit(UnaryExpression &unary) { - SetFlag set_write(access_write, access_write || unary.oper->token[1]=='+' || unary.oper->token[1]=='-'); + SetFlag set_write(access_write, (unary.oper->token[1]=='+' || unary.oper->token[1]=='-')); visit(unary.expression); r_trivial = false; } @@ -428,10 +432,10 @@ void ExpressionInliner::visit(Assignment &assign) r_trivial = true; visit(assign.right); - auto i = assignments.find(assign.target); + auto i = assignments.find(assign.target.declaration); if(i!=assignments.end()) { - if(iteration_body && i->second->expression) + if(iteration_body && i->second && i->second->expression) { /* Block inlining into previous references within the iteration statement. On iterations after the first they would refer to the @@ -441,6 +445,10 @@ void ExpressionInliner::visit(Assignment &assign) u.blocked = (k==iteration_body); } + for(; (i!=assignments.end() && i->first.declaration==assign.target.declaration); ++i) + if(targets_overlap(i->first, assign.target)) + i->second->blocked = true; + expressions.push_back(ExpressionInfo()); ExpressionInfo &info = expressions.back(); info.target = assign.target; @@ -450,7 +458,7 @@ void ExpressionInliner::visit(Assignment &assign) info.assign_scope = current_block; info.trivial = r_trivial; - i->second = &info; + assignments[assign.target] = &info; } r_trivial = false; @@ -1049,10 +1057,11 @@ void ConstantFolder::visit(Iteration &iter) } -void ConstantConditionEliminator::apply(Stage &stage) +bool ConstantConditionEliminator::apply(Stage &stage) { stage.content.visit(*this); NodeRemover().apply(stage, nodes_to_remove); + return !nodes_to_remove.empty(); } ConstantConditionEliminator::ConstantStatus ConstantConditionEliminator::check_constant_condition(const Expression &expr)