From 42903b905cd3924ecc45d3cb08222bc3548cab91 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 4 Apr 2021 11:38:42 +0300 Subject: [PATCH] Make function dependency collection its own visitor class I need it for creating SPIR-V entry points too. --- source/glsl/optimize.cpp | 30 +++++--------------------- source/glsl/optimize.h | 1 - source/glsl/reflect.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ source/glsl/reflect.h | 18 ++++++++++++++++ 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 43f94e8d..d7558ebd 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -1,6 +1,7 @@ #include #include #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::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); } diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index 7b90a2cd..d434c68a 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -57,7 +57,6 @@ class InlineContentInjector: private TraversingVisitor private: enum Pass { - DEPENDS, REFERENCED, INLINE, RENAME diff --git a/source/glsl/reflect.cpp b/source/glsl/reflect.cpp index a3e36be8..688c99bf 100644 --- a/source/glsl/reflect.cpp +++ b/source/glsl/reflect.cpp @@ -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(); } + +set 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 diff --git a/source/glsl/reflect.h b/source/glsl/reflect.h index a48ad53f..72a50c3e 100644 --- a/source/glsl/reflect.h +++ b/source/glsl/reflect.h @@ -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 dependencies; + std::set locals; + +public: + std::set 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 -- 2.43.0