// Copyright (c) 2018 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 <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "effcee/effcee.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "source/opt/basic_block.h"
#include "source/opt/build_module.h"
#include "source/opt/instruction.h"
#include "source/opt/ir_builder.h"
#include "source/opt/type_manager.h"
#include "spirv-tools/libspirv.hpp"

namespace spvtools {
namespace opt {
namespace {

using Analysis = IRContext::Analysis;
using IRBuilderTest = ::testing::Test;

bool Validate(const std::vector<uint32_t>& bin) {
  spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
  spv_context spvContext = spvContextCreate(target_env);
  spv_diagnostic diagnostic = nullptr;
  spv_const_binary_t binary = {bin.data(), bin.size()};
  spv_result_t error = spvValidate(spvContext, &binary, &diagnostic);
  if (error != 0) spvDiagnosticPrint(diagnostic);
  spvDiagnosticDestroy(diagnostic);
  spvContextDestroy(spvContext);
  return error == 0;
}

void Match(const std::string& original, IRContext* context,
           bool do_validation = true) {
  std::vector<uint32_t> bin;
  context->module()->ToBinary(&bin, true);
  if (do_validation) {
    EXPECT_TRUE(Validate(bin));
  }
  std::string assembly;
  SpirvTools tools(SPV_ENV_UNIVERSAL_1_2);
  EXPECT_TRUE(
      tools.Disassemble(bin, &assembly, SpirvTools::kDefaultDisassembleOption))
      << "Disassembling failed for shader:\n"
      << assembly << std::endl;
  auto match_result = effcee::Match(assembly, original);
  EXPECT_EQ(effcee::Result::Status::Ok, match_result.status())
      << match_result.message() << "\nChecking result:\n"
      << assembly;
}

TEST_F(IRBuilderTest, TestInsnAddition) {
  const std::string text = R"(
; CHECK: %18 = OpLabel
; CHECK: OpPhi %int %int_0 %14
; CHECK: OpPhi %bool %16 %14
; CHECK: OpBranch %17
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main" %3
               OpExecutionMode %2 OriginUpperLeft
               OpSource GLSL 330
               OpName %2 "main"
               OpName %4 "i"
               OpName %3 "c"
               OpDecorate %3 Location 0
          %5 = OpTypeVoid
          %6 = OpTypeFunction %5
          %7 = OpTypeInt 32 1
          %8 = OpTypePointer Function %7
          %9 = OpConstant %7 0
         %10 = OpTypeBool
         %11 = OpTypeFloat 32
         %12 = OpTypeVector %11 4
         %13 = OpTypePointer Output %12
          %3 = OpVariable %13 Output
          %2 = OpFunction %5 None %6
         %14 = OpLabel
          %4 = OpVariable %8 Function
               OpStore %4 %9
         %15 = OpLoad %7 %4
         %16 = OpINotEqual %10 %15 %9
               OpSelectionMerge %17 None
               OpBranchConditional %16 %18 %17
         %18 = OpLabel
               OpBranch %17
         %17 = OpLabel
               OpReturn
               OpFunctionEnd
)";

  {
    std::unique_ptr<IRContext> context =
        BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);

    BasicBlock* bb = context->cfg()->block(18);

    // Build managers.
    context->get_def_use_mgr();
    context->get_instr_block(nullptr);

    InstructionBuilder builder(context.get(), &*bb->begin());
    Instruction* phi1 = builder.AddPhi(7, {9, 14});
    Instruction* phi2 = builder.AddPhi(10, {16, 14});

    // Make sure the InstructionBuilder did not update the def/use manager.
    EXPECT_EQ(context->get_def_use_mgr()->GetDef(phi1->result_id()), nullptr);
    EXPECT_EQ(context->get_def_use_mgr()->GetDef(phi2->result_id()), nullptr);
    EXPECT_EQ(context->get_instr_block(phi1), nullptr);
    EXPECT_EQ(context->get_instr_block(phi2), nullptr);

    Match(text, context.get());
  }

  {
    std::unique_ptr<IRContext> context =
        BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);

    // Build managers.
    context->get_def_use_mgr();
    context->get_instr_block(nullptr);

    BasicBlock* bb = context->cfg()->block(18);
    InstructionBuilder builder(
        context.get(), &*bb->begin(),
        IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
    Instruction* phi1 = builder.AddPhi(7, {9, 14});
    Instruction* phi2 = builder.AddPhi(10, {16, 14});

    // Make sure InstructionBuilder updated the def/use manager
    EXPECT_NE(context->get_def_use_mgr()->GetDef(phi1->result_id()), nullptr);
    EXPECT_NE(context->get_def_use_mgr()->GetDef(phi2->result_id()), nullptr);
    EXPECT_NE(context->get_instr_block(phi1), nullptr);
    EXPECT_NE(context->get_instr_block(phi2), nullptr);

    Match(text, context.get());
  }
}

TEST_F(IRBuilderTest, TestCondBranchAddition) {
  const std::string text = R"(
; CHECK: %main = OpFunction %void None %6
; CHECK-NEXT: %15 = OpLabel
; CHECK-NEXT: OpSelectionMerge %13 None
; CHECK-NEXT: OpBranchConditional %true %14 %13
; CHECK-NEXT: %14 = OpLabel
; CHECK-NEXT: OpBranch %13
; CHECK-NEXT: %13 = OpLabel
; CHECK-NEXT: OpReturn
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main" %3
               OpExecutionMode %2 OriginUpperLeft
               OpSource GLSL 330
               OpName %2 "main"
               OpName %4 "i"
               OpName %3 "c"
               OpDecorate %3 Location 0
          %5 = OpTypeVoid
          %6 = OpTypeFunction %5
          %7 = OpTypeBool
          %8 = OpTypePointer Private %7
          %9 = OpConstantTrue %7
         %10 = OpTypeFloat 32
         %11 = OpTypeVector %10 4
         %12 = OpTypePointer Output %11
          %3 = OpVariable %12 Output
          %4 = OpVariable %8 Private
          %2 = OpFunction %5 None %6
         %13 = OpLabel
               OpReturn
               OpFunctionEnd
)";

  {
    std::unique_ptr<IRContext> context =
        BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);

    Function& fn = *context->module()->begin();

    BasicBlock& bb_merge = *fn.begin();

    // TODO(1841): Handle id overflow.
    fn.begin().InsertBefore(std::unique_ptr<BasicBlock>(
        new BasicBlock(std::unique_ptr<Instruction>(new Instruction(
            context.get(), SpvOpLabel, 0, context->TakeNextId(), {})))));
    BasicBlock& bb_true = *fn.begin();
    {
      InstructionBuilder builder(context.get(), &*bb_true.begin());
      builder.AddBranch(bb_merge.id());
    }

    // TODO(1841): Handle id overflow.
    fn.begin().InsertBefore(std::unique_ptr<BasicBlock>(
        new BasicBlock(std::unique_ptr<Instruction>(new Instruction(
            context.get(), SpvOpLabel, 0, context->TakeNextId(), {})))));
    BasicBlock& bb_cond = *fn.begin();

    InstructionBuilder builder(context.get(), &bb_cond);
    // This also test consecutive instruction insertion: merge selection +
    // branch.
    builder.AddConditionalBranch(9, bb_true.id(), bb_merge.id(), bb_merge.id());

    Match(text, context.get());
  }
}

TEST_F(IRBuilderTest, AddSelect) {
  const std::string text = R"(
; CHECK: [[bool:%\w+]] = OpTypeBool
; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
; CHECK: [[true:%\w+]] = OpConstantTrue [[bool]]
; CHECK: [[u0:%\w+]] = OpConstant [[uint]] 0
; CHECK: [[u1:%\w+]] = OpConstant [[uint]] 1
; CHECK: OpSelect [[uint]] [[true]] [[u0]] [[u1]]
OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
%1 = OpTypeVoid
%2 = OpTypeBool
%3 = OpTypeInt 32 0
%4 = OpConstantTrue %2
%5 = OpConstant %3 0
%6 = OpConstant %3 1
%7 = OpTypeFunction %1
%8 = OpFunction %1 None %7
%9 = OpLabel
OpReturn
OpFunctionEnd
)";

  std::unique_ptr<IRContext> context =
      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  EXPECT_NE(nullptr, context);

  InstructionBuilder builder(context.get(),
                             &*context->module()->begin()->begin()->begin());
  EXPECT_NE(nullptr, builder.AddSelect(3u, 4u, 5u, 6u));

  Match(text, context.get());
}

TEST_F(IRBuilderTest, AddCompositeConstruct) {
  const std::string text = R"(
; CHECK: [[uint:%\w+]] = OpTypeInt
; CHECK: [[u0:%\w+]] = OpConstant [[uint]] 0
; CHECK: [[u1:%\w+]] = OpConstant [[uint]] 1
; CHECK: [[struct:%\w+]] = OpTypeStruct [[uint]] [[uint]] [[uint]] [[uint]]
; CHECK: OpCompositeConstruct [[struct]] [[u0]] [[u1]] [[u1]] [[u0]]
OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
%1 = OpTypeVoid
%2 = OpTypeInt 32 0
%3 = OpConstant %2 0
%4 = OpConstant %2 1
%5 = OpTypeStruct %2 %2 %2 %2
%6 = OpTypeFunction %1
%7 = OpFunction %1 None %6
%8 = OpLabel
OpReturn
OpFunctionEnd
)";

  std::unique_ptr<IRContext> context =
      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  EXPECT_NE(nullptr, context);

  InstructionBuilder builder(context.get(),
                             &*context->module()->begin()->begin()->begin());
  std::vector<uint32_t> ids = {3u, 4u, 4u, 3u};
  EXPECT_NE(nullptr, builder.AddCompositeConstruct(5u, ids));

  Match(text, context.get());
}

TEST_F(IRBuilderTest, ConstantAdder) {
  const std::string text = R"(
; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
; CHECK: OpConstant [[uint]] 13
; CHECK: [[sint:%\w+]] = OpTypeInt 32 1
; CHECK: OpConstant [[sint]] -1
; CHECK: OpConstant [[uint]] 1
; CHECK: OpConstant [[sint]] 34
; CHECK: OpConstant [[uint]] 0
; CHECK: OpConstant [[sint]] 0
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%3 = OpFunction %1 None %2
%4 = OpLabel
OpReturn
OpFunctionEnd
)";

  std::unique_ptr<IRContext> context =
      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  EXPECT_NE(nullptr, context);

  InstructionBuilder builder(context.get(),
                             &*context->module()->begin()->begin()->begin());
  EXPECT_NE(nullptr, builder.GetUintConstant(13));
  EXPECT_NE(nullptr, builder.GetSintConstant(-1));

  // Try adding the same constants again to make sure they aren't added.
  EXPECT_NE(nullptr, builder.GetUintConstant(13));
  EXPECT_NE(nullptr, builder.GetSintConstant(-1));

  // Try adding different constants to make sure the type is reused.
  EXPECT_NE(nullptr, builder.GetUintConstant(1));
  EXPECT_NE(nullptr, builder.GetSintConstant(34));

  // Try adding 0 as both signed and unsigned.
  EXPECT_NE(nullptr, builder.GetUintConstant(0));
  EXPECT_NE(nullptr, builder.GetSintConstant(0));

  Match(text, context.get());
}

TEST_F(IRBuilderTest, ConstantAdderTypeAlreadyExists) {
  const std::string text = R"(
; CHECK: OpConstant %uint 13
; CHECK: OpConstant %int -1
; CHECK: OpConstant %uint 1
; CHECK: OpConstant %int 34
; CHECK: OpConstant %uint 0
; CHECK: OpConstant %int 0
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
%1 = OpTypeVoid
%uint = OpTypeInt 32 0
%int = OpTypeInt 32 1
%4 = OpTypeFunction %1
%5 = OpFunction %1 None %4
%6 = OpLabel
OpReturn
OpFunctionEnd
)";

  std::unique_ptr<IRContext> context =
      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  EXPECT_NE(nullptr, context);

  InstructionBuilder builder(context.get(),
                             &*context->module()->begin()->begin()->begin());
  Instruction* const_1 = builder.GetUintConstant(13);
  Instruction* const_2 = builder.GetSintConstant(-1);

  EXPECT_NE(nullptr, const_1);
  EXPECT_NE(nullptr, const_2);

  // Try adding the same constants again to make sure they aren't added.
  EXPECT_EQ(const_1, builder.GetUintConstant(13));
  EXPECT_EQ(const_2, builder.GetSintConstant(-1));

  Instruction* const_3 = builder.GetUintConstant(1);
  Instruction* const_4 = builder.GetSintConstant(34);

  // Try adding different constants to make sure the type is reused.
  EXPECT_NE(nullptr, const_3);
  EXPECT_NE(nullptr, const_4);

  Instruction* const_5 = builder.GetUintConstant(0);
  Instruction* const_6 = builder.GetSintConstant(0);

  // Try adding 0 as both signed and unsigned.
  EXPECT_NE(nullptr, const_5);
  EXPECT_NE(nullptr, const_6);

  // They have the same value but different types so should be unique.
  EXPECT_NE(const_5, const_6);

  // Check the types are correct.
  uint32_t type_id_unsigned = const_1->GetSingleWordOperand(0);
  uint32_t type_id_signed = const_2->GetSingleWordOperand(0);

  EXPECT_NE(type_id_unsigned, type_id_signed);

  EXPECT_EQ(const_3->GetSingleWordOperand(0), type_id_unsigned);
  EXPECT_EQ(const_5->GetSingleWordOperand(0), type_id_unsigned);

  EXPECT_EQ(const_4->GetSingleWordOperand(0), type_id_signed);
  EXPECT_EQ(const_6->GetSingleWordOperand(0), type_id_signed);

  Match(text, context.get());
}

TEST_F(IRBuilderTest, AccelerationStructureNV) {
  const std::string text = R"(
; CHECK: OpTypeAccelerationStructureKHR
OpCapability Shader
OpCapability RayTracingNV
OpExtension "SPV_NV_ray_tracing"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %8 "main"
OpExecutionMode %8 OriginUpperLeft
%1 = OpTypeVoid
%2 = OpTypeBool
%3 = OpTypeAccelerationStructureNV
%7 = OpTypeFunction %1
%8 = OpFunction %1 None %7
%9 = OpLabel
OpReturn
OpFunctionEnd
)";

  std::unique_ptr<IRContext> context =
      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  EXPECT_NE(nullptr, context);

  InstructionBuilder builder(context.get(),
                             &*context->module()->begin()->begin()->begin());
  Match(text, context.get());
}

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