//
// 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_util.h"
#include "compiler/translator/IntermTraverse.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, CreateZeroNode(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
