From: Mikko Rasa Date: Tue, 9 Mar 2021 10:05:29 +0000 (+0200) Subject: Handle expression replacement through TraversingVisitor X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=2a9f8f3803e1b57e0e5325454266d4e701b38cc5;p=libs%2Fgl.git Handle expression replacement through TraversingVisitor There were several cases missing, like VariableResolver not handling replacement of swizzles in return statements. This way each of the visitors can just concentrate on what they're actually doing. --- diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 8547152e..1f229991 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -274,7 +274,7 @@ void VariableResolver::enter(Block &block) block.variables.clear(); } -void VariableResolver::visit_and_replace(RefPtr &expr) +void VariableResolver::visit(RefPtr &expr) { r_replacement_expr = 0; expr->visit(*this); @@ -376,7 +376,7 @@ void VariableResolver::add_to_chain(Assignment::Target::ChainType type, unsigned void VariableResolver::visit(MemberAccess &memacc) { - visit_and_replace(memacc.left); + TraversingVisitor::visit(memacc); VariableDeclaration *declaration = 0; if(StructDeclaration *strct = dynamic_cast(memacc.left->type)) @@ -430,7 +430,7 @@ void VariableResolver::visit(MemberAccess &memacc) void VariableResolver::visit(Swizzle &swizzle) { - visit_and_replace(swizzle.left); + TraversingVisitor::visit(swizzle); if(record_target) { @@ -441,11 +441,6 @@ void VariableResolver::visit(Swizzle &swizzle) } } -void VariableResolver::visit(UnaryExpression &unary) -{ - visit_and_replace(unary.expression); -} - void VariableResolver::visit(BinaryExpression &binary) { if(binary.oper->token[0]=='[') @@ -454,9 +449,9 @@ void VariableResolver::visit(BinaryExpression &binary) /* The subscript expression is not a part of the primary assignment target. */ SetFlag set(record_target, false); - visit_and_replace(binary.right); + visit(binary.right); } - visit_and_replace(binary.left); + visit(binary.left); if(record_target) { @@ -468,10 +463,7 @@ void VariableResolver::visit(BinaryExpression &binary) } } else - { - visit_and_replace(binary.left); - visit_and_replace(binary.right); - } + TraversingVisitor::visit(binary); } void VariableResolver::visit(Assignment &assign) @@ -479,30 +471,19 @@ void VariableResolver::visit(Assignment &assign) { SetFlag set(record_target); r_assignment_target = Assignment::Target(); - visit_and_replace(assign.left); + visit(assign.left); r_any_resolved |= (r_assignment_targettoken[0]!='='); } -void VariableResolver::visit(FunctionCall &call) -{ - for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) - visit_and_replace(*i); -} - void VariableResolver::visit(VariableDeclaration &var) { - if(var.layout) - var.layout->visit(*this); - if(var.array_size) - visit_and_replace(var.array_size); - if(var.init_expression) - visit_and_replace(var.init_expression); + TraversingVisitor::visit(var); current_block->variables.insert(make_pair(var.name, &var)); } diff --git a/source/glsl/generate.h b/source/glsl/generate.h index c04e2f45..4e66ef68 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -107,17 +107,15 @@ public: private: virtual void enter(Block &); - void visit_and_replace(RefPtr &); + virtual void visit(RefPtr &); void check_assignment_target(Statement *); virtual void visit(VariableReference &); virtual void visit(InterfaceBlockReference &); void add_to_chain(Assignment::Target::ChainType, unsigned); virtual void visit(MemberAccess &); virtual void visit(Swizzle &); - virtual void visit(UnaryExpression &); virtual void visit(BinaryExpression &); virtual void visit(Assignment &); - virtual void visit(FunctionCall &); virtual void visit(VariableDeclaration &); virtual void visit(InterfaceBlock &); }; diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 87410d5a..be6cf7b6 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -193,7 +193,7 @@ bool FunctionInliner::apply(Stage &s) return r_any_inlined; } -void FunctionInliner::visit_and_inline(RefPtr &ptr) +void FunctionInliner::visit(RefPtr &ptr) { r_inline_result = 0; ptr->visit(*this); @@ -216,31 +216,10 @@ void FunctionInliner::visit(Block &block) } } -void FunctionInliner::visit(UnaryExpression &unary) -{ - visit_and_inline(unary.expression); -} - -void FunctionInliner::visit(BinaryExpression &binary) -{ - visit_and_inline(binary.left); - visit_and_inline(binary.right); -} - -void FunctionInliner::visit(MemberAccess &memacc) -{ - visit_and_inline(memacc.left); -} - -void FunctionInliner::visit(Swizzle &swizzle) -{ - visit_and_inline(swizzle.left); -} - void FunctionInliner::visit(FunctionCall &call) { for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) - visit_and_inline(*i); + visit(*i); FunctionDeclaration *def = call.declaration; if(def) @@ -264,29 +243,12 @@ void FunctionInliner::visit(FunctionCall &call) } } -void FunctionInliner::visit(ExpressionStatement &expr) -{ - visit_and_inline(expr.expression); -} - -void FunctionInliner::visit(VariableDeclaration &var) -{ - if(var.init_expression) - visit_and_inline(var.init_expression); -} - void FunctionInliner::visit(FunctionDeclaration &func) { SetForScope set_func(current_function, &func); TraversingVisitor::visit(func); } -void FunctionInliner::visit(Conditional &cond) -{ - visit_and_inline(cond.condition); - cond.body.visit(*this); -} - void FunctionInliner::visit(Iteration &iter) { /* Visit the initialization statement before entering the loop body so the @@ -301,12 +263,6 @@ void FunctionInliner::visit(Iteration &iter) iter.body.visit(*this); } -void FunctionInliner::visit(Return &ret) -{ - if(ret.expression) - visit_and_inline(ret.expression); -} - ExpressionInliner::ExpressionInfo::ExpressionInfo(): expression(0), @@ -413,6 +369,11 @@ void ExpressionInliner::visit(Block &block) i->second.available = false; } +void ExpressionInliner::visit(RefPtr &expr) +{ + visit_and_record(expr, 0, false); +} + void ExpressionInliner::visit(VariableReference &var) { if(var.declaration) @@ -493,8 +454,7 @@ void ExpressionInliner::visit(Assignment &assign) void ExpressionInliner::visit(FunctionCall &call) { - for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) - visit_and_record(*i, 0, false); + TraversingVisitor::visit(call); r_oper = 0; r_trivial = false; } @@ -503,8 +463,7 @@ void ExpressionInliner::visit(VariableDeclaration &var) { r_oper = 0; r_trivial = true; - if(var.init_expression) - visit_and_record(var.init_expression, 0, false); + TraversingVisitor::visit(var); bool constant = var.constant; if(constant && var.layout) @@ -528,12 +487,6 @@ void ExpressionInliner::visit(VariableDeclaration &var) } } -void ExpressionInliner::visit(Conditional &cond) -{ - visit_and_record(cond.condition, 0, false); - cond.body.visit(*this); -} - void ExpressionInliner::visit(Iteration &iter) { SetForScope set_block(current_block, &iter.body); @@ -545,16 +498,10 @@ void ExpressionInliner::visit(Iteration &iter) SetForScope set_body(iteration_body, &iter.body); if(iter.condition) - iter.condition->visit(*this); + visit(iter.condition); iter.body.visit(*this); if(iter.loop_expression) - iter.loop_expression->visit(*this); -} - -void ExpressionInliner::visit(Return &ret) -{ - if(ret.expression) - visit_and_record(ret.expression, 0, false); + visit(iter.loop_expression); } diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index 4663c12e..26076452 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -83,21 +83,11 @@ public: bool apply(Stage &); private: - void visit_and_inline(RefPtr &); - + virtual void visit(RefPtr &); virtual void visit(Block &); - virtual void visit(UnaryExpression &); - virtual void visit(BinaryExpression &); - virtual void visit(Assignment &a) { visit(static_cast(a)); } - virtual void visit(MemberAccess &); - virtual void visit(Swizzle &); virtual void visit(FunctionCall &); - virtual void visit(ExpressionStatement &); - virtual void visit(VariableDeclaration &); virtual void visit(FunctionDeclaration &); - virtual void visit(Conditional &); virtual void visit(Iteration &); - virtual void visit(Return &); }; /** Inlines variables into expressions. Variables with trivial values (those @@ -138,6 +128,7 @@ private: void visit_and_record(RefPtr &, const Operator *, bool); void inline_expression(Expression &, RefPtr &, const Operator *, const Operator *, bool); virtual void visit(Block &); + virtual void visit(RefPtr &); virtual void visit(VariableReference &); virtual void visit(MemberAccess &); virtual void visit(Swizzle &); @@ -146,9 +137,7 @@ private: virtual void visit(Assignment &); virtual void visit(FunctionCall &); virtual void visit(VariableDeclaration &); - virtual void visit(Conditional &); virtual void visit(Iteration &); - virtual void visit(Return &); }; /** Removes conditional statements and loops where the condition can be diff --git a/source/glsl/visitor.cpp b/source/glsl/visitor.cpp index dfe2d8d4..8c8056c5 100644 --- a/source/glsl/visitor.cpp +++ b/source/glsl/visitor.cpp @@ -16,47 +16,52 @@ void TraversingVisitor::visit(Block &block) (*i)->visit(*this); } +void TraversingVisitor::visit(RefPtr &expr) +{ + expr->visit(*this); +} + void TraversingVisitor::visit(ParenthesizedExpression &parexpr) { - parexpr.expression->visit(*this); + visit(parexpr.expression); } void TraversingVisitor::visit(MemberAccess &memacc) { - memacc.left->visit(*this); + visit(memacc.left); } void TraversingVisitor::visit(Swizzle &swizzle) { - swizzle.left->visit(*this); + visit(swizzle.left); } void TraversingVisitor::visit(UnaryExpression &unary) { - unary.expression->visit(*this); + visit(unary.expression); } void TraversingVisitor::visit(BinaryExpression &binary) { - binary.left->visit(*this); - binary.right->visit(*this); + visit(binary.left); + visit(binary.right); } void TraversingVisitor::visit(Assignment &assign) { - assign.left->visit(*this); - assign.right->visit(*this); + visit(assign.left); + visit(assign.right); } void TraversingVisitor::visit(FunctionCall &call) { for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) - (*i)->visit(*this); + visit(*i); } void TraversingVisitor::visit(ExpressionStatement &expr) { - expr.expression->visit(*this); + visit(expr.expression); } void TraversingVisitor::visit(InterfaceLayout &layout) @@ -74,9 +79,9 @@ void TraversingVisitor::visit(VariableDeclaration &var) if(var.layout) var.layout->visit(*this); if(var.init_expression) - var.init_expression->visit(*this); + visit(var.init_expression); if(var.array_size) - var.array_size->visit(*this); + visit(var.array_size); } void TraversingVisitor::visit(InterfaceBlock &iface) @@ -96,7 +101,7 @@ void TraversingVisitor::visit(FunctionDeclaration &func) void TraversingVisitor::visit(Conditional &cond) { - cond.condition->visit(*this); + visit(cond.condition); cond.body.visit(*this); cond.else_body.visit(*this); } @@ -108,22 +113,22 @@ void TraversingVisitor::visit(Iteration &iter) if(iter.init_statement) iter.init_statement->visit(*this); if(iter.condition) - iter.condition->visit(*this); + visit(iter.condition); iter.body.visit(*this); if(iter.loop_expression) - iter.loop_expression->visit(*this); + visit(iter.loop_expression); } void TraversingVisitor::visit(Passthrough &pass) { if(pass.subscript) - pass.subscript->visit(*this); + visit(pass.subscript); } void TraversingVisitor::visit(Return &ret) { if(ret.expression) - ret.expression->visit(*this); + visit(ret.expression); } diff --git a/source/glsl/visitor.h b/source/glsl/visitor.h index 30ab2544..85f9e848 100644 --- a/source/glsl/visitor.h +++ b/source/glsl/visitor.h @@ -57,6 +57,7 @@ protected: public: virtual void enter(Block &) { } virtual void visit(Block &); + virtual void visit(RefPtr &); virtual void visit(ParenthesizedExpression &); virtual void visit(MemberAccess &); virtual void visit(Swizzle &);