diff options
Diffstat (limited to 'gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp')
-rw-r--r-- | gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp | 106 |
1 files changed, 0 insertions, 106 deletions
diff --git a/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp b/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp deleted file mode 100644 index 018e72cd1..000000000 --- a/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// -// Copyright (c) 2016 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. -// - -// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend -// may record a variable as aliasing another. Sometimes the alias information gets garbled -// so we work around this issue by breaking the aliasing chain in inner loops. - -#include "BreakVariableAliasingInInnerLoops.h" - -#include "compiler/translator/IntermNode.h" - -// A HLSL compiler developer gave us more details on the root cause and the workaround needed: -// The root problem is that if the HLSL compiler is applying aliasing information even on -// incomplete simulations (in this case, a single pass). The bug is triggered by an assignment -// that comes from a series of assignments, possibly with swizzled or ternary operators with -// known conditionals, where the source is before the loop. -// So, a workaround is to add a +0 term to variables the first time they are assigned to in -// an inner loop (if they are declared in an outside scope, otherwise there is no need). -// This will break the aliasing chain. - -// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because -// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure -// assignment don't need a workaround. - -namespace sh -{ - -namespace -{ - -class AliasingBreaker : public TIntermTraverser -{ - public: - AliasingBreaker() : TIntermTraverser(true, false, true) {} - - protected: - bool visitBinary(Visit visit, TIntermBinary *binary) - { - if (visit != PreVisit) - { - return false; - } - - if (mLoopLevel < 2 || !binary->isAssignment()) - { - return true; - } - - TIntermTyped *B = binary->getRight(); - TType type = B->getType(); - - if (!type.isScalar() && !type.isVector() && !type.isMatrix()) - { - return true; - } - - if (type.isArray() || IsSampler(type.getBasicType())) - { - return true; - } - - // We have a scalar / vector / matrix assignment with loop depth 2. - // Transform it from - // A = B - // to - // A = (B + typeof<B>(0)); - - TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type)); - bPlusZero->setLine(B->getLine()); - - binary->replaceChildNode(B, bPlusZero); - - return true; - } - - bool visitLoop(Visit visit, TIntermLoop *loop) - { - if (visit == PreVisit) - { - mLoopLevel++; - } - else - { - ASSERT(mLoopLevel > 0); - mLoopLevel--; - } - - return true; - } - - private: - int mLoopLevel = 0; -}; - -} // anonymous namespace - -void BreakVariableAliasingInInnerLoops(TIntermNode *root) -{ - AliasingBreaker breaker; - root->traverse(&breaker); -} - -} // namespace sh |