From 1fa69bb8eec3070f5da296d6dd0bd67aea62d3bf Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 15 Feb 2021 16:01:55 +0200 Subject: [PATCH] Refactor the way of applying visitors to stages --- source/glsl/builtin.cpp | 3 +- source/glsl/compatibility.cpp | 17 ++++++++-- source/glsl/compatibility.h | 15 +++++++-- source/glsl/compiler.cpp | 62 ++++++++++++++--------------------- source/glsl/compiler.h | 4 --- source/glsl/generate.cpp | 14 ++++---- source/glsl/generate.h | 29 ++++++++++------ source/glsl/optimize.cpp | 6 ++-- source/glsl/optimize.h | 46 +++++++++++++------------- source/glsl/output.cpp | 9 +++-- source/glsl/output.h | 12 +++---- source/glsl/visitor.cpp | 18 ++++------ source/glsl/visitor.h | 37 +++++++-------------- 13 files changed, 135 insertions(+), 137 deletions(-) diff --git a/source/glsl/builtin.cpp b/source/glsl/builtin.cpp index ee692462..c9118f69 100644 --- a/source/glsl/builtin.cpp +++ b/source/glsl/builtin.cpp @@ -34,8 +34,7 @@ Module *create_builtins_module() Module *module = new Module(parser.parse(builtins_src, "")); for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) { - VariableResolver resolver; - i->content.visit(resolver); + VariableResolver().visit(i->content); for(map::iterator j=i->content.variables.begin(); j!=i->content.variables.end(); ++j) j->second->linked_declaration = j->second; } diff --git a/source/glsl/compatibility.cpp b/source/glsl/compatibility.cpp index a3b2882d..398a7bd3 100644 --- a/source/glsl/compatibility.cpp +++ b/source/glsl/compatibility.cpp @@ -14,9 +14,16 @@ namespace GL { namespace SL { DefaultPrecisionGenerator::DefaultPrecisionGenerator(): + stage_type(Stage::SHARED), toplevel(true) { } +void DefaultPrecisionGenerator::apply(Stage &stage) +{ + SetForScope set_stage(stage_type, stage.type); + visit(stage.content); +} + void DefaultPrecisionGenerator::visit(Block &block) { if(toplevel) @@ -25,7 +32,7 @@ void DefaultPrecisionGenerator::visit(Block &block) BlockModifier::visit(block); } else - StageVisitor::visit(block); + TraversingVisitor::visit(block); } void DefaultPrecisionGenerator::visit(Precision &prec) @@ -49,7 +56,7 @@ void DefaultPrecisionGenerator::visit(VariableDeclaration &var) Precision *prec = new Precision; if(!type.compare(0, 7, "sampler")) prec->precision = "lowp"; - else if(stage->type==Stage::FRAGMENT) + else if(stage_type==Stage::FRAGMENT) prec->precision = "mediump"; else prec->precision = "highp"; @@ -106,6 +113,12 @@ bool LegacyConverter::check_extension(const Extension &extension) const return true; } +void LegacyConverter::apply(Stage &s) +{ + SetForScope set_stage(stage, &s); + visit(s.content); +} + bool LegacyConverter::supports_unified_interface_syntax() const { if(target_api==OPENGL_ES2) diff --git a/source/glsl/compatibility.h b/source/glsl/compatibility.h index f3376876..732f3477 100644 --- a/source/glsl/compatibility.h +++ b/source/glsl/compatibility.h @@ -11,13 +11,16 @@ namespace SL { class DefaultPrecisionGenerator: public BlockModifier { private: + Stage::Type stage_type; bool toplevel; std::set have_default; public: DefaultPrecisionGenerator(); - using StageVisitor::visit; + void apply(Stage &); + + using BlockModifier::visit; virtual void visit(Block &); virtual void visit(Precision &); virtual void visit(VariableDeclaration &); @@ -26,7 +29,9 @@ public: class PrecisionRemover: public BlockModifier { public: - using StageVisitor::visit; + void apply(Stage &s) { visit(s.content); } + + using BlockModifier::visit; virtual void visit(Precision &); virtual void visit(VariableDeclaration &); }; @@ -34,6 +39,7 @@ public: class LegacyConverter: public BlockModifier { private: + Stage *stage; GLApi target_api; Version target_version; std::string type; @@ -46,7 +52,10 @@ public: private: bool check_version(const Version &) const; bool check_extension(const Extension &) const; - using StageVisitor::visit; +public: + using BlockModifier::visit; + virtual void apply(Stage &); +private: bool supports_unified_interface_syntax() const; virtual void visit(VariableReference &); virtual void visit(Assignment &); diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index e6c03577..21060cb4 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -65,17 +65,19 @@ void Compiler::add_shaders(Program &program) { for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) { + string stage_src = Formatter().apply(*i); + if(i->type==Stage::VERTEX) { - program.attach_shader_owned(new VertexShader(apply(*i))); + program.attach_shader_owned(new VertexShader(stage_src)); for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) program.bind_attribute(j->second, j->first); } else if(i->type==Stage::GEOMETRY) - program.attach_shader_owned(new GeometryShader(apply(*i))); + program.attach_shader_owned(new GeometryShader(stage_src)); else if(i->type==Stage::FRAGMENT) { - program.attach_shader_owned(new FragmentShader(apply(*i))); + program.attach_shader_owned(new FragmentShader(stage_src)); if(EXT_gpu_shader4) { for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) @@ -124,10 +126,10 @@ void Compiler::add_shaders(Program &program) void Compiler::append_module(Module &mod) { - vector imports = apply >(mod.shared); + vector imports = NodeGatherer().apply(mod.shared); for(vector::iterator i=imports.begin(); i!=imports.end(); ++i) import((*i)->module); - apply(mod.shared, set(imports.begin(), imports.end())); + NodeRemover(set(imports.begin(), imports.end())).apply(mod.shared); append_stage(mod.shared); for(list::iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i) @@ -160,7 +162,7 @@ void Compiler::append_stage(Stage &stage) target->required_version = stage.required_version; for(NodeList::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i) target->content.body.push_back(*i); - apply(*target); + DeclarationCombiner().apply(*target); } void Compiler::process() @@ -198,27 +200,27 @@ void Compiler::generate(Stage &stage) stage.required_version = module->shared.required_version; inject_block(stage.content, module->shared.content); - apply(stage); - apply(stage); - apply(stage); - apply(stage); - apply(stage); - apply(stage); - apply(stage); - apply(stage); + DeclarationReorderer().apply(stage); + FunctionResolver().apply(stage); + VariableResolver().apply(stage); + InterfaceGenerator().apply(stage); + VariableResolver().apply(stage); + DeclarationReorderer().apply(stage); + FunctionResolver().apply(stage); + LegacyConverter().apply(stage); } bool Compiler::optimize(Stage &stage) { - apply(stage); + ConstantConditionEliminator().apply(stage); - set inlineable = apply(stage); - apply(stage, inlineable); + set inlineable = InlineableFunctionLocator().apply(stage); + FunctionInliner(inlineable).apply(stage); - set unused = apply(stage); - set unused2 = apply(stage); + set unused = UnusedVariableLocator().apply(stage); + set unused2 = UnusedFunctionLocator().apply(stage); unused.insert(unused2.begin(), unused2.end()); - apply(stage, unused); + NodeRemover(unused).apply(stage); return !unused.empty(); } @@ -226,9 +228,9 @@ bool Compiler::optimize(Stage &stage) void Compiler::finalize(Stage &stage) { if(get_gl_api()==OPENGL_ES2) - apply(stage); + DefaultPrecisionGenerator().apply(stage); else - apply(stage); + PrecisionRemover().apply(stage); } void Compiler::inject_block(Block &target, const Block &source) @@ -238,22 +240,6 @@ void Compiler::inject_block(Block &target, const Block &source) target.body.insert(insert_point, (*i)->clone()); } -template -typename T::ResultType Compiler::apply(Stage &stage) -{ - T visitor; - visitor.apply(stage); - return visitor.get_result(); -} - -template -typename T::ResultType Compiler::apply(Stage &stage, const A &arg) -{ - T visitor(arg); - visitor.apply(stage); - return visitor.get_result(); -} - } // namespace SL } // namespace GL } // namespace Msp diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index c8cb565f..2afc2f56 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -36,10 +36,6 @@ private: bool optimize(Stage &); void finalize(Stage &); static void inject_block(Block &, const Block &); - template - static typename T::ResultType apply(Stage &); - template - static typename T::ResultType apply(Stage &, const A &); }; } // namespace SL diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 69a8dfb1..f3c57a2f 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -78,13 +78,12 @@ VariableResolver::VariableResolver(): self_referencing(false) { } -void VariableResolver::apply(Stage &s) +void VariableResolver::apply(Stage &stage) { - SetForScope set(stage, &s); - Stage *builtins = get_builtins(stage->type); + Stage *builtins = get_builtins(stage.type); if(builtins) blocks.push_back(&builtins->content); - stage->content.visit(*this); + visit(stage.content); if(builtins) blocks.pop_back(); } @@ -240,6 +239,7 @@ void FunctionResolver::visit(FunctionDeclaration &func) InterfaceGenerator::InterfaceGenerator(): + stage(0), scope_level(0) { } @@ -259,7 +259,7 @@ void InterfaceGenerator::apply(Stage &s) if(stage->previous) in_prefix = get_out_prefix(stage->previous->type); out_prefix = get_out_prefix(stage->type); - stage->content.visit(*this); + visit(s.content); } void InterfaceGenerator::visit(Block &block) @@ -471,7 +471,7 @@ void DeclarationReorderer::visit(Block &block) { SetForScope set(scope_level, scope_level+1); if(scope_level>1) - return StageVisitor::visit(block); + return TraversingVisitor::visit(block); NodeList::iterator struct_insert_point = block.body.end(); NodeList::iterator variable_insert_point = block.body.end(); @@ -547,7 +547,7 @@ void DeclarationReorderer::visit(Block &block) void DeclarationReorderer::visit(VariableDeclaration &var) { - StageVisitor::visit(var); + TraversingVisitor::visit(var); kind = VARIABLE; } diff --git a/source/glsl/generate.h b/source/glsl/generate.h index a09c552f..90cf2722 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -21,13 +21,15 @@ private: public: DeclarationCombiner(); - using StageVisitor::visit; + void apply(Stage &s) { visit(s.content); } + + using BlockModifier::visit; virtual void visit(Block &); virtual void visit(FunctionDeclaration &); virtual void visit(VariableDeclaration &); }; -class VariableResolver: public StageVisitor +class VariableResolver: public TraversingVisitor { private: std::vector blocks; @@ -41,8 +43,9 @@ private: public: VariableResolver(); - virtual void apply(Stage &); - using StageVisitor::visit; + void apply(Stage &); + + using TraversingVisitor::visit; virtual void visit(Block &); virtual void visit(VariableReference &); virtual void visit(MemberAccess &); @@ -53,13 +56,15 @@ public: virtual void visit(InterfaceBlock &); }; -class FunctionResolver: public StageVisitor +class FunctionResolver: public TraversingVisitor { private: std::map > functions; public: - using StageVisitor::visit; + void apply(Stage &s) { visit(s.content); } + + using TraversingVisitor::visit; virtual void visit(FunctionCall &); virtual void visit(FunctionDeclaration &); }; @@ -67,6 +72,7 @@ public: class InterfaceGenerator: public BlockModifier { private: + Stage *stage; std::string in_prefix; std::string out_prefix; unsigned scope_level; @@ -75,9 +81,10 @@ private: public: InterfaceGenerator(); + void apply(Stage &); + static std::string get_out_prefix(Stage::Type); - virtual void apply(Stage &); - using StageVisitor::visit; + using BlockModifier::visit; virtual void visit(Block &); std::string change_prefix(const std::string &, const std::string &) const; bool generate_interface(VariableDeclaration &, const std::string &, const std::string &); @@ -87,7 +94,7 @@ public: virtual void visit(Passthrough &); }; -class DeclarationReorderer: public StageVisitor +class DeclarationReorderer: public TraversingVisitor { private: enum DeclarationKind @@ -107,7 +114,9 @@ private: public: DeclarationReorderer(); - using StageVisitor::visit; + void apply(Stage &s) { visit(s.content); } + + using TraversingVisitor::visit; virtual void visit(Block &); virtual void visit(FunctionCall &); virtual void visit(InterfaceLayout &) { kind = LAYOUT; } diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index f4d1680b..c76cae1b 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -217,10 +217,10 @@ UnusedVariableLocator::UnusedVariableLocator(): global_scope(true) { } -void UnusedVariableLocator::apply(Stage &s) +const set &UnusedVariableLocator::apply(Stage &s) { variables.push_back(BlockVariableMap()); - StageVisitor::apply(s); + visit(s.content); BlockVariableMap &global_variables = variables.back(); for(BlockVariableMap::iterator i=global_variables.begin(); i!=global_variables.end(); ++i) { @@ -233,6 +233,8 @@ void UnusedVariableLocator::apply(Stage &s) } } variables.pop_back(); + + return unused_nodes; } void UnusedVariableLocator::visit(VariableReference &var) diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index 698aa0b2..2e28d48a 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -10,11 +10,8 @@ namespace Msp { namespace GL { namespace SL { -class InlineableFunctionLocator: public StageVisitor +class InlineableFunctionLocator: public TraversingVisitor { -public: - typedef std::set ResultType; - private: std::map refcounts; std::set inlineable; @@ -23,13 +20,14 @@ private: public: InlineableFunctionLocator(); - const ResultType &get_result() const { return inlineable; } - using StageVisitor::visit; + const std::set &apply(Stage &s) { visit(s.content); return inlineable; } + + using TraversingVisitor::visit; virtual void visit(FunctionCall &); virtual void visit(FunctionDeclaration &); }; -class FunctionInliner: public StageVisitor +class FunctionInliner: public TraversingVisitor { private: std::set inlineable; @@ -40,10 +38,12 @@ public: FunctionInliner(); FunctionInliner(const std::set &); + void apply(Stage &s) { visit(s.content); } + private: void visit_and_inline(RefPtr &); public: - using StageVisitor::visit; + using TraversingVisitor::visit; virtual void visit(Block &); virtual void visit(UnaryExpression &); virtual void visit(BinaryExpression &); @@ -63,7 +63,9 @@ private: public: ConstantConditionEliminator(); - using StageVisitor::visit; + void apply(Stage &s) { visit(s.content); } + + using BlockModifier::visit; virtual void visit(Block &); virtual void visit(UnaryExpression &); virtual void visit(Assignment &); @@ -72,11 +74,8 @@ public: virtual void visit(Iteration &); }; -class UnusedVariableLocator: public StageVisitor +class UnusedVariableLocator: public TraversingVisitor { -public: - typedef std::set ResultType; - private: struct VariableInfo { @@ -102,38 +101,39 @@ private: public: UnusedVariableLocator(); - virtual void apply(Stage &); - const ResultType &get_result() const { return unused_nodes; } -private: - using StageVisitor::visit; + const std::set &apply(Stage &); + + using TraversingVisitor::visit; virtual void visit(VariableReference &); virtual void visit(MemberAccess &); virtual void visit(BinaryExpression &); virtual void visit(Assignment &); +private: void record_assignment(VariableDeclaration &, Node &, bool); void clear_assignments(VariableInfo &, bool); +public: virtual void visit(ExpressionStatement &); virtual void visit(StructDeclaration &); virtual void visit(VariableDeclaration &); virtual void visit(InterfaceBlock &); virtual void visit(FunctionDeclaration &); +private: void merge_down_variables(); +public: virtual void visit(Conditional &); virtual void visit(Iteration &); }; -class UnusedFunctionLocator: public StageVisitor +class UnusedFunctionLocator: public TraversingVisitor { -public: - typedef std::set ResultType; - private: std::set unused_nodes; std::set used_definitions; public: - const ResultType &get_result() const { return unused_nodes; } - using StageVisitor::visit; + const std::set &apply(Stage &s) { visit(s.content); return unused_nodes; } + + using TraversingVisitor::visit; virtual void visit(FunctionCall &); virtual void visit(FunctionDeclaration &); }; diff --git a/source/glsl/output.cpp b/source/glsl/output.cpp index dfd93470..6e88fd1f 100644 --- a/source/glsl/output.cpp +++ b/source/glsl/output.cpp @@ -9,14 +9,17 @@ namespace GL { namespace SL { Formatter::Formatter(): + stage(0), source_index(0), source_line(1), indent(0), parameter_list(false) { } -void Formatter::apply(Stage &s) +const string &Formatter::apply(Stage &s) { + SetForScope set_stage(stage, &s); + GLApi api = get_gl_api(); const Version &ver = s.required_version; @@ -33,7 +36,9 @@ void Formatter::apply(Stage &s) if(!s.required_extensions.empty()) formatted += '\n'; - StageVisitor::apply(s); + visit(s.content); + + return formatted; } void Formatter::append(const string &text) diff --git a/source/glsl/output.h b/source/glsl/output.h index b58c3f96..06bb5fd1 100644 --- a/source/glsl/output.h +++ b/source/glsl/output.h @@ -8,12 +8,10 @@ namespace Msp { namespace GL { namespace SL { -class Formatter: public StageVisitor +class Formatter: public TraversingVisitor { -public: - typedef std::string ResultType; - private: + Stage *stage; std::string formatted; unsigned source_index; unsigned source_line; @@ -24,14 +22,14 @@ private: public: Formatter(); - virtual void apply(Stage &); - const std::string &get_result() const { return formatted; } + const std::string &apply(Stage &); + private: void append(const std::string &); void append(char); void set_source(unsigned, unsigned); public: - using StageVisitor::visit; + using TraversingVisitor::visit; virtual void visit(Block &); virtual void visit(Literal &); virtual void visit(ParenthesizedExpression &); diff --git a/source/glsl/visitor.cpp b/source/glsl/visitor.cpp index 58d323ab..717acad1 100644 --- a/source/glsl/visitor.cpp +++ b/source/glsl/visitor.cpp @@ -114,17 +114,6 @@ void TraversingVisitor::visit(Return &ret) } -StageVisitor::StageVisitor(): - stage(0) -{ } - -void StageVisitor::apply(Stage &s) -{ - SetForScope set(stage, &s); - stage->content.visit(*this); -} - - BlockModifier::BlockModifier(): remove_node(false) { } @@ -158,9 +147,16 @@ void BlockModifier::visit(Block &block) NodeRemover::NodeRemover(const set &r): + stage(0), to_remove(r) { } +void NodeRemover::apply(Stage &s) +{ + SetForScope set_stage(stage, &s); + visit(s.content); +} + void NodeRemover::visit(Block &block) { for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ) diff --git a/source/glsl/visitor.h b/source/glsl/visitor.h index 582628bb..e1c45b5c 100644 --- a/source/glsl/visitor.h +++ b/source/glsl/visitor.h @@ -66,22 +66,7 @@ public: virtual void visit(Return &); }; -class StageVisitor: public TraversingVisitor -{ -public: - typedef void ResultType; - -protected: - Stage *stage; - - StageVisitor(); - -public: - virtual void apply(Stage &); - void get_result() const { } -}; - -class BlockModifier: public StageVisitor +class BlockModifier: public TraversingVisitor { protected: bool remove_node; @@ -93,35 +78,35 @@ protected: void apply_and_increment(Block &, NodeList::iterator &); public: - using StageVisitor::visit; + using TraversingVisitor::visit; virtual void visit(Block &); }; template -class NodeGatherer: public StageVisitor +class NodeGatherer: public TraversingVisitor { -public: - typedef std::vector ResultType; - private: std::vector nodes; public: - const ResultType &get_result() const { return nodes; } - using StageVisitor::visit; + const std::vector &apply(Stage &s) { visit(s.content); return nodes; } + + using TraversingVisitor::visit; virtual void visit(T &n) { nodes.push_back(&n); } }; -class NodeRemover: public StageVisitor +class NodeRemover: public TraversingVisitor { private: + Stage *stage; std::set to_remove; public: - NodeRemover() { } NodeRemover(const std::set &); - using StageVisitor::visit; + void apply(Stage &); + + using TraversingVisitor::visit; virtual void visit(Block &); virtual void visit(VariableDeclaration &); virtual void visit(Iteration &); -- 2.43.0