]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/optimize.cpp
Make variable renaming while inlining more robust
[libs/gl.git] / source / glsl / optimize.cpp
index c8c9041fd43c7c9814cbd53e4d3ab8a719252cb2..c4118dee205d09f2f84c1e468001b6c6706de1c9 100644 (file)
@@ -74,6 +74,10 @@ const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &ta
 {
        target_block = &tgt_blk;
        source_func = &src;
+       remap_prefix = source_func->name;
+
+       vector<RefPtr<Statement> > inlined;
+       inlined.reserve(src.body.body.size());
        for(NodeList<Statement>::iterator i=src.body.body.begin(); i!=src.body.body.end(); ++i)
        {
                r_inlined_statement = 0;
@@ -81,11 +85,18 @@ const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &ta
                if(!r_inlined_statement)
                        r_inlined_statement = (*i)->clone();
 
-               SetFlag set_remap(remap_names);
+               SetForScope<unsigned> set_remap(remap_names, 2);
                r_inlined_statement->visit(*this);
-               tgt_blk.body.insert(ins_pt, r_inlined_statement);
+               inlined.push_back(r_inlined_statement);
        }
 
+       SetForScope<unsigned> set_remap(remap_names, 1);
+       SetForScope<string> set_prefix(remap_prefix, target_func.name);
+       variable_map.clear();
+       target_func.visit(*this);
+
+       tgt_blk.body.insert(ins_pt, inlined.begin(), inlined.end());
+
        NodeReorderer().apply(stage, target_func, dependencies);
 
        return r_result_name;
@@ -102,7 +113,11 @@ void InlineContentInjector::visit(VariableReference &var)
        else if(var.declaration)
        {
                SetFlag set_deps(deps_only);
-               dependencies.insert(var.declaration);
+               if(!variable_map.count(var.name))
+               {
+                       dependencies.insert(var.declaration);
+                       referenced_names.insert(var.name);
+               }
                var.declaration->visit(*this);
        }
 }
@@ -113,6 +128,7 @@ void InlineContentInjector::visit(InterfaceBlockReference &iface)
        {
                SetFlag set_deps(deps_only);
                dependencies.insert(iface.declaration);
+               referenced_names.insert(iface.name);
                iface.declaration->visit(*this);
        }
 }
@@ -120,7 +136,10 @@ void InlineContentInjector::visit(InterfaceBlockReference &iface)
 void InlineContentInjector::visit(FunctionCall &call)
 {
        if(!remap_names && call.declaration)
+       {
                dependencies.insert(call.declaration);
+               referenced_names.insert(call.name);
+       }
        TraversingVisitor::visit(call);
 }
 
@@ -128,28 +147,29 @@ void InlineContentInjector::visit(VariableDeclaration &var)
 {
        TraversingVisitor::visit(var);
 
-       if(var.type_declaration)
+       if(remap_names)
+       {
+               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;
+                       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);
        }
-
-       if(!remap_names && !deps_only)
-       {
-               RefPtr<VariableDeclaration> inlined_var = var.clone();
-               inlined_var->name = get_unused_variable_name(*target_block, var.name, source_func->name);
-               r_inlined_statement = inlined_var;
-
-               variable_map[var.name] = inlined_var.get();
-       }
 }
 
 void InlineContentInjector::visit(Return &ret)
 {
        TraversingVisitor::visit(ret);
 
-       if(ret.expression)
+       if(!remap_names && ret.expression)
        {
                /* Create a new variable to hold the return value of the inlined
                function. */