// Copyright (c) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "source/opt/propagator.h"

#include <map>
#include <memory>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "source/opt/build_module.h"
#include "source/opt/cfg.h"
#include "source/opt/ir_context.h"

namespace spvtools {
namespace opt {
namespace {

using ::testing::UnorderedElementsAre;

class PropagatorTest : public testing::Test {
 protected:
  virtual void TearDown() {
    ctx_.reset(nullptr);
    values_.clear();
    values_vec_.clear();
  }

  void Assemble(const std::string& input) {
    ctx_ = BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, input);
    ASSERT_NE(nullptr, ctx_) << "Assembling failed for shader:\n"
                             << input << "\n";
  }

  bool Propagate(const SSAPropagator::VisitFunction& visit_fn) {
    SSAPropagator propagator(ctx_.get(), visit_fn);
    bool retval = false;
    for (auto& fn : *ctx_->module()) {
      retval |= propagator.Run(&fn);
    }
    return retval;
  }

  const std::vector<uint32_t>& GetValues() {
    values_vec_.clear();
    for (const auto& it : values_) {
      values_vec_.push_back(it.second);
    }
    return values_vec_;
  }

  std::unique_ptr<IRContext> ctx_;
  std::map<uint32_t, uint32_t> values_;
  std::vector<uint32_t> values_vec_;
};

TEST_F(PropagatorTest, LocalPropagate) {
  const std::string spv_asm = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %outparm
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %x "x"
               OpName %y "y"
               OpName %z "z"
               OpName %outparm "outparm"
               OpDecorate %outparm Location 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
        %int = OpTypeInt 32 1
%_ptr_Function_int = OpTypePointer Function %int
      %int_4 = OpConstant %int 4
      %int_3 = OpConstant %int 3
      %int_1 = OpConstant %int 1
%_ptr_Output_int = OpTypePointer Output %int
    %outparm = OpVariable %_ptr_Output_int Output
       %main = OpFunction %void None %3
          %5 = OpLabel
          %x = OpVariable %_ptr_Function_int Function
          %y = OpVariable %_ptr_Function_int Function
          %z = OpVariable %_ptr_Function_int Function
               OpStore %x %int_4
               OpStore %y %int_3
               OpStore %z %int_1
         %20 = OpLoad %int %z
               OpStore %outparm %20
               OpReturn
               OpFunctionEnd
               )";
  Assemble(spv_asm);

  const auto visit_fn = [this](Instruction* instr, BasicBlock** dest_bb) {
    *dest_bb = nullptr;
    if (instr->opcode() == spv::Op::OpStore) {
      uint32_t lhs_id = instr->GetSingleWordOperand(0);
      uint32_t rhs_id = instr->GetSingleWordOperand(1);
      Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id);
      if (rhs_def->opcode() == spv::Op::OpConstant) {
        uint32_t val = rhs_def->GetSingleWordOperand(2);
        values_[lhs_id] = val;
        return SSAPropagator::kInteresting;
      }
    }
    return SSAPropagator::kVarying;
  };

  EXPECT_TRUE(Propagate(visit_fn));
  EXPECT_THAT(GetValues(), UnorderedElementsAre(4, 3, 1));
}

TEST_F(PropagatorTest, PropagateThroughPhis) {
  const std::string spv_asm = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %x %outparm
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %x "x"
               OpName %outparm "outparm"
               OpDecorate %x Flat
               OpDecorate %x Location 0
               OpDecorate %outparm Location 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
        %int = OpTypeInt 32 1
       %bool = OpTypeBool
%_ptr_Function_int = OpTypePointer Function %int
      %int_4 = OpConstant %int 4
      %int_3 = OpConstant %int 3
      %int_1 = OpConstant %int 1
%_ptr_Input_int = OpTypePointer Input %int
          %x = OpVariable %_ptr_Input_int Input
%_ptr_Output_int = OpTypePointer Output %int
    %outparm = OpVariable %_ptr_Output_int Output
       %main = OpFunction %void None %3
          %4 = OpLabel
          %5 = OpLoad %int %x
          %6 = OpSGreaterThan %bool %5 %int_3
               OpSelectionMerge %25 None
               OpBranchConditional %6 %22 %23
         %22 = OpLabel
          %7 = OpLoad %int %int_4
               OpBranch %25
         %23 = OpLabel
          %8 = OpLoad %int %int_4
               OpBranch %25
         %25 = OpLabel
         %35 = OpPhi %int %7 %22 %8 %23
               OpStore %outparm %35
               OpReturn
               OpFunctionEnd
               )";

  Assemble(spv_asm);

  Instruction* phi_instr = nullptr;
  const auto visit_fn = [this, &phi_instr](Instruction* instr,
                                           BasicBlock** dest_bb) {
    *dest_bb = nullptr;
    if (instr->opcode() == spv::Op::OpLoad) {
      uint32_t rhs_id = instr->GetSingleWordOperand(2);
      Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id);
      if (rhs_def->opcode() == spv::Op::OpConstant) {
        uint32_t val = rhs_def->GetSingleWordOperand(2);
        values_[instr->result_id()] = val;
        return SSAPropagator::kInteresting;
      }
    } else if (instr->opcode() == spv::Op::OpPhi) {
      phi_instr = instr;
      SSAPropagator::PropStatus retval;
      for (uint32_t i = 2; i < instr->NumOperands(); i += 2) {
        uint32_t phi_arg_id = instr->GetSingleWordOperand(i);
        auto it = values_.find(phi_arg_id);
        if (it != values_.end()) {
          EXPECT_EQ(it->second, 4u);
          retval = SSAPropagator::kInteresting;
          values_[instr->result_id()] = it->second;
        } else {
          retval = SSAPropagator::kNotInteresting;
          break;
        }
      }
      return retval;
    }

    return SSAPropagator::kVarying;
  };

  EXPECT_TRUE(Propagate(visit_fn));

  // The propagator should've concluded that the Phi instruction has a constant
  // value of 4.
  EXPECT_NE(phi_instr, nullptr);
  EXPECT_EQ(values_[phi_instr->result_id()], 4u);

  EXPECT_THAT(GetValues(), UnorderedElementsAre(4u, 4u, 4u));
}

}  // namespace
}  // namespace opt
}  // namespace spvtools
