From 3415ed0f925d781df9d8243e0f4c454516b1c450 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 5 Apr 2021 16:46:11 +0300 Subject: [PATCH] Track composite assignments and references in UnusedVariableRemover --- source/glsl/optimize.cpp | 96 +++++++++++++++++++-- source/glsl/optimize.h | 6 ++ tests/glsl/unused_component_assignment.glsl | 33 +++++++ 3 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 tests/glsl/unused_component_assignment.glsl diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 57182019..927047cc 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -963,7 +963,8 @@ UnusedVariableRemover::UnusedVariableRemover(): interface_block(0), r_assignment(0), assignment_target(false), - r_side_effects(false) + r_side_effects(false), + composite_reference(false) { } bool UnusedVariableRemover::apply(Stage &s) @@ -1008,18 +1009,80 @@ void UnusedVariableRemover::referenced(const Assignment::Target &target, Node &n if(!assignment_target) { for(vector::const_iterator i=var_info.assignments.begin(); i!=var_info.assignments.end(); ++i) - (*i)->used_by.push_back(&node); + { + bool covered = true; + for(unsigned j=0; (covered && j<(*i)->target.chain_len && j((*i)->target.chain[j]&0xC0); + Assignment::Target::ChainType type2 = static_cast(target.chain[j]&0xC0); + if(type1==Assignment::Target::SWIZZLE || type2==Assignment::Target::SWIZZLE) + { + unsigned index1 = (*i)->target.chain[j]&0x3F; + unsigned index2 = target.chain[j]&0x3F; + if(type1==Assignment::Target::SWIZZLE && type2==Assignment::Target::SWIZZLE) + covered = index1&index2; + else if(type1==Assignment::Target::ARRAY && index1<4) + covered = index2&(1<target.chain[j]==target.chain[j]); + } + if(covered) + (*i)->used_by.push_back(&node); + } } } void UnusedVariableRemover::visit(VariableReference &var) { - referenced(var.declaration, var); + if(composite_reference) + r_reference.declaration = var.declaration; + else + referenced(var.declaration, var); } void UnusedVariableRemover::visit(InterfaceBlockReference &iface) { - referenced(iface.declaration, iface); + if(composite_reference) + r_reference.declaration = iface.declaration; + else + referenced(iface.declaration, iface); +} + +void UnusedVariableRemover::visit_composite(Expression &expr) +{ + if(!composite_reference) + r_reference = Assignment::Target(); + + SetFlag set_composite(composite_reference); + expr.visit(*this); +} + +void UnusedVariableRemover::visit(MemberAccess &memacc) +{ + visit_composite(*memacc.left); + + add_to_chain(r_reference, Assignment::Target::MEMBER, memacc.index); + + if(!composite_reference && r_reference.declaration) + referenced(r_reference, memacc); +} + +void UnusedVariableRemover::visit(Swizzle &swizzle) +{ + visit_composite(*swizzle.left); + + unsigned mask = 0; + for(unsigned i=0; itoken[0]=='[') { - binary.left->visit(*this); - SetFlag set(assignment_target, false); - binary.right->visit(*this); + visit_composite(*binary.left); + + { + SetFlag clear_assignment(assignment_target, false); + SetFlag clear_composite(composite_reference, false); + binary.right->visit(*this); + } + + add_to_chain(r_reference, Assignment::Target::ARRAY, 0x3F); + + if(!composite_reference && r_reference.declaration) + referenced(r_reference, binary); } else + { + SetFlag clear_composite(composite_reference, false); TraversingVisitor::visit(binary); + } +} + +void UnusedVariableRemover::visit(TernaryExpression &ternary) +{ + SetFlag clear_composite(composite_reference, false); + TraversingVisitor::visit(ternary); } void UnusedVariableRemover::visit(Assignment &assign) @@ -1054,6 +1135,7 @@ void UnusedVariableRemover::visit(Assignment &assign) void UnusedVariableRemover::visit(FunctionCall &call) { + SetFlag clear_composite(composite_reference, false); TraversingVisitor::visit(call); /* Treat function calls as having side effects so expression statements consisting of nothing but a function call won't be optimized away. */ diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index 1504acb2..249a859a 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -280,6 +280,8 @@ private: Assignment *r_assignment; bool assignment_target; bool r_side_effects; + bool composite_reference; + Assignment::Target r_reference; std::set unused_nodes; public: @@ -291,9 +293,13 @@ private: void referenced(const Assignment::Target &, Node &); virtual void visit(VariableReference &); virtual void visit(InterfaceBlockReference &); + void visit_composite(Expression &); + virtual void visit(MemberAccess &); + virtual void visit(Swizzle &); virtual void visit(UnaryExpression &); virtual void visit(BinaryExpression &); virtual void visit(Assignment &); + virtual void visit(TernaryExpression &); virtual void visit(FunctionCall &); void record_assignment(const Assignment::Target &, Node &); virtual void visit(ExpressionStatement &); diff --git a/tests/glsl/unused_component_assignment.glsl b/tests/glsl/unused_component_assignment.glsl new file mode 100644 index 00000000..0febd561 --- /dev/null +++ b/tests/glsl/unused_component_assignment.glsl @@ -0,0 +1,33 @@ +uniform mat4 mvp; + +#pragma MSP stage(vertex) +layout(location=0) in vec4 position; +int main() +{ + vec4 c0 = mvp[0]*position; + vec4 c1 = mvp[1]*position; + vec4 c2 = mvp[2]*position; + vec4 c3 = mvp[3]*position; + vec4 clip_pos; + clip_pos.x = c0.x+c1.x+c2.x+c3.x; + clip_pos.y = c0.y+c1.y+c2.y+c3.y; + clip_pos.z = c0.z+c1.z+c2.z+c3.z; + clip_pos.w = c0.w+c1.w+c2.w+c3.w; + gl_Position = vec4(clip_pos.xy, 0.0, 1.0); +} + +/* Expected output: vertex +layout(location=0) uniform mat4 mvp; +layout(location=0) in vec4 position; +int main() +{ + vec4 c0 = mvp[0]*position; + vec4 c1 = mvp[1]*position; + vec4 c2 = mvp[2]*position; + vec4 c3 = mvp[3]*position; + vec4 clip_pos; + clip_pos.x = c0.x+c1.x+c2.x+c3.x; + clip_pos.y = c0.y+c1.y+c2.y+c3.y; + gl_Position = vec4(clip_pos.xy, 0.0, 1.0); +} +*/ -- 2.43.0