//
// 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
