From: Mikko Rasa Date: Sun, 17 Dec 2023 10:44:51 +0000 (+0200) Subject: Fix some issues with inlining variables in GLSL X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=8d8e54806c5270148b55b2b8475f5e546a1ca9da;p=libs%2Fgl.git Fix some issues with inlining variables in GLSL --- diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 0086a072..6b2f1a03 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -351,6 +351,17 @@ bool ExpressionInliner::apply(Stage &s) return any_inlined; } +void ExpressionInliner::visit(Block &block) +{ + TraversingVisitor::visit(block); + + /* Block inlining of any assignments from the scope as we leave it. They + may depend on local variables or might not always be executed. */ + for(ExpressionInfo &e: expressions) + if(e.assign_scope==&block) + e.blocked = true; +} + void ExpressionInliner::visit(NodePtr &expr) { r_ref_info = nullptr; @@ -371,11 +382,6 @@ void ExpressionInliner::visit(NodePtr &expr) for(Block *i=iteration_body->parent; (!use.blocked && i); i=i->parent) use.blocked = (i==r_ref_info->assign_scope); } - - /* Block inlining assignments from from inner scopes. The assignment may - depend on local variables of that scope or may not always be executed. */ - for(Block *i=r_ref_info->assign_scope->parent; (!use.blocked && i); i=i->parent) - use.blocked = (i==current_block); } r_oper = expr->oper; r_ref_info = nullptr; @@ -459,8 +465,16 @@ void ExpressionInliner::visit(Assignment &assign) for(; (i!=assignments.end() && i->first.declaration==assign.target.declaration); ++i) if(targets_overlap(i->first, assign.target)) + { i->second->blocked = true; + /* Block further inlining of any expressions which used the + previous value of this variable. */ + for(const ExpressionUse &u: i->second->uses) + if(u.containing_expr) + u.containing_expr->blocked = true; + } + info->trivial = r_trivial; assignments[assign.target] = info; } diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index d3d475b6..55b5e11b 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -142,6 +142,7 @@ public: bool apply(Stage &); private: + void visit(Block &) override; void visit(NodePtr &) override; void visit(VariableReference &) override; void visit(MemberAccess &) override; diff --git a/tests/glsl/swap.glsl b/tests/glsl/swap.glsl new file mode 100644 index 00000000..de7d5250 --- /dev/null +++ b/tests/glsl/swap.glsl @@ -0,0 +1,57 @@ +#pragma MSP stage(vertex) +layout(location=0) in vec4 vertex; +void main() +{ + float x = vertex.x; + float y = vertex.y; + float z = vertex.z; + if(x>y) + { + float temp = x; + x = y; + y = temp; + } + if(y>z) + { + float temp = y; + y = z; + z = temp; + } + if(x>y) + { + float temp = x; + x = y; + y = temp; + } + gl_Position = vec4(x, y, z, 1.0); +} + +/* Expected output: vertex +layout(location=0) in vec4 vertex; +void main() +{ + float x = vertex.x; + float y = vertex.y; + float z = vertex.z; + if(x>y) + { + float temp = x; + x = y; + y = temp; + } + if(y>z) + { + float temp = y; + y = z; + z = temp; + } + if(x>y) + { + float temp = x; + x = y; + y = temp; + } + gl_Position = vec4(x, y, z, 1.0); + gl_Position.z = gl_Position.z*2.0-gl_Position.w; +} +*/