diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp new file mode 100644 index 0000000000..83a0f029b8 --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp @@ -0,0 +1,97 @@ +// +// Copyright 2018 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RewriteRepeatedAssignToSwizzled.cpp: Rewrite expressions that assign an assignment to a swizzled +// vector, like: +// v.x = z = expression; +// to: +// z = expression; +// v.x = z; +// +// Note that this doesn't handle some corner cases: expressions nested inside other expressions, +// inside loop headers, or inside if conditions. + +#include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h" + +#include "compiler/translator/tree_util/IntermNode_util.h" +#include "compiler/translator/tree_util/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class RewriteAssignToSwizzledTraverser : public TIntermTraverser +{ + public: + [[nodiscard]] static bool rewrite(TCompiler *compiler, TIntermBlock *root); + + private: + RewriteAssignToSwizzledTraverser(); + + bool visitBinary(Visit, TIntermBinary *node) override; + + void nextIteration(); + + bool didRewrite() { return mDidRewrite; } + + bool mDidRewrite; +}; + +// static +bool RewriteAssignToSwizzledTraverser::rewrite(TCompiler *compiler, TIntermBlock *root) +{ + RewriteAssignToSwizzledTraverser rewrite; + do + { + rewrite.nextIteration(); + root->traverse(&rewrite); + if (!rewrite.updateTree(compiler, root)) + { + return false; + } + } while (rewrite.didRewrite()); + + return true; +} + +RewriteAssignToSwizzledTraverser::RewriteAssignToSwizzledTraverser() + : TIntermTraverser(true, false, false), mDidRewrite(false) +{} + +void RewriteAssignToSwizzledTraverser::nextIteration() +{ + mDidRewrite = false; +} + +bool RewriteAssignToSwizzledTraverser::visitBinary(Visit, TIntermBinary *node) +{ + TIntermBinary *rightBinary = node->getRight()->getAsBinaryNode(); + TIntermBlock *parentBlock = getParentNode()->getAsBlock(); + if (parentBlock && node->isAssignment() && node->getLeft()->getAsSwizzleNode() && rightBinary && + rightBinary->isAssignment()) + { + TIntermSequence replacements; + replacements.push_back(rightBinary); + TIntermTyped *rightAssignmentTargetCopy = rightBinary->getLeft()->deepCopy(); + TIntermBinary *lastAssign = + new TIntermBinary(EOpAssign, node->getLeft(), rightAssignmentTargetCopy); + replacements.push_back(lastAssign); + mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements)); + mDidRewrite = true; + return false; + } + return true; +} + +} // anonymous namespace + +bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler, TIntermBlock *root) +{ + return RewriteAssignToSwizzledTraverser::rewrite(compiler, root); +} + +} // namespace sh |