]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/optimize.cpp
Use C++11 features with containers
[libs/gl.git] / source / glsl / optimize.cpp
index 593a3222533874b6d8fde6265608efd9642e46e1..9388c04129cfc1b03020ef0f00da650bf2b46f1a 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include <msp/core/raii.h>
 #include <msp/strings/format.h>
 #include <msp/strings/utils.h>
@@ -26,20 +27,19 @@ void ConstantSpecializer::visit(VariableDeclaration &var)
        if(var.layout)
        {
                vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
-               for(vector<Layout::Qualifier>::iterator i=qualifiers.begin(); (!specializable && i!=qualifiers.end()); ++i)
-                       if(i->name=="constant_id")
-                       {
-                               specializable = true;
-                               qualifiers.erase(i);
-                       }
-
-               if(qualifiers.empty())
-                       var.layout = 0;
+               auto i = find_member(qualifiers, string("constant_id"), &Layout::Qualifier::name);
+               if(i!=qualifiers.end())
+               {
+                       specializable = true;
+                       qualifiers.erase(i);
+                       if(qualifiers.empty())
+                               var.layout = 0;
+               }
        }
 
        if(specializable)
        {
-               map<string, int>::const_iterator i = values->find(var.name);
+               auto i = values->find(var.name);
                if(i!=values->end())
                {
                        RefPtr<Literal> literal = new Literal;
@@ -85,9 +85,8 @@ void InlineableFunctionLocator::visit(FunctionCall &call)
 
 void InlineableFunctionLocator::visit(FunctionDeclaration &func)
 {
-       bool has_out_params = false;
-       for(NodeArray<VariableDeclaration>::const_iterator i=func.parameters.begin(); (!has_out_params && i!=func.parameters.end()); ++i)
-               has_out_params = ((*i)->interface=="out");
+       bool has_out_params = any_of(func.parameters.begin(), func.parameters.end(),
+               [](const RefPtr<VariableDeclaration> &p){ return p->interface=="out"; });
 
        unsigned &count = refcounts[func.definition];
        if((count<=1 || func.source==BUILTIN_SOURCE) && !has_out_params)
@@ -141,9 +140,9 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu
 
        vector<RefPtr<VariableDeclaration> > params;
        params.reserve(source_func->parameters.size());
-       for(NodeArray<VariableDeclaration>::iterator i=source_func->parameters.begin(); i!=source_func->parameters.end(); ++i)
+       for(const RefPtr<VariableDeclaration> &p: source_func->parameters)
        {
-               RefPtr<VariableDeclaration> var = (*i)->clone();
+               RefPtr<VariableDeclaration> var = p->clone();
                var->interface.clear();
 
                SetForScope<Pass> set_pass(pass, RENAME);
@@ -153,12 +152,12 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu
                params.push_back(var);
        }
 
-       for(NodeList<Statement>::iterator i=source_func->body.body.begin(); i!=source_func->body.body.end(); ++i)
+       for(const RefPtr<Statement> &s: source_func->body.body)
        {
                r_inlined_statement = 0;
-               (*i)->visit(*this);
+               s->visit(*this);
                if(!r_inlined_statement)
-                       r_inlined_statement = (*i)->clone();
+                       r_inlined_statement = s->clone();
 
                SetForScope<Pass> set_pass(pass, RENAME);
                r_inlined_statement->visit(*this);
@@ -194,7 +193,7 @@ void InlineContentInjector::visit(VariableReference &var)
 {
        if(pass==RENAME)
        {
-               map<string, VariableDeclaration *>::const_iterator i = staging_block.variables.find(var.name);
+               auto i = staging_block.variables.find(var.name);
                if(i!=staging_block.variables.end())
                        var.name = i->second->name;
        }
@@ -289,7 +288,7 @@ void FunctionInliner::visit(Block &block)
 {
        SetForScope<Block *> set_block(current_block, &block);
        SetForScope<NodeList<Statement>::iterator> save_insert_point(insert_point, block.body.begin());
-       for(NodeList<Statement>::iterator i=block.body.begin(); (!r_inlined_here && i!=block.body.end()); ++i)
+       for(auto i=block.body.begin(); (!r_inlined_here && i!=block.body.end()); ++i)
        {
                insert_point = i;
                (*i)->visit(*this);
@@ -298,7 +297,7 @@ void FunctionInliner::visit(Block &block)
 
 void FunctionInliner::visit(FunctionCall &call)
 {
-       for(NodeArray<Expression>::iterator i=call.arguments.begin(); (!r_inlined_here && i!=call.arguments.end()); ++i)
+       for(auto i=call.arguments.begin(); (!r_inlined_here && i!=call.arguments.end()); ++i)
                visit(*i);
 
        if(r_inlined_here)
@@ -364,13 +363,13 @@ bool ExpressionInliner::apply(Stage &s)
        s.content.visit(*this);
 
        bool any_inlined = false;
-       for(list<ExpressionInfo>::iterator i=expressions.begin(); i!=expressions.end(); ++i)
-               if(i->expression && (i->trivial || i->uses.size()==1))
+       for(ExpressionInfo &e: expressions)
+               if(e.expression && (e.trivial || e.uses.size()==1))
                {
-                       for(vector<ExpressionUse>::iterator j=i->uses.begin(); j!=i->uses.end(); ++j)
-                               if(!j->blocked)
+                       for(ExpressionUse &u: e.uses)
+                               if(!u.blocked)
                                {
-                                       *j->reference = i->expression->clone();
+                                       *u.reference = e.expression->clone();
                                        any_inlined = true;
                                }
                }
@@ -413,7 +412,7 @@ void ExpressionInliner::visit(VariableReference &var)
 {
        if(var.declaration && access_read)
        {
-               map<Assignment::Target, ExpressionInfo *>::iterator i = assignments.find(var.declaration);
+               auto i = assignments.find(var.declaration);
                if(i!=assignments.end())
                        r_ref_info = i->second;
        }
@@ -459,7 +458,7 @@ void ExpressionInliner::visit(Assignment &assign)
        r_trivial = true;
        visit(assign.right);
 
-       map<Assignment::Target, ExpressionInfo *>::iterator i = assignments.find(assign.target);
+       auto i = assignments.find(assign.target);
        if(i!=assignments.end())
        {
                if(iteration_body && i->second->expression)
@@ -467,9 +466,9 @@ void ExpressionInliner::visit(Assignment &assign)
                        /* Block inlining into previous references within the iteration
                        statement.  On iterations after the first they would refer to the
                        assignment within the iteration. */
-                       for(vector<ExpressionUse>::iterator j=i->second->uses.begin(); j!=i->second->uses.end(); ++j)
-                               for(Block *k=j->ref_scope; (!j->blocked && k); k=k->parent)
-                                       j->blocked = (k==iteration_body);
+                       for(ExpressionUse &u: i->second->uses)
+                               for(Block *k=u.ref_scope; (!u.blocked && k); k=k->parent)
+                                       u.blocked = (k==iteration_body);
                }
 
                expressions.push_back(ExpressionInfo());
@@ -510,8 +509,8 @@ void ExpressionInliner::visit(VariableDeclaration &var)
        bool constant = var.constant;
        if(constant && var.layout)
        {
-               for(vector<Layout::Qualifier>::const_iterator i=var.layout->qualifiers.begin(); (constant && i!=var.layout->qualifiers.end()); ++i)
-                       constant = (i->name!="constant_id");
+               constant = !any_of(var.layout->qualifiers.begin(), var.layout->qualifiers.end(),
+                       [](const Layout::Qualifier &q){ return q.name=="constant_id"; });
        }
 
        /* Only inline global variables if they're constant and have trivial
@@ -894,7 +893,7 @@ ConstantConditionEliminator::ConstantStatus ConstantConditionEliminator::check_c
 void ConstantConditionEliminator::visit(Block &block)
 {
        SetForScope<Block *> set_block(current_block, &block);
-       for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
+       for(auto i=block.body.begin(); i!=block.body.end(); ++i)
        {
                insert_point = i;
                (*i)->visit(*this);
@@ -963,7 +962,7 @@ bool UnreachableCodeRemover::apply(Stage &stage)
 
 void UnreachableCodeRemover::visit(Block &block)
 {
-       NodeList<Statement>::iterator i = block.body.begin();
+       auto i = block.body.begin();
        for(; (reachable && i!=block.body.end()); ++i)
                (*i)->visit(*this);
        for(; i!=block.body.end(); ++i)
@@ -1063,29 +1062,29 @@ bool UnusedVariableRemover::apply(Stage &s)
        stage = &s;
        s.content.visit(*this);
 
-       for(list<AssignmentInfo>::const_iterator i=assignments.begin(); i!=assignments.end(); ++i)
-               if(i->used_by.empty())
-                       unused_nodes.insert(i->node);
+       for(const AssignmentInfo &a: assignments)
+               if(a.used_by.empty())
+                       unused_nodes.insert(a.node);
 
-       for(BlockVariableMap::const_iterator i=variables.begin(); i!=variables.end(); ++i)
+       for(const auto &kvp: variables)
        {
-               if(i->second.output)
+               if(kvp.second.output)
                {
                        /* The last visible assignments of output variables are used by the
                        next stage or the API. */
-                       for(vector<AssignmentInfo *>::const_iterator j=i->second.assignments.begin(); j!=i->second.assignments.end(); ++j)
-                               unused_nodes.erase((*j)->node);
+                       for(AssignmentInfo *a: kvp.second.assignments)
+                               unused_nodes.erase(a->node);
                }
 
-               if(!i->second.output && !i->second.referenced)
+               if(!kvp.second.output && !kvp.second.referenced)
                {
                        // Don't remove variables from inside interface blocks.
-                       if(!i->second.interface_block)
-                               unused_nodes.insert(i->first);
+                       if(!kvp.second.interface_block)
+                               unused_nodes.insert(kvp.first);
                }
-               else if(i->second.interface_block)
+               else if(kvp.second.interface_block)
                        // Interface blocks are kept if even one member is used.
-                       unused_nodes.erase(i->second.interface_block);
+                       unused_nodes.erase(kvp.second.interface_block);
        }
 
        NodeRemover().apply(s, unused_nodes);
@@ -1100,16 +1099,16 @@ void UnusedVariableRemover::referenced(const Assignment::Target &target, Node &n
        if(!assignment_target)
        {
                bool loop_external = false;
-               for(vector<AssignmentInfo *>::const_iterator i=var_info.assignments.begin(); i!=var_info.assignments.end(); ++i)
+               for(AssignmentInfo *a: var_info.assignments)
                {
                        bool covered = true;
-                       for(unsigned j=0; (covered && j<(*i)->target.chain_len && j<target.chain_len); ++j)
+                       for(unsigned j=0; (covered && j<a->target.chain_len && j<target.chain_len); ++j)
                        {
-                               Assignment::Target::ChainType type1 = static_cast<Assignment::Target::ChainType>((*i)->target.chain[j]&0xC0);
+                               Assignment::Target::ChainType type1 = static_cast<Assignment::Target::ChainType>(a->target.chain[j]&0xC0);
                                Assignment::Target::ChainType type2 = static_cast<Assignment::Target::ChainType>(target.chain[j]&0xC0);
                                if(type1==Assignment::Target::SWIZZLE || type2==Assignment::Target::SWIZZLE)
                                {
-                                       unsigned index1 = (*i)->target.chain[j]&0x3F;
+                                       unsigned index1 = a->target.chain[j]&0x3F;
                                        unsigned index2 = target.chain[j]&0x3F;
                                        if(type1==Assignment::Target::SWIZZLE && type2==Assignment::Target::SWIZZLE)
                                                covered = index1&index2;
@@ -1121,13 +1120,13 @@ void UnusedVariableRemover::referenced(const Assignment::Target &target, Node &n
                                        covered as true */
                                }
                                else
-                                       covered = ((*i)->target.chain[j]==target.chain[j]);
+                                       covered = (a->target.chain[j]==target.chain[j]);
                        }
 
                        if(covered)
                        {
-                               (*i)->used_by.push_back(&node);
-                               if((*i)->in_loop<in_loop)
+                               a->used_by.push_back(&node);
+                               if(a->in_loop<in_loop)
                                        loop_external = true;
                        }
                }
@@ -1243,9 +1242,9 @@ void UnusedVariableRemover::visit(FunctionCall &call)
 
        if(stage->type==Stage::GEOMETRY && call.name=="EmitVertex")
        {
-               for(map<Statement *, VariableInfo>::const_iterator i=variables.begin(); i!=variables.end(); ++i)
-                       if(i->second.output)
-                               referenced(i->first, call);
+               for(const auto &kvp: variables)
+                       if(kvp.second.output)
+                               referenced(kvp.first, call);
        }
 }
 
@@ -1326,24 +1325,24 @@ void UnusedVariableRemover::visit(InterfaceBlock &iface)
 
 void UnusedVariableRemover::merge_variables(const BlockVariableMap &other_vars)
 {
-       for(BlockVariableMap::const_iterator i=other_vars.begin(); i!=other_vars.end(); ++i)
+       for(const auto &kvp: other_vars)
        {
-               BlockVariableMap::iterator j = variables.find(i->first);
+               auto j = variables.find(kvp.first);
                if(j!=variables.end())
                {
                        /* The merged blocks started as copies of each other so any common
                        assignments must be in the beginning. */
                        unsigned k = 0;
-                       for(; (k<i->second.assignments.size() && k<j->second.assignments.size()); ++k)
-                               if(i->second.assignments[k]!=j->second.assignments[k])
+                       for(; (k<kvp.second.assignments.size() && k<j->second.assignments.size()); ++k)
+                               if(kvp.second.assignments[k]!=j->second.assignments[k])
                                        break;
 
                        // Remaining assignments are unique to each block; merge them.
-                       j->second.assignments.insert(j->second.assignments.end(), i->second.assignments.begin()+k, i->second.assignments.end());
-                       j->second.referenced |= i->second.referenced;
+                       j->second.assignments.insert(j->second.assignments.end(), kvp.second.assignments.begin()+k, kvp.second.assignments.end());
+                       j->second.referenced |= kvp.second.referenced;
                }
                else
-                       variables.insert(*i);
+                       variables.insert(kvp);
        }
 }
 
@@ -1354,17 +1353,17 @@ void UnusedVariableRemover::visit(FunctionDeclaration &func)
 
        BlockVariableMap saved_vars = variables;
        // Assignments from other functions should not be visible.
-       for(BlockVariableMap::iterator i=variables.begin(); i!=variables.end(); ++i)
-               i->second.assignments.resize(i->second.initialized);
+       for(auto &kvp: variables)
+               kvp.second.assignments.resize(kvp.second.initialized);
        TraversingVisitor::visit(func);
        swap(variables, saved_vars);
        merge_variables(saved_vars);
 
        /* Always treat function parameters as referenced.  Removing unused
        parameters is not currently supported. */
-       for(NodeArray<VariableDeclaration>::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
+       for(const RefPtr<VariableDeclaration> &p: func.parameters)
        {
-               BlockVariableMap::iterator j = variables.find(i->get());
+               auto j = variables.find(p.get());
                if(j!=variables.end())
                        j->second.referenced = true;
        }
@@ -1397,8 +1396,8 @@ void UnusedVariableRemover::visit(Iteration &iter)
 
        /* Visit the external references of the loop again to record assignments
        done in the loop as used. */
-       for(vector<Node *>::const_iterator i=saved_refs.begin(); i!=saved_refs.end(); ++i)
-               (*i)->visit(*this);
+       for(Node *n: saved_refs)
+               n->visit(*this);
 
        /* Merge assignments from the iteration, without clearing previous state.
        Further analysis is needed to determine which parts of the iteration body