From: Mikko Rasa Date: Sun, 21 Feb 2021 03:12:28 +0000 (+0200) Subject: Further refactor block and scope management X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=99719790df8a1215465a68c7b1d87a495bff87eb Further refactor block and scope management TraversingVisitor now provides a current_block variable and block know their parent block so checking if we're in the toplevel block is easy. --- diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 02f4ea13..db9017cf 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -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); diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 3707e4ed..064d217e 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -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 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::iterator i=blocks.end(); i!=blocks.begin(); ) + for(Block *block=current_block; block; block=next_block(*block)) { - --i; - map::iterator j = (*i)->variables.find(var.name); - if(j!=(*i)->variables.end()) + map::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::iterator i=blocks.end(); i!=blocks.begin(); ) + for(Block *block=current_block; block; block=next_block(*block)) { - --i; - map::iterator j = (*i)->types.find(var.type); - if(j!=(*i)->types.end()) + map::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 set2(block_interface, iface.interface); + SetForScope set_iface(block_interface, iface.interface); TraversingVisitor::visit(iface); } void VariableResolver::visit(FunctionDeclaration &func) { - blocks.push_back(&func.body); + SetForScope 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 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 set(scope_level, scope_level+1); SetForScope set_block(current_block, &block); for(NodeList::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 set_level(scope_level, 1); SetForScope 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 set(scope_level, scope_level+1); - if(scope_level>1) + if(block.parent) return TraversingVisitor::visit(block); NodeList::iterator struct_insert_point = block.body.end(); diff --git a/source/glsl/generate.h b/source/glsl/generate.h index 1867cc3e..511a4607 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -14,14 +14,11 @@ namespace SL { class DeclarationCombiner: private TraversingVisitor { private: - bool toplevel; std::map > functions; std::map variables; std::set 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 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::iterator iface_insert_point; NodeList::iterator assignment_insert_point; std::set nodes_to_remove; @@ -116,7 +123,6 @@ private: FUNCTION }; - unsigned scope_level; DeclarationKind kind; std::set ordered_funcs; std::set needed_funcs; diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 208e17a3..4f1f8629 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -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 set(scope_level, scope_level+1); SetForScope set_block(current_block, &block); for(NodeList::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 set(global_scope, false); - for(NodeArray::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) - (*i)->visit(*this); - func.body.visit(*this); - } + for(NodeArray::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) diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index ea772b3d..2caa498d 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -56,8 +56,6 @@ private: class ConstantConditionEliminator: private TraversingVisitor { private: - unsigned scope_level; - Block *current_block; bool record_only; ExpressionEvaluator::ValueMap variable_values; NodeList::iterator insert_point; @@ -100,7 +98,6 @@ private: Assignment *assignment; bool assignment_target; bool assign_to_subscript; - bool global_scope; public: UnusedVariableRemover(); diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index 957b49ce..0b9ecb54 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -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) diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index 05bcee54..d646e558 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -107,10 +107,13 @@ struct Block: Node { NodeList body; bool use_braces; + bool anonymous; std::map types; std::map variables; + Block *parent; Block(); + Block(const Block &); virtual Block *clone() const { return new Block(*this); } virtual void visit(NodeVisitor &); diff --git a/source/glsl/visitor.cpp b/source/glsl/visitor.cpp index cf0cca96..265b11d4 100644 --- a/source/glsl/visitor.cpp +++ b/source/glsl/visitor.cpp @@ -15,6 +15,7 @@ void NodeVisitor::visit(Assignment &assign) void TraversingVisitor::visit(Block &block) { + SetForScope set_block(current_block, &block); for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) (*i)->visit(*this); } diff --git a/source/glsl/visitor.h b/source/glsl/visitor.h index 9ca910be..35dce524 100644 --- a/source/glsl/visitor.h +++ b/source/glsl/visitor.h @@ -44,7 +44,9 @@ public: class TraversingVisitor: public NodeVisitor { protected: - TraversingVisitor() { } + Block *current_block; + + TraversingVisitor(): current_block(0) { } public: using NodeVisitor::visit;