// 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 Function %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();

    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());
    }

    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.Add32BitUnsignedIntegerConstant(13));
  EXPECT_NE(nullptr, builder.Add32BitSignedIntegerConstant(-1));

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

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

  // Try adding 0 as both signed and unsigned.
  EXPECT_NE(nullptr, builder.Add32BitUnsignedIntegerConstant(0));
  EXPECT_NE(nullptr, builder.Add32BitSignedIntegerConstant(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.Add32BitUnsignedIntegerConstant(13);
  Instruction* const_2 = builder.Add32BitSignedIntegerConstant(-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.Add32BitUnsignedIntegerConstant(13));
  EXPECT_EQ(const_2, builder.Add32BitSignedIntegerConstant(-1));

  Instruction* const_3 = builder.Add32BitUnsignedIntegerConstant(1);
  Instruction* const_4 = builder.Add32BitSignedIntegerConstant(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.Add32BitUnsignedIntegerConstant(0);
  Instruction* const_6 = builder.Add32BitSignedIntegerConstant(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());
}

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