// Copyright 2014 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/change-lowering.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-properties-inl.h"
#include "src/compiler/simplified-operator.h"
#include "test/unittests/compiler/compiler-test-utils.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
#include "testing/gmock-support.h"

using testing::_;
using testing::AllOf;
using testing::Capture;
using testing::CaptureEq;

namespace v8 {
namespace internal {
namespace compiler {

class ChangeLoweringTest : public GraphTest {
 public:
  ChangeLoweringTest() : simplified_(zone()) {}
  virtual ~ChangeLoweringTest() {}

  virtual MachineType WordRepresentation() const = 0;

 protected:
  int HeapNumberValueOffset() const {
    STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0);
    return (HeapNumber::kValueOffset / kApiPointerSize) * PointerSize() -
           kHeapObjectTag;
  }
  bool Is32() const { return WordRepresentation() == kRepWord32; }
  int PointerSize() const {
    switch (WordRepresentation()) {
      case kRepWord32:
        return 4;
      case kRepWord64:
        return 8;
      default:
        break;
    }
    UNREACHABLE();
    return 0;
  }
  int SmiMaxValue() const { return -(SmiMinValue() + 1); }
  int SmiMinValue() const {
    return static_cast<int>(0xffffffffu << (SmiValueSize() - 1));
  }
  int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); }
  int SmiShiftSize() const {
    return Is32() ? SmiTagging<4>::SmiShiftSize()
                  : SmiTagging<8>::SmiShiftSize();
  }
  int SmiValueSize() const {
    return Is32() ? SmiTagging<4>::SmiValueSize()
                  : SmiTagging<8>::SmiValueSize();
  }

  Node* Parameter(int32_t index = 0) {
    return graph()->NewNode(common()->Parameter(index), graph()->start());
  }

  Reduction Reduce(Node* node) {
    MachineOperatorBuilder machine(WordRepresentation());
    JSOperatorBuilder javascript(zone());
    JSGraph jsgraph(graph(), common(), &javascript, &machine);
    CompilationInfo info(isolate(), zone());
    Linkage linkage(&info);
    ChangeLowering reducer(&jsgraph, &linkage);
    return reducer.Reduce(node);
  }

  SimplifiedOperatorBuilder* simplified() { return &simplified_; }

  Matcher<Node*> IsAllocateHeapNumber(const Matcher<Node*>& effect_matcher,
                                      const Matcher<Node*>& control_matcher) {
    return IsCall(
        _, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
               CEntryStub(isolate(), 1).GetCode())),
        IsExternalConstant(ExternalReference(
            Runtime::FunctionForId(Runtime::kAllocateHeapNumber), isolate())),
        IsInt32Constant(0), IsNumberConstant(0.0), effect_matcher,
        control_matcher);
  }
  Matcher<Node*> IsLoadHeapNumber(const Matcher<Node*>& value_matcher,
                                  const Matcher<Node*>& control_matcher) {
    return IsLoad(kMachFloat64, value_matcher,
                  IsInt32Constant(HeapNumberValueOffset()), graph()->start(),
                  control_matcher);
  }
  Matcher<Node*> IsWordEqual(const Matcher<Node*>& lhs_matcher,
                             const Matcher<Node*>& rhs_matcher) {
    return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher)
                  : IsWord64Equal(lhs_matcher, rhs_matcher);
  }

 private:
  SimplifiedOperatorBuilder simplified_;
};


// -----------------------------------------------------------------------------
// Common.


class ChangeLoweringCommonTest
    : public ChangeLoweringTest,
      public ::testing::WithParamInterface<MachineType> {
 public:
  virtual ~ChangeLoweringCommonTest() {}

  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
    return GetParam();
  }
};


TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBitToBool) {
  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeBitToBool(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch;
  EXPECT_THAT(phi,
              IsPhi(static_cast<MachineType>(kTypeBool | kRepTagged),
                    IsTrueConstant(), IsFalseConstant(),
                    IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
                                           IsBranch(val, graph()->start()))),
                            IsIfFalse(CaptureEq(&branch)))));
}


TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) {
  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant()));
}


TARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) {
  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeFloat64ToTagged(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* finish = reduction.replacement();
  Capture<Node*> heap_number;
  EXPECT_THAT(
      finish,
      IsFinish(
          AllOf(CaptureEq(&heap_number),
                IsAllocateHeapNumber(IsValueEffect(val), graph()->start())),
          IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
                  CaptureEq(&heap_number),
                  IsInt32Constant(HeapNumberValueOffset()), val,
                  CaptureEq(&heap_number), graph()->start())));
}


TARGET_TEST_P(ChangeLoweringCommonTest, StringAdd) {
  Node* node =
      graph()->NewNode(simplified()->StringAdd(), Parameter(0), Parameter(1));
  Reduction reduction = Reduce(node);
  EXPECT_FALSE(reduction.Changed());
}


INSTANTIATE_TEST_CASE_P(ChangeLoweringTest, ChangeLoweringCommonTest,
                        ::testing::Values(kRepWord32, kRepWord64));


// -----------------------------------------------------------------------------
// 32-bit


class ChangeLowering32Test : public ChangeLoweringTest {
 public:
  virtual ~ChangeLowering32Test() {}
  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
    return kRepWord32;
  }
};


TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> add, branch, heap_number, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(kMachAnyTagged,
            IsFinish(AllOf(CaptureEq(&heap_number),
                           IsAllocateHeapNumber(_, CaptureEq(&if_true))),
                     IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
                             CaptureEq(&heap_number),
                             IsInt32Constant(HeapNumberValueOffset()),
                             IsChangeInt32ToFloat64(val),
                             CaptureEq(&heap_number), CaptureEq(&if_true))),
            IsProjection(
                0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))),
            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
                    IsIfFalse(AllOf(CaptureEq(&branch),
                                    IsBranch(IsProjection(1, CaptureEq(&add)),
                                             graph()->start()))))));
}


TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(
          kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)),
          IsChangeInt32ToFloat64(
              IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))),
          IsMerge(
              AllOf(CaptureEq(&if_true),
                    IsIfTrue(AllOf(
                        CaptureEq(&branch),
                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
                                 graph()->start())))),
              IsIfFalse(CaptureEq(&branch)))));
}


TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(kMachInt32,
            IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
                    IsIfFalse(AllOf(
                        CaptureEq(&branch),
                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
                                 graph()->start()))))));
}


TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToUint32) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(kMachUint32,
            IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
                    IsIfFalse(AllOf(
                        CaptureEq(&branch),
                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
                                 graph()->start()))))));
}


TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, heap_number, if_false;
  EXPECT_THAT(
      phi,
      IsPhi(
          kMachAnyTagged, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())),
          IsFinish(AllOf(CaptureEq(&heap_number),
                         IsAllocateHeapNumber(_, CaptureEq(&if_false))),
                   IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
                           CaptureEq(&heap_number),
                           IsInt32Constant(HeapNumberValueOffset()),
                           IsChangeUint32ToFloat64(val),
                           CaptureEq(&heap_number), CaptureEq(&if_false))),
          IsMerge(
              IsIfTrue(AllOf(CaptureEq(&branch),
                             IsBranch(IsUint32LessThanOrEqual(
                                          val, IsInt32Constant(SmiMaxValue())),
                                      graph()->start()))),
              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
}


// -----------------------------------------------------------------------------
// 64-bit


class ChangeLowering64Test : public ChangeLoweringTest {
 public:
  virtual ~ChangeLowering64Test() {}
  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
    return kRepWord64;
  }
};


TARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) {
  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  EXPECT_THAT(reduction.replacement(),
              IsWord64Shl(IsChangeInt32ToInt64(val),
                          IsInt32Constant(SmiShiftAmount())));
}


TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(
          kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)),
          IsChangeInt32ToFloat64(IsTruncateInt64ToInt32(
              IsWord64Sar(val, IsInt32Constant(SmiShiftAmount())))),
          IsMerge(
              AllOf(CaptureEq(&if_true),
                    IsIfTrue(AllOf(
                        CaptureEq(&branch),
                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
                                 graph()->start())))),
              IsIfFalse(CaptureEq(&branch)))));
}


TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(kMachInt32,
            IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
            IsTruncateInt64ToInt32(
                IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
                    IsIfFalse(AllOf(
                        CaptureEq(&branch),
                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
                                 graph()->start()))))));
}


TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToUint32) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, if_true;
  EXPECT_THAT(
      phi,
      IsPhi(kMachUint32,
            IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
            IsTruncateInt64ToInt32(
                IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
                    IsIfFalse(AllOf(
                        CaptureEq(&branch),
                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
                                 graph()->start()))))));
}


TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagSize == 1);

  Node* val = Parameter(0);
  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
  Reduction reduction = Reduce(node);
  ASSERT_TRUE(reduction.Changed());

  Node* phi = reduction.replacement();
  Capture<Node*> branch, heap_number, if_false;
  EXPECT_THAT(
      phi,
      IsPhi(
          kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(val),
                                      IsInt32Constant(SmiShiftAmount())),
          IsFinish(AllOf(CaptureEq(&heap_number),
                         IsAllocateHeapNumber(_, CaptureEq(&if_false))),
                   IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
                           CaptureEq(&heap_number),
                           IsInt32Constant(HeapNumberValueOffset()),
                           IsChangeUint32ToFloat64(val),
                           CaptureEq(&heap_number), CaptureEq(&if_false))),
          IsMerge(
              IsIfTrue(AllOf(CaptureEq(&branch),
                             IsBranch(IsUint32LessThanOrEqual(
                                          val, IsInt32Constant(SmiMaxValue())),
                                      graph()->start()))),
              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
}

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