// Copyright (c) 2019 Google LLC
//
// 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 "reduce_test_util.h"
#include "source/opt/build_module.h"
#include "source/reduce/reduction_opportunity.h"
#include "source/reduce/remove_block_reduction_opportunity.h"
#include "source/reduce/remove_block_reduction_opportunity_finder.h"

namespace spvtools {
namespace reduce {
namespace {

TEST(RemoveBlockReductionPassTest, BasicCheck) {
  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "x"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %9 = OpConstant %6 1
         %10 = OpConstant %6 2
         %11 = OpConstant %6 3
         %12 = OpConstant %6 4
          %4 = OpFunction %2 None %3
          %5 = OpLabel
          %8 = OpVariable %7 Function
               OpBranch %14
         %13 = OpLabel ; unreachable
               OpStore %8 %9
               OpBranch %14
         %14 = OpLabel
               OpStore %8 %10
               OpBranch %16
         %15 = OpLabel ; unreachable
               OpStore %8 %11
               OpBranch %16
         %16 = OpLabel
               OpStore %8 %12
               OpBranch %17
         %17 = OpLabel
               OpReturn
               OpFunctionEnd
  )";
  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context =
      BuildModule(env, consumer, shader, kReduceAssembleOption);
  const auto ops =
      RemoveBlockReductionOpportunityFinder().GetAvailableOpportunities(
          context.get());
  ASSERT_EQ(2, ops.size());

  ASSERT_TRUE(ops[0]->PreconditionHolds());
  ops[0]->TryToApply();

  std::string after_op_0 = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "x"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %9 = OpConstant %6 1
         %10 = OpConstant %6 2
         %11 = OpConstant %6 3
         %12 = OpConstant %6 4
          %4 = OpFunction %2 None %3
          %5 = OpLabel
          %8 = OpVariable %7 Function
               OpBranch %14
         %14 = OpLabel
               OpStore %8 %10
               OpBranch %16
         %15 = OpLabel
               OpStore %8 %11
               OpBranch %16
         %16 = OpLabel
               OpStore %8 %12
               OpBranch %17
         %17 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  CheckEqual(env, after_op_0, context.get());

  ASSERT_TRUE(ops[1]->PreconditionHolds());
  ops[1]->TryToApply();

  std::string after_op_1 = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "x"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %9 = OpConstant %6 1
         %10 = OpConstant %6 2
         %11 = OpConstant %6 3
         %12 = OpConstant %6 4
          %4 = OpFunction %2 None %3
          %5 = OpLabel
          %8 = OpVariable %7 Function
               OpBranch %14
         %14 = OpLabel
               OpStore %8 %10
               OpBranch %16
         %16 = OpLabel
               OpStore %8 %12
               OpBranch %17
         %17 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  CheckEqual(env, after_op_1, context.get());
}

TEST(RemoveBlockReductionPassTest, UnreachableContinueAndMerge) {
  // Loop with unreachable merge and continue target. There should be no
  // opportunities.

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpBranch %13
         %13 = OpLabel
               OpLoopMerge %16 %15 None
               OpBranch %14
         %14 = OpLabel
               OpReturn
         %15 = OpLabel
               OpBranch %13
         %16 = OpLabel
               OpReturn
               OpFunctionEnd
  )";
  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context =
      BuildModule(env, consumer, shader, kReduceAssembleOption);
  const auto ops =
      RemoveBlockReductionOpportunityFinder().GetAvailableOpportunities(
          context.get());
  ASSERT_EQ(0, ops.size());
}

TEST(RemoveBlockReductionPassTest, OneBlock) {
  // Function with just one block. There should be no opportunities.

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
  )";
  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context =
      BuildModule(env, consumer, shader, kReduceAssembleOption);
  const auto ops =
      RemoveBlockReductionOpportunityFinder().GetAvailableOpportunities(
          context.get());
  ASSERT_EQ(0, ops.size());
}

TEST(RemoveBlockReductionPassTest, UnreachableBlocksWithOutsideIdUses) {
  // A function with two unreachable blocks A -> B. A defines ID %9 and B uses
  // %9. There are no references to A, but removing A would be invalid because
  // of B's use of %9, so there should be no opportunities.

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main"
               OpExecutionMode %2 OriginUpperLeft
               OpSource ESSL 310
               OpName %2 "main"
          %3 = OpTypeVoid
          %4 = OpTypeInt 32 1
          %5 = OpTypeFunction %3
          %6 = OpConstant %4 1
          %2 = OpFunction %3 None %5
          %7 = OpLabel
               OpReturn
          %8 = OpLabel          ; A
          %9 = OpUndef %4
               OpBranch %10
         %10 = OpLabel          ; B
         %11 = OpIAdd %4 %6 %9  ; uses %9 from A, so A cannot be removed
               OpReturn
               OpFunctionEnd
  )";
  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context =
      BuildModule(env, consumer, shader, kReduceAssembleOption);
  const auto ops =
      RemoveBlockReductionOpportunityFinder().GetAvailableOpportunities(
          context.get());
  ASSERT_EQ(0, ops.size());
}

TEST(RemoveBlockReductionPassTest, UnreachableBlocksWithInsideIdUses) {
  // Similar to the above test.

  // A function with two unreachable blocks A -> B. Both blocks create and use
  // IDs, but the uses are contained within each block, so A should be removed.

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main"
               OpExecutionMode %2 OriginUpperLeft
               OpSource ESSL 310
               OpName %2 "main"
          %3 = OpTypeVoid
          %4 = OpTypeInt 32 1
          %5 = OpTypeFunction %3
          %6 = OpConstant %4 1
          %2 = OpFunction %3 None %5
          %7 = OpLabel
               OpReturn
          %8 = OpLabel                     ; A
          %9 = OpUndef %4                  ; define %9
         %10 = OpIAdd %4 %6 %9             ; use %9
               OpBranch %11
         %11 = OpLabel                     ; B
         %12 = OpUndef %4                  ; define %12
         %13 = OpIAdd %4 %6 %12            ; use %12
               OpReturn
               OpFunctionEnd
  )";
  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context =
      BuildModule(env, consumer, shader, kReduceAssembleOption);
  auto ops = RemoveBlockReductionOpportunityFinder().GetAvailableOpportunities(
      context.get());
  ASSERT_EQ(1, ops.size());

  ASSERT_TRUE(ops[0]->PreconditionHolds());

  ops[0]->TryToApply();

  // Same as above, but block A is removed.
  std::string after_op_0 = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main"
               OpExecutionMode %2 OriginUpperLeft
               OpSource ESSL 310
               OpName %2 "main"
          %3 = OpTypeVoid
          %4 = OpTypeInt 32 1
          %5 = OpTypeFunction %3
          %6 = OpConstant %4 1
          %2 = OpFunction %3 None %5
          %7 = OpLabel
               OpReturn
         %11 = OpLabel
         %12 = OpUndef %4
         %13 = OpIAdd %4 %6 %12
               OpReturn
               OpFunctionEnd
  )";

  CheckEqual(env, after_op_0, context.get());

  // Find opportunities again. There are no reference to B. B should now be
  // removed.

  ops = RemoveBlockReductionOpportunityFinder().GetAvailableOpportunities(
      context.get());

  ASSERT_EQ(1, ops.size());

  ASSERT_TRUE(ops[0]->PreconditionHolds());

  ops[0]->TryToApply();

  // Same as above, but block B is removed.
  std::string after_op_0_again = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main"
               OpExecutionMode %2 OriginUpperLeft
               OpSource ESSL 310
               OpName %2 "main"
          %3 = OpTypeVoid
          %4 = OpTypeInt 32 1
          %5 = OpTypeFunction %3
          %6 = OpConstant %4 1
          %2 = OpFunction %3 None %5
          %7 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  CheckEqual(env, after_op_0_again, context.get());
}

}  // namespace
}  // namespace reduce
}  // namespace spvtools
