]> git.tdb.fi Git - libs/gl.git/commitdiff
Make function dependency collection its own visitor class
authorMikko Rasa <tdb@tdb.fi>
Sun, 4 Apr 2021 08:38:42 +0000 (11:38 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 4 Apr 2021 08:39:23 +0000 (11:39 +0300)
I need it for creating SPIR-V entry points too.

source/glsl/optimize.cpp
source/glsl/optimize.h
source/glsl/reflect.cpp
source/glsl/reflect.h

index 43f94e8d4da10422be8a8047c238d9c61b9b6a9a..d7558ebde6c095b240943d4b317840425b46282a 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/core/raii.h>
 #include <msp/strings/format.h>
 #include "optimize.h"
+#include "reflect.h"
 
 using namespace std;
 
@@ -119,17 +120,13 @@ void InlineableFunctionLocator::visit(Return &ret)
 
 InlineContentInjector::InlineContentInjector():
        source_func(0),
-       pass(DEPENDS)
+       pass(REFERENCED)
 { }
 
 const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_func, Block &tgt_blk, const NodeList<Statement>::iterator &ins_pt, FunctionCall &call)
 {
        source_func = call.declaration->definition;
 
-       // Collect all declarations the inlined function depends on.
-       pass = DEPENDS;
-       source_func->visit(*this);
-
        /* Populate referenced_names from the target function so we can rename
        variables from the inlined function that would conflict. */
        pass = REFERENCED;
@@ -187,7 +184,7 @@ const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &ta
 
        tgt_blk.body.splice(ins_pt, staging_block.body);
 
-       NodeReorderer().apply(stage, target_func, dependencies);
+       NodeReorderer().apply(stage, target_func, DependencyCollector().apply(*source_func));
 
        return r_result_name;
 }
@@ -200,31 +197,19 @@ void InlineContentInjector::visit(VariableReference &var)
                if(i!=staging_block.variables.end())
                        var.name = i->second->name;
        }
-       else if(pass==DEPENDS && var.declaration)
-       {
-               dependencies.insert(var.declaration);
-               var.declaration->visit(*this);
-       }
        else if(pass==REFERENCED)
                referenced_names.insert(var.name);
 }
 
 void InlineContentInjector::visit(InterfaceBlockReference &iface)
 {
-       if(pass==DEPENDS && iface.declaration)
-       {
-               dependencies.insert(iface.declaration);
-               iface.declaration->visit(*this);
-       }
-       else if(pass==REFERENCED)
+       if(pass==REFERENCED)
                referenced_names.insert(iface.name);
 }
 
 void InlineContentInjector::visit(FunctionCall &call)
 {
-       if(pass==DEPENDS && call.declaration)
-               dependencies.insert(call.declaration);
-       else if(pass==REFERENCED)
+       if(pass==REFERENCED)
                referenced_names.insert(call.name);
        TraversingVisitor::visit(call);
 }
@@ -249,11 +234,6 @@ void InlineContentInjector::visit(VariableDeclaration &var)
                        }
                }
        }
-       else if(pass==DEPENDS && var.type_declaration)
-       {
-               dependencies.insert(var.type_declaration);
-               var.type_declaration->visit(*this);
-       }
        else if(pass==REFERENCED)
                referenced_names.insert(var.type);
 }
index 7b90a2cd676b62a7693b3b8ccdedf94ce2888d8a..d434c68a85c1df63594dcda6294c9698573e969f 100644 (file)
@@ -57,7 +57,6 @@ class InlineContentInjector: private TraversingVisitor
 private:
        enum Pass
        {
-               DEPENDS,
                REFERENCED,
                INLINE,
                RENAME
index a3e36be8448c57eba60bd4ae6a154525e95a4b59..688c99bf81b951ae288a23c9d5409e94fd7903c8 100644 (file)
@@ -1,5 +1,7 @@
 #include "reflect.h"
 
+using namespace std;
+
 namespace Msp {
 namespace GL {
 namespace SL {
@@ -41,6 +43,50 @@ void LocationCounter::visit(VariableDeclaration &var)
                                r_count *= literal->value.value<int>();
 }
 
+
+set<Node *> DependencyCollector::apply(FunctionDeclaration &func)
+{
+       func.visit(*this);
+       return dependencies;
+}
+
+void DependencyCollector::visit(VariableReference &var)
+{
+       if(var.declaration && !locals.count(var.declaration))
+       {
+               dependencies.insert(var.declaration);
+               var.declaration->visit(*this);
+       }
+}
+
+void DependencyCollector::visit(InterfaceBlockReference &iface)
+{
+       if(iface.declaration)
+       {
+               dependencies.insert(iface.declaration);
+               iface.declaration->visit(*this);
+       }
+}
+
+void DependencyCollector::visit(FunctionCall &call)
+{
+       if(call.declaration)
+               dependencies.insert(call.declaration);
+       TraversingVisitor::visit(call);
+}
+
+void DependencyCollector::visit(VariableDeclaration &var)
+{
+       locals.insert(&var);
+       if(var.type_declaration)
+       {
+               dependencies.insert(var.type_declaration);
+               var.type_declaration->visit(*this);
+       }
+
+       TraversingVisitor::visit(var);
+}
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp
index a48ad53f8cfa9b960665af6a61cd66e2a475d686..72a50c3eb6368b303ba5bd6e2fad8f7095e0189b 100644 (file)
@@ -25,6 +25,24 @@ private:
        virtual void visit(VariableDeclaration &);
 };
 
+/** Collects dependencies of a function.  This includes global variables,
+interface blocks, other functions and types. */
+class DependencyCollector: private TraversingVisitor
+{
+private:
+       std::set<Node *> dependencies;
+       std::set<Node *> locals;
+
+public:
+       std::set<Node *> apply(FunctionDeclaration &);
+
+private:
+       virtual void visit(VariableReference &);
+       virtual void visit(InterfaceBlockReference &);
+       virtual void visit(FunctionCall &);
+       virtual void visit(VariableDeclaration &);
+};
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp