// Copyright 2015 the V8 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.

#include "src/compiler/common-operator.h"
#include "src/compiler/dead-code-elimination.h"
#include "test/unittests/compiler/graph-reducer-unittest.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
#include "testing/gmock-support.h"

using testing::StrictMock;

namespace v8 {
namespace internal {
namespace compiler {
namespace dead_code_elimination_unittest {

class DeadCodeEliminationTest : public GraphTest {
 public:
  explicit DeadCodeEliminationTest(int num_parameters = 4)
      : GraphTest(num_parameters) {}
  ~DeadCodeEliminationTest() override {}

 protected:
  Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) {
    DeadCodeElimination reducer(editor, graph(), common(), zone());
    return reducer.Reduce(node);
  }

  Reduction Reduce(Node* node) {
    StrictMock<MockAdvancedReducerEditor> editor;
    return Reduce(&editor, node);
  }
};


namespace {

const MachineRepresentation kMachineRepresentations[] = {
    MachineRepresentation::kBit,     MachineRepresentation::kWord8,
    MachineRepresentation::kWord16,  MachineRepresentation::kWord32,
    MachineRepresentation::kWord64,  MachineRepresentation::kFloat32,
    MachineRepresentation::kFloat64, MachineRepresentation::kTagged};


const int kMaxInputs = 16;


const Operator kOp0(0, Operator::kNoProperties, "Op0", 1, 1, 1, 1, 1, 1);

}  // namespace


// -----------------------------------------------------------------------------
// General dead propagation


TEST_F(DeadCodeEliminationTest, GeneralDeadPropagation) {
  Node* const value = Parameter(0);
  Node* const effect = graph()->start();
  Node* const dead = graph()->NewNode(common()->Dead());
  Node* const node = graph()->NewNode(&kOp0, value, effect, dead);
  Reduction const r = Reduce(node);
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsDead());
}


// -----------------------------------------------------------------------------
// Branch


TEST_F(DeadCodeEliminationTest, BranchWithDeadControlInput) {
  BranchHint const kHints[] = {BranchHint::kNone, BranchHint::kTrue,
                               BranchHint::kFalse};
  TRACED_FOREACH(BranchHint, hint, kHints) {
    Reduction const r =
        Reduce(graph()->NewNode(common()->Branch(hint), Parameter(0),
                                graph()->NewNode(common()->Dead())));
    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsDead());
  }
}


// -----------------------------------------------------------------------------
// IfTrue


TEST_F(DeadCodeEliminationTest, IfTrueWithDeadInput) {
  Reduction const r = Reduce(
      graph()->NewNode(common()->IfTrue(), graph()->NewNode(common()->Dead())));
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsDead());
}


// -----------------------------------------------------------------------------
// IfFalse


TEST_F(DeadCodeEliminationTest, IfFalseWithDeadInput) {
  Reduction const r = Reduce(graph()->NewNode(
      common()->IfFalse(), graph()->NewNode(common()->Dead())));
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsDead());
}


// -----------------------------------------------------------------------------
// IfSuccess


TEST_F(DeadCodeEliminationTest, IfSuccessWithDeadInput) {
  Reduction const r = Reduce(graph()->NewNode(
      common()->IfSuccess(), graph()->NewNode(common()->Dead())));
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsDead());
}


// -----------------------------------------------------------------------------
// IfException


TEST_F(DeadCodeEliminationTest, IfExceptionWithDeadControlInput) {
  Reduction const r =
      Reduce(graph()->NewNode(common()->IfException(), graph()->start(),
                              graph()->NewNode(common()->Dead())));
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsDead());
}


// -----------------------------------------------------------------------------
// End


TEST_F(DeadCodeEliminationTest, EndWithDeadAndStart) {
  Node* const dead = graph()->NewNode(common()->Dead());
  Node* const start = graph()->start();
  Reduction const r = Reduce(graph()->NewNode(common()->End(2), dead, start));
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsEnd(start));
}


TEST_F(DeadCodeEliminationTest, EndWithOnlyDeadInputs) {
  Node* inputs[kMaxInputs];
  TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
    for (int i = 0; i < input_count; ++i) {
      inputs[i] = graph()->NewNode(common()->Dead());
    }
    Reduction const r = Reduce(
        graph()->NewNode(common()->End(input_count), input_count, inputs));
    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsDead());
  }
}


// -----------------------------------------------------------------------------
// Merge


TEST_F(DeadCodeEliminationTest, MergeWithOnlyDeadInputs) {
  Node* inputs[kMaxInputs + 1];
  TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
    for (int i = 0; i < input_count; ++i) {
      inputs[i] = graph()->NewNode(common()->Dead());
    }
    Reduction const r = Reduce(
        graph()->NewNode(common()->Merge(input_count), input_count, inputs));
    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsDead());
  }
}


TEST_F(DeadCodeEliminationTest, MergeWithOneLiveAndOneDeadInput) {
  Node* const v0 = Parameter(0);
  Node* const v1 = Parameter(1);
  Node* const c0 =
      graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
  Node* const c1 = graph()->NewNode(common()->Dead());
  Node* const e0 = graph()->NewNode(&kOp0, v0, graph()->start(), c0);
  Node* const e1 = graph()->NewNode(&kOp0, v1, graph()->start(), c1);
  Node* const merge = graph()->NewNode(common()->Merge(2), c0, c1);
  Node* const phi = graph()->NewNode(
      common()->Phi(MachineRepresentation::kTagged, 2), v0, v1, merge);
  Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e1, merge);
  StrictMock<MockAdvancedReducerEditor> editor;
  EXPECT_CALL(editor, Replace(phi, v0));
  EXPECT_CALL(editor, Replace(ephi, e0));
  Reduction const r = Reduce(&editor, merge);
  ASSERT_TRUE(r.Changed());
  EXPECT_EQ(c0, r.replacement());
}


TEST_F(DeadCodeEliminationTest, MergeWithTwoLiveAndTwoDeadInputs) {
  Node* const v0 = Parameter(0);
  Node* const v1 = Parameter(1);
  Node* const v2 = Parameter(2);
  Node* const v3 = Parameter(3);
  Node* const c0 =
      graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
  Node* const c1 = graph()->NewNode(common()->Dead());
  Node* const c2 = graph()->NewNode(common()->Dead());
  Node* const c3 = graph()->NewNode(&kOp0, v3, graph()->start(), c0);
  Node* const e0 = graph()->start();
  Node* const e1 = graph()->NewNode(&kOp0, v1, e0, c0);
  Node* const e2 = graph()->NewNode(&kOp0, v2, e1, c0);
  Node* const e3 = graph()->NewNode(&kOp0, v3, graph()->start(), c3);
  Node* const merge = graph()->NewNode(common()->Merge(4), c0, c1, c2, c3);
  Node* const phi = graph()->NewNode(
      common()->Phi(MachineRepresentation::kTagged, 4), v0, v1, v2, v3, merge);
  Node* const ephi =
      graph()->NewNode(common()->EffectPhi(4), e0, e1, e2, e3, merge);
  StrictMock<MockAdvancedReducerEditor> editor;
  EXPECT_CALL(editor, Revisit(phi));
  EXPECT_CALL(editor, Revisit(ephi));
  Reduction const r = Reduce(&editor, merge);
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsMerge(c0, c3));
  EXPECT_THAT(phi,
              IsPhi(MachineRepresentation::kTagged, v0, v3, r.replacement()));
  EXPECT_THAT(ephi, IsEffectPhi(e0, e3, r.replacement()));
}


// -----------------------------------------------------------------------------
// Loop


TEST_F(DeadCodeEliminationTest, LoopWithDeadFirstInput) {
  Node* inputs[kMaxInputs + 1];
  TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
    inputs[0] = graph()->NewNode(common()->Dead());
    for (int i = 1; i < input_count; ++i) {
      inputs[i] = graph()->start();
    }
    Reduction const r = Reduce(
        graph()->NewNode(common()->Loop(input_count), input_count, inputs));
    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsDead());
  }
}


TEST_F(DeadCodeEliminationTest, LoopWithOnlyDeadInputs) {
  Node* inputs[kMaxInputs + 1];
  TRACED_FORRANGE(int, input_count, 1, kMaxInputs - 1) {
    for (int i = 0; i < input_count; ++i) {
      inputs[i] = graph()->NewNode(common()->Dead());
    }
    Reduction const r = Reduce(
        graph()->NewNode(common()->Loop(input_count), input_count, inputs));
    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsDead());
  }
}


TEST_F(DeadCodeEliminationTest, LoopWithOneLiveAndOneDeadInput) {
  Node* const v0 = Parameter(0);
  Node* const v1 = Parameter(1);
  Node* const c0 =
      graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
  Node* const c1 = graph()->NewNode(common()->Dead());
  Node* const e0 = graph()->NewNode(&kOp0, v0, graph()->start(), c0);
  Node* const e1 = graph()->NewNode(&kOp0, v1, graph()->start(), c1);
  Node* const loop = graph()->NewNode(common()->Loop(2), c0, c1);
  Node* const phi = graph()->NewNode(
      common()->Phi(MachineRepresentation::kTagged, 2), v0, v1, loop);
  Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e1, loop);
  Node* const terminate = graph()->NewNode(common()->Terminate(), ephi, loop);
  StrictMock<MockAdvancedReducerEditor> editor;
  EXPECT_CALL(editor, Replace(phi, v0));
  EXPECT_CALL(editor, Replace(ephi, e0));
  EXPECT_CALL(editor, Replace(terminate, IsDead()));
  Reduction const r = Reduce(&editor, loop);
  ASSERT_TRUE(r.Changed());
  EXPECT_EQ(c0, r.replacement());
}


TEST_F(DeadCodeEliminationTest, LoopWithTwoLiveAndTwoDeadInputs) {
  Node* const v0 = Parameter(0);
  Node* const v1 = Parameter(1);
  Node* const v2 = Parameter(2);
  Node* const v3 = Parameter(3);
  Node* const c0 =
      graph()->NewNode(&kOp0, v0, graph()->start(), graph()->start());
  Node* const c1 = graph()->NewNode(common()->Dead());
  Node* const c2 = graph()->NewNode(common()->Dead());
  Node* const c3 = graph()->NewNode(&kOp0, v3, graph()->start(), c0);
  Node* const e0 = graph()->start();
  Node* const e1 = graph()->NewNode(&kOp0, v1, e0, c0);
  Node* const e2 = graph()->NewNode(&kOp0, v2, e1, c0);
  Node* const e3 = graph()->NewNode(&kOp0, v3, graph()->start(), c3);
  Node* const loop = graph()->NewNode(common()->Loop(4), c0, c1, c2, c3);
  Node* const phi = graph()->NewNode(
      common()->Phi(MachineRepresentation::kTagged, 4), v0, v1, v2, v3, loop);
  Node* const ephi =
      graph()->NewNode(common()->EffectPhi(4), e0, e1, e2, e3, loop);
  StrictMock<MockAdvancedReducerEditor> editor;
  EXPECT_CALL(editor, Revisit(phi));
  EXPECT_CALL(editor, Revisit(ephi));
  Reduction const r = Reduce(&editor, loop);
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsLoop(c0, c3));
  EXPECT_THAT(phi,
              IsPhi(MachineRepresentation::kTagged, v0, v3, r.replacement()));
  EXPECT_THAT(ephi, IsEffectPhi(e0, e3, r.replacement()));
}


// -----------------------------------------------------------------------------
// Phi


TEST_F(DeadCodeEliminationTest, PhiWithDeadControlInput) {
  Node* inputs[kMaxInputs + 1];
  TRACED_FOREACH(MachineRepresentation, rep, kMachineRepresentations) {
    TRACED_FORRANGE(int, input_count, 1, kMaxInputs) {
      for (int i = 0; i < input_count; ++i) {
        inputs[i] = Parameter(i);
      }
      inputs[input_count] = graph()->NewNode(common()->Dead());
      Reduction const r = Reduce(graph()->NewNode(
          common()->Phi(rep, input_count), input_count + 1, inputs));
      ASSERT_TRUE(r.Changed());
      EXPECT_THAT(r.replacement(), IsDead());
    }
  }
}


// -----------------------------------------------------------------------------
// EffectPhi


TEST_F(DeadCodeEliminationTest, EffectPhiWithDeadControlInput) {
  Node* inputs[kMaxInputs + 1];
  TRACED_FORRANGE(int, input_count, 1, kMaxInputs) {
    for (int i = 0; i < input_count; ++i) {
      inputs[i] = graph()->start();
    }
    inputs[input_count] = graph()->NewNode(common()->Dead());
    Reduction const r = Reduce(graph()->NewNode(
        common()->EffectPhi(input_count), input_count + 1, inputs));
    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsDead());
  }
}


// -----------------------------------------------------------------------------
// Terminate


TEST_F(DeadCodeEliminationTest, TerminateWithDeadControlInput) {
  Reduction const r =
      Reduce(graph()->NewNode(common()->Terminate(), graph()->start(),
                              graph()->NewNode(common()->Dead())));
  ASSERT_TRUE(r.Changed());
  EXPECT_THAT(r.replacement(), IsDead());
}

}  // namespace dead_code_elimination_unittest
}  // namespace compiler
}  // namespace internal
}  // namespace v8
