tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RewriteRepeatedAssignToSwizzled.cpp (2766B)


      1 //
      2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 // RewriteRepeatedAssignToSwizzled.cpp: Rewrite expressions that assign an assignment to a swizzled
      7 // vector, like:
      8 //     v.x = z = expression;
      9 // to:
     10 //     z = expression;
     11 //     v.x = z;
     12 //
     13 // Note that this doesn't handle some corner cases: expressions nested inside other expressions,
     14 // inside loop headers, or inside if conditions.
     15 
     16 #include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h"
     17 
     18 #include "compiler/translator/tree_util/IntermNode_util.h"
     19 #include "compiler/translator/tree_util/IntermTraverse.h"
     20 
     21 namespace sh
     22 {
     23 
     24 namespace
     25 {
     26 
     27 class RewriteAssignToSwizzledTraverser : public TIntermTraverser
     28 {
     29  public:
     30    [[nodiscard]] static bool rewrite(TCompiler *compiler, TIntermBlock *root);
     31 
     32  private:
     33    RewriteAssignToSwizzledTraverser();
     34 
     35    bool visitBinary(Visit, TIntermBinary *node) override;
     36 
     37    void nextIteration();
     38 
     39    bool didRewrite() { return mDidRewrite; }
     40 
     41    bool mDidRewrite;
     42 };
     43 
     44 // static
     45 bool RewriteAssignToSwizzledTraverser::rewrite(TCompiler *compiler, TIntermBlock *root)
     46 {
     47    RewriteAssignToSwizzledTraverser rewrite;
     48    do
     49    {
     50        rewrite.nextIteration();
     51        root->traverse(&rewrite);
     52        if (!rewrite.updateTree(compiler, root))
     53        {
     54            return false;
     55        }
     56    } while (rewrite.didRewrite());
     57 
     58    return true;
     59 }
     60 
     61 RewriteAssignToSwizzledTraverser::RewriteAssignToSwizzledTraverser()
     62    : TIntermTraverser(true, false, false), mDidRewrite(false)
     63 {}
     64 
     65 void RewriteAssignToSwizzledTraverser::nextIteration()
     66 {
     67    mDidRewrite = false;
     68 }
     69 
     70 bool RewriteAssignToSwizzledTraverser::visitBinary(Visit, TIntermBinary *node)
     71 {
     72    TIntermBinary *rightBinary = node->getRight()->getAsBinaryNode();
     73    TIntermBlock *parentBlock  = getParentNode()->getAsBlock();
     74    if (parentBlock && node->isAssignment() && node->getLeft()->getAsSwizzleNode() && rightBinary &&
     75        rightBinary->isAssignment())
     76    {
     77        TIntermSequence replacements;
     78        replacements.push_back(rightBinary);
     79        TIntermTyped *rightAssignmentTargetCopy = rightBinary->getLeft()->deepCopy();
     80        TIntermBinary *lastAssign =
     81            new TIntermBinary(EOpAssign, node->getLeft(), rightAssignmentTargetCopy);
     82        replacements.push_back(lastAssign);
     83        mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
     84        mDidRewrite = true;
     85        return false;
     86    }
     87    return true;
     88 }
     89 
     90 }  // anonymous namespace
     91 
     92 bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler, TIntermBlock *root)
     93 {
     94    return RewriteAssignToSwizzledTraverser::rewrite(compiler, root);
     95 }
     96 
     97 }  // namespace sh