]> git.tdb.fi Git - libs/gl.git/commitdiff
Further refactor block and scope management
authorMikko Rasa <tdb@tdb.fi>
Sun, 21 Feb 2021 03:12:28 +0000 (05:12 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 21 Feb 2021 03:13:42 +0000 (05:13 +0200)
TraversingVisitor now provides a current_block variable and block know
their parent block so checking if we're in the toplevel block is easy.

source/glsl/compiler.cpp
source/glsl/generate.cpp
source/glsl/generate.h
source/glsl/optimize.cpp
source/glsl/optimize.h
source/glsl/syntax.cpp
source/glsl/syntax.h
source/glsl/visitor.cpp
source/glsl/visitor.h

index 02f4ea13b7fbe864245898af9658b40d3e81116d..db9017cfb675745779ca45e7654f092ad9d868e6 100644 (file)
@@ -171,6 +171,7 @@ void Compiler::generate(Stage &stage)
        inject_block(stage.content, module->shared.content);
 
        DeclarationReorderer().apply(stage);
+       BlockResolver().apply(stage);
        FunctionResolver().apply(stage);
        VariableResolver().apply(stage);
        InterfaceGenerator().apply(stage);
@@ -185,6 +186,7 @@ bool Compiler::optimize(Stage &stage)
        ConstantConditionEliminator().apply(stage);
 
        FunctionInliner().apply(stage);
+       BlockResolver().apply(stage);
        VariableResolver().apply(stage);
 
        bool result = UnusedVariableRemover().apply(stage);
index 3707e4eda2cabc902397f0d9a344950462f24fcc..064d217e7da7b9b47f2c90dbab59a8f5006f9a77 100644 (file)
@@ -8,10 +8,6 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-DeclarationCombiner::DeclarationCombiner():
-       toplevel(true)
-{ }
-
 void DeclarationCombiner::apply(Stage &stage)
 {
        visit(stage.content);
@@ -20,10 +16,9 @@ void DeclarationCombiner::apply(Stage &stage)
 
 void DeclarationCombiner::visit(Block &block)
 {
-       if(!toplevel)
+       if(current_block)
                return;
 
-       SetForScope<bool> set(toplevel, false);
        TraversingVisitor::visit(block);
 }
 
@@ -77,8 +72,20 @@ void DeclarationCombiner::visit(VariableDeclaration &var)
 }
 
 
+void BlockResolver::visit(Block &block)
+{
+       block.parent = current_block;
+       TraversingVisitor::visit(block);
+}
+
+void BlockResolver::visit(InterfaceBlock &iface)
+{
+       iface.members.anonymous = true;
+       TraversingVisitor::visit(iface);
+}
+
+
 VariableResolver::VariableResolver():
-       anonymous(false),
        record_target(false),
        assignment_target(0),
        self_referencing(false)
@@ -86,34 +93,32 @@ VariableResolver::VariableResolver():
 
 void VariableResolver::apply(Stage &stage)
 {
-       Stage *builtins = get_builtins(stage.type);
-       if(builtins)
-               blocks.push_back(&builtins->content);
+       Stage *builtin_stage = get_builtins(stage.type);
+       builtins = (builtin_stage ? &builtin_stage->content : 0);
        visit(stage.content);
-       if(builtins)
-               blocks.pop_back();
+}
+
+Block *VariableResolver::next_block(Block &block)
+{
+       return block.parent ? block.parent : &block!=builtins ? builtins : 0;
 }
 
 void VariableResolver::visit(Block &block)
 {
-       if(!blocks.empty() && blocks.back()==&block)
-               return TraversingVisitor::visit(block);
+       if(current_block!=&block)
+               block.variables.clear();
 
-       blocks.push_back(&block);
-       block.variables.clear();
        TraversingVisitor::visit(block);
-       blocks.pop_back();
 }
 
 void VariableResolver::visit(VariableReference &var)
 {
        var.declaration = 0;
        type = 0;
-       for(vector<Block *>::iterator i=blocks.end(); i!=blocks.begin(); )
+       for(Block *block=current_block; block; block=next_block(*block))
        {
-               --i;
-               map<string, VariableDeclaration *>::iterator j = (*i)->variables.find(var.name);
-               if(j!=(*i)->variables.end())
+               map<string, VariableDeclaration *>::iterator j = block->variables.find(var.name);
+               if(j!=block->variables.end())
                {
                        var.declaration = j->second;
                        type = j->second->type_declaration;
@@ -189,16 +194,15 @@ void VariableResolver::visit(Assignment &assign)
 void VariableResolver::visit(StructDeclaration &strct)
 {
        TraversingVisitor::visit(strct);
-       blocks.back()->types[strct.name] = &strct;
+       current_block->types[strct.name] = &strct;
 }
 
 void VariableResolver::visit(VariableDeclaration &var)
 {
-       for(vector<Block *>::iterator i=blocks.end(); i!=blocks.begin(); )
+       for(Block *block=current_block; block; block=next_block(*block))
        {
-               --i;
-               map<string, StructDeclaration *>::iterator j = (*i)->types.find(var.type);
-               if(j!=(*i)->types.end())
+               map<string, StructDeclaration *>::iterator j = block->types.find(var.type);
+               if(j!=block->types.end())
                        var.type_declaration = j->second;
        }
 
@@ -206,32 +210,29 @@ void VariableResolver::visit(VariableDeclaration &var)
                var.interface = block_interface;
 
        TraversingVisitor::visit(var);
-       blocks.back()->variables[var.name] = &var;
-       if(anonymous && blocks.size()>1)
-               blocks[blocks.size()-2]->variables[var.name] = &var;
+       current_block->variables[var.name] = &var;
+       if(current_block->anonymous && current_block->parent)
+               current_block->parent->variables[var.name] = &var;
 }
 
 void VariableResolver::visit(InterfaceBlock &iface)
 {
-       SetFlag set(anonymous);
-       SetForScope<string> set2(block_interface, iface.interface);
+       SetForScope<string> set_iface(block_interface, iface.interface);
        TraversingVisitor::visit(iface);
 }
 
 void VariableResolver::visit(FunctionDeclaration &func)
 {
-       blocks.push_back(&func.body);
+       SetForScope<Block *> set_block(current_block, &func.body);
        func.body.variables.clear();
        TraversingVisitor::visit(func);
-       blocks.pop_back();
 }
 
 void VariableResolver::visit(Iteration &iter)
 {
-       blocks.push_back(&iter.body);
+       SetForScope<Block *> set_block(current_block, &iter.body);
        iter.body.variables.clear();
        TraversingVisitor::visit(iter);
-       blocks.pop_back();
 }
 
 
@@ -264,9 +265,7 @@ void FunctionResolver::visit(FunctionDeclaration &func)
 
 
 InterfaceGenerator::InterfaceGenerator():
-       stage(0),
-       scope_level(0),
-       current_block(0)
+       stage(0)
 { }
 
 string InterfaceGenerator::get_out_prefix(Stage::Type type)
@@ -291,12 +290,11 @@ void InterfaceGenerator::apply(Stage &s)
 
 void InterfaceGenerator::visit(Block &block)
 {
-       SetForScope<unsigned> set(scope_level, scope_level+1);
        SetForScope<Block *> set_block(current_block, &block);
        for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
        {
                assignment_insert_point = i;
-               if(scope_level==1)
+               if(&block==&stage->content)
                        iface_insert_point = i;
 
                (*i)->visit(*this);
@@ -331,7 +329,6 @@ bool InterfaceGenerator::generate_interface(VariableDeclaration &var, const stri
                iface_var->linked_declaration = &var;
        stage->content.body.insert(iface_insert_point, iface_var);
        {
-               SetForScope<unsigned> set_level(scope_level, 1);
                SetForScope<Block *> set_block(current_block, &stage->content);
                iface_var->visit(*this);
        }
@@ -376,7 +373,7 @@ void InterfaceGenerator::visit(VariableDeclaration &var)
 {
        if(var.interface=="out")
        {
-               if(scope_level==1)
+               if(current_block==&stage->content)
                        stage->out_variables[var.name] = &var;
                else if(generate_interface(var, "out", change_prefix(var.name, string())))
                {
@@ -474,7 +471,6 @@ void InterfaceGenerator::visit(Passthrough &pass)
 
 
 DeclarationReorderer::DeclarationReorderer():
-       scope_level(0),
        kind(NO_DECLARATION)
 { }
 
@@ -489,8 +485,7 @@ void DeclarationReorderer::visit(FunctionCall &call)
 
 void DeclarationReorderer::visit(Block &block)
 {
-       SetForScope<unsigned> set(scope_level, scope_level+1);
-       if(scope_level>1)
+       if(block.parent)
                return TraversingVisitor::visit(block);
 
        NodeList<Statement>::iterator struct_insert_point = block.body.end();
index 1867cc3e2a7d1a909ec3f59368216f6d69e17d23..511a460793d4e162fb05c24119c37c8538114322 100644 (file)
@@ -14,14 +14,11 @@ namespace SL {
 class DeclarationCombiner: private TraversingVisitor
 {
 private:
-       bool toplevel;
        std::map<std::string, std::vector<FunctionDeclaration *> > functions;
        std::map<std::string, VariableDeclaration *> variables;
        std::set<Node *> nodes_to_remove;
 
 public:
-       DeclarationCombiner();
-
        void apply(Stage &);
 
 private:
@@ -31,12 +28,22 @@ private:
        using TraversingVisitor::visit;
 };
 
+class BlockResolver: private TraversingVisitor
+{
+public:
+       void apply(Stage &s) { visit(s.content); }
+
+private:
+       virtual void visit(Block &);
+       virtual void visit(InterfaceBlock &);
+       using TraversingVisitor::visit;
+};
+
 class VariableResolver: private TraversingVisitor
 {
 private:
-       std::vector<Block *> blocks;
+       Block *builtins;
        StructDeclaration *type;
-       bool anonymous;
        std::string block_interface;
        bool record_target;
        VariableDeclaration *assignment_target;
@@ -48,6 +55,8 @@ public:
        void apply(Stage &);
 
 private:
+       Block *next_block(Block &);
+
        virtual void visit(Block &);
        virtual void visit(VariableReference &);
        virtual void visit(MemberAccess &);
@@ -81,8 +90,6 @@ private:
        Stage *stage;
        std::string in_prefix;
        std::string out_prefix;
-       unsigned scope_level;
-       Block *current_block;
        NodeList<Statement>::iterator iface_insert_point;
        NodeList<Statement>::iterator assignment_insert_point;
        std::set<Node *> nodes_to_remove;
@@ -116,7 +123,6 @@ private:
                FUNCTION
        };
 
-       unsigned scope_level;
        DeclarationKind kind;
        std::set<Node *> ordered_funcs;
        std::set<Node *> needed_funcs;
index 208e17a39b49e6fe1fd92f10b31e65808e77068b..4f1f8629a58f46964fc34ba7bb11e172b39f2037 100644 (file)
@@ -124,8 +124,6 @@ void FunctionInliner::visit(Return &ret)
 
 
 ConstantConditionEliminator::ConstantConditionEliminator():
-       scope_level(0),
-       current_block(0),
        record_only(false)
 { }
 
@@ -137,7 +135,6 @@ void ConstantConditionEliminator::apply(Stage &stage)
 
 void ConstantConditionEliminator::visit(Block &block)
 {
-       SetForScope<unsigned> set(scope_level, scope_level+1);
        SetForScope<Block *> set_block(current_block, &block);
        for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
        {
@@ -163,7 +160,7 @@ void ConstantConditionEliminator::visit(Assignment &assign)
 
 void ConstantConditionEliminator::visit(VariableDeclaration &var)
 {
-       if(var.constant || scope_level>1)
+       if(var.constant || current_block->parent)
                variable_values[&var] = var.init_expression.get();
 }
 
@@ -228,8 +225,7 @@ UnusedVariableRemover::UnusedVariableRemover():
        aggregate(0),
        assignment(0),
        assignment_target(false),
-       assign_to_subscript(false),
-       global_scope(true)
+       assign_to_subscript(false)
 { }
 
 bool UnusedVariableRemover::apply(Stage &stage)
@@ -358,12 +354,9 @@ void UnusedVariableRemover::visit(FunctionDeclaration &func)
 {
        variables.push_back(BlockVariableMap());
 
-       {
-               SetForScope<bool> set(global_scope, false);
-               for(NodeArray<VariableDeclaration>::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
-                       (*i)->visit(*this);
-               func.body.visit(*this);
-       }
+       for(NodeArray<VariableDeclaration>::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
+               (*i)->visit(*this);
+       func.body.visit(*this);
 
        BlockVariableMap &block_variables = variables.back();
        for(BlockVariableMap::iterator i=block_variables.begin(); i!=block_variables.end(); ++i)
index ea772b3d841b1ef78171d99ebb9afef064a76dfd..2caa498da0512624a31734232dfca88e870f6b31 100644 (file)
@@ -56,8 +56,6 @@ private:
 class ConstantConditionEliminator: private TraversingVisitor
 {
 private:
-       unsigned scope_level;
-       Block *current_block;
        bool record_only;
        ExpressionEvaluator::ValueMap variable_values;
        NodeList<Statement>::iterator insert_point;
@@ -100,7 +98,6 @@ private:
        Assignment *assignment;
        bool assignment_target;
        bool assign_to_subscript;
-       bool global_scope;
 
 public:
        UnusedVariableRemover();
index 957b49cea61a149fc213f9dbe71ecc9fa9774d1b..0b9ecb54ca9d0aef569b9ebc4fe7477ec8202415 100644 (file)
@@ -73,7 +73,17 @@ Statement::Statement():
 
 
 Block::Block():
-       use_braces(false)
+       use_braces(false),
+       anonymous(false),
+       parent(0)
+{ }
+
+Block::Block(const Block &other):
+       Node(other),
+       body(other.body),
+       use_braces(other.use_braces),
+       anonymous(other.anonymous),
+       parent(0)
 { }
 
 void Block::visit(NodeVisitor &visitor)
index 05bcee545f4a62431ddf8c00978d766e6c670565..d646e558e9cdc44f607abb147cf45f6e840ae849 100644 (file)
@@ -107,10 +107,13 @@ struct Block: Node
 {
        NodeList<Statement> body;
        bool use_braces;
+       bool anonymous;
        std::map<std::string, StructDeclaration *> types;
        std::map<std::string, VariableDeclaration *> variables;
+       Block *parent;
 
        Block();
+       Block(const Block &);
 
        virtual Block *clone() const { return new Block(*this); }
        virtual void visit(NodeVisitor &);
index cf0cca9612e92132e9a89f16471f788c8f7d00a1..265b11d41215da3bae6cebdbfcaa1b92e0919f24 100644 (file)
@@ -15,6 +15,7 @@ void NodeVisitor::visit(Assignment &assign)
 
 void TraversingVisitor::visit(Block &block)
 {
+       SetForScope<Block *> set_block(current_block, &block);
        for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
                (*i)->visit(*this);
 }
index 9ca910becaa38656c15382ca3f8be0a97f499ba4..35dce52400fc74daf1c71ae538e8affa700121f4 100644 (file)
@@ -44,7 +44,9 @@ public:
 class TraversingVisitor: public NodeVisitor
 {
 protected:
-       TraversingVisitor() { }
+       Block *current_block;
+
+       TraversingVisitor(): current_block(0) { }
 
 public:
        using NodeVisitor::visit;