summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/compiler')
-rw-r--r--deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc7
-rw-r--r--deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc213
-rw-r--r--deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc94
-rw-r--r--deps/v8/test/unittests/compiler/branch-elimination-unittest.cc204
-rw-r--r--deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc19
-rw-r--r--deps/v8/test/unittests/compiler/change-lowering-unittest.cc72
-rw-r--r--deps/v8/test/unittests/compiler/common-operator-unittest.cc51
-rw-r--r--deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc12
-rw-r--r--deps/v8/test/unittests/compiler/instruction-selector-unittest.cc63
-rw-r--r--deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc14
-rw-r--r--deps/v8/test/unittests/compiler/instruction-sequence-unittest.h8
-rw-r--r--deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc156
-rw-r--r--deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h5
-rw-r--r--deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc47
-rw-r--r--deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc78
-rw-r--r--deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc60
-rw-r--r--deps/v8/test/unittests/compiler/js-operator-unittest.cc3
-rw-r--r--deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc13
-rw-r--r--deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc379
-rw-r--r--deps/v8/test/unittests/compiler/live-range-unittest.cc33
-rw-r--r--deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc3
-rw-r--r--deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc15
-rw-r--r--deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc75
-rw-r--r--deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc89
-rw-r--r--deps/v8/test/unittests/compiler/move-optimizer-unittest.cc73
-rw-r--r--deps/v8/test/unittests/compiler/node-matchers-unittest.cc3
-rw-r--r--deps/v8/test/unittests/compiler/node-test-utils.cc46
-rw-r--r--deps/v8/test/unittests/compiler/node-test-utils.h15
-rw-r--r--deps/v8/test/unittests/compiler/register-allocator-unittest.cc9
-rw-r--r--deps/v8/test/unittests/compiler/scheduler-unittest.cc6
-rw-r--r--deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc3
-rw-r--r--deps/v8/test/unittests/compiler/simplified-operator-unittest.cc6
-rw-r--r--deps/v8/test/unittests/compiler/state-values-utils-unittest.cc6
-rw-r--r--deps/v8/test/unittests/compiler/typer-unittest.cc10
-rw-r--r--deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc3
35 files changed, 1456 insertions, 437 deletions
diff --git a/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
index 941fa26e00..bfae2ba4d0 100644
--- a/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
+++ b/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
@@ -1320,7 +1320,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+ m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -1335,8 +1336,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
diff --git a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
index 154645c1fb..3af1232cff 100644
--- a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
@@ -583,7 +583,6 @@ TEST_F(InstructionSelectorTest, AddImmediateOnLeft) {
TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
- // Subtraction with zero on the left maps to Neg.
{
// 32-bit subtract.
StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
@@ -591,8 +590,10 @@ TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode());
- EXPECT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
+ EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
EXPECT_EQ(1U, s[0]->OutputCount());
}
{
@@ -602,13 +603,71 @@ TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kArm64Neg, s[0]->arch_opcode());
- EXPECT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
+ EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0)));
EXPECT_EQ(1U, s[0]->OutputCount());
}
}
+TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) {
+ TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+ {
+ // Test 32-bit operations. Ignore ROR shifts, as subtract does not
+ // support them.
+ if ((shift.mi.machine_type != kMachInt32) ||
+ (shift.mi.arch_opcode == kArm64Ror32) ||
+ (shift.mi.arch_opcode == kArm64Ror))
+ continue;
+
+ TRACED_FORRANGE(int, imm, -32, 63) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ m.Return(m.Int32Sub(
+ m.Int32Constant(0),
+ (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm))));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
+ EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ }
+ {
+ // Test 64-bit operations. Ignore ROR shifts, as subtract does not
+ // support them.
+ if ((shift.mi.machine_type != kMachInt64) ||
+ (shift.mi.arch_opcode == kArm64Ror32) ||
+ (shift.mi.arch_opcode == kArm64Ror))
+ continue;
+
+ TRACED_FORRANGE(int, imm, -32, 127) {
+ StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+ m.Return(m.Int64Sub(
+ m.Int64Constant(0),
+ (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm))));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
+ EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ }
+ }
+}
+
+
TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) {
{
// 32-bit add.
@@ -2097,7 +2156,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+ m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -2112,8 +2172,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -2473,6 +2533,71 @@ TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) {
}
}
+namespace {
+
+struct IntegerCmp {
+ MachInst2 mi;
+ FlagsCondition cond;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const IntegerCmp& cmp) {
+ return os << cmp.mi;
+}
+
+
+// ARM64 32-bit integer comparison instructions.
+const IntegerCmp kIntegerCmpInstructions[] = {
+ {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32,
+ kMachInt32},
+ kEqual},
+ {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32,
+ kMachInt32},
+ kSignedLessThan},
+ {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
+ kArm64Cmp32, kMachInt32},
+ kSignedLessThanOrEqual},
+ {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32,
+ kMachUint32},
+ kUnsignedLessThan},
+ {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
+ kArm64Cmp32, kMachUint32},
+ kUnsignedLessThanOrEqual}};
+
+} // namespace
+
+
+TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) {
+ TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
+ TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+ // Test 32-bit operations. Ignore ROR shifts, as compare-negate does not
+ // support them.
+ if (shift.mi.machine_type != kMachInt32 ||
+ shift.mi.arch_opcode == kArm64Ror32) {
+ continue;
+ }
+
+ TRACED_FORRANGE(int32_t, imm, -32, 63) {
+ StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm));
+ m.Return(
+ (m.*cmp.mi.constructor)(p0, m.Int32Sub(m.Int32Constant(0), r)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+ }
+ }
+ }
+}
+
// -----------------------------------------------------------------------------
// Miscellaneous
@@ -3054,6 +3179,78 @@ TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
}
+
+TEST_F(InstructionSelectorTest, Float32Max) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float32Max(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float32Max is `(b < a) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Float32Max, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float32Min) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float32Min(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float32Min is `(a < b) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Float32Min, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Max) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float64Max(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float64Max is `(b < a) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Float64Max, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Min) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float64Min(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float64Min is `(a < b) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Float64Min, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc
new file mode 100644
index 0000000000..5d223446e2
--- /dev/null
+++ b/deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc
@@ -0,0 +1,94 @@
+// 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/binary-operator-reducer.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/machine-type.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/types-inl.h"
+#include "test/unittests/compiler/graph-reducer-unittest.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+
+using testing::StrictMock;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class BinaryOperatorReducerTest : public TypedGraphTest {
+ public:
+ explicit BinaryOperatorReducerTest(int num_parameters = 1)
+ : TypedGraphTest(num_parameters), machine_(zone()), simplified_(zone()) {}
+ ~BinaryOperatorReducerTest() override {}
+
+ protected:
+ Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) {
+ BinaryOperatorReducer reducer(editor, graph(), common(), machine());
+ return reducer.Reduce(node);
+ }
+
+ Reduction Reduce(Node* node) {
+ StrictMock<MockAdvancedReducerEditor> editor;
+ return Reduce(&editor, node);
+ }
+
+ MachineOperatorBuilder* machine() { return &machine_; }
+ SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+
+ private:
+ MachineOperatorBuilder machine_;
+ SimplifiedOperatorBuilder simplified_;
+};
+
+
+TEST_F(BinaryOperatorReducerTest, Div52OfMul52) {
+ // This reduction applies only to 64bit arch
+ if (!machine()->Is64()) return;
+
+ Node* p0 = Parameter(0);
+ Node* p1 = Parameter(1);
+ Node* t0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), p0);
+ Node* t1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), p1);
+
+ Type* mul_range = Type::Range(0x0, 0xFFFFFFFFFFFFFULL, graph()->zone());
+ Node* mul = graph()->NewNode(machine()->Float64Mul(), t0, t1);
+ NodeProperties::SetType(
+ mul, Type::Intersect(mul_range, Type::Number(), graph()->zone()));
+
+ Node* mul_replacement;
+ auto mul_matcher = IsInt64Mul(p0, p1);
+ {
+ StrictMock<MockAdvancedReducerEditor> editor;
+
+ EXPECT_CALL(editor, Revisit(mul_matcher));
+
+ Reduction r = Reduce(&editor, mul);
+ ASSERT_TRUE(r.Changed());
+ mul_replacement = r.replacement();
+ EXPECT_THAT(mul_replacement, IsRoundInt64ToFloat64(mul_matcher));
+ }
+
+ {
+ StrictMock<MockAdvancedReducerEditor> editor;
+
+ Node* power = Float64Constant(0x4000000);
+ Node* div =
+ graph()->NewNode(machine()->Float64Div(), mul_replacement, power);
+
+ auto shr_matcher = IsWord64Shr(mul_matcher, IsInt64Constant(26));
+ EXPECT_CALL(editor, Revisit(shr_matcher));
+
+ Reduction r = Reduce(&editor, div);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsRoundInt64ToFloat64(shr_matcher));
+ }
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/branch-elimination-unittest.cc b/deps/v8/test/unittests/compiler/branch-elimination-unittest.cc
new file mode 100644
index 0000000000..efa490d7ec
--- /dev/null
+++ b/deps/v8/test/unittests/compiler/branch-elimination-unittest.cc
@@ -0,0 +1,204 @@
+// 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/branch-elimination.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-properties.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"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class BranchEliminationTest : public TypedGraphTest {
+ public:
+ BranchEliminationTest()
+ : machine_(zone(), kMachPtr, MachineOperatorBuilder::kNoFlags) {}
+
+ MachineOperatorBuilder* machine() { return &machine_; }
+
+ void Reduce() {
+ JSOperatorBuilder javascript(zone());
+ JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
+ machine());
+ GraphReducer graph_reducer(zone(), graph(), jsgraph.Dead());
+ BranchElimination branch_condition_elimination(&graph_reducer, &jsgraph,
+ zone());
+ graph_reducer.AddReducer(&branch_condition_elimination);
+ graph_reducer.ReduceGraph();
+ }
+
+ private:
+ MachineOperatorBuilder machine_;
+};
+
+
+TEST_F(BranchEliminationTest, NestedBranchSameTrue) {
+ // { return (x ? (x ? 1 : 2) : 3; }
+ // should be reduced to
+ // { return (x ? 1 : 3; }
+ Node* condition = Parameter(0);
+ Node* outer_branch =
+ graph()->NewNode(common()->Branch(), condition, graph()->start());
+
+ Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch);
+ Node* inner_branch =
+ graph()->NewNode(common()->Branch(), condition, outer_if_true);
+ Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch);
+ Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch);
+ Node* inner_merge =
+ graph()->NewNode(common()->Merge(2), inner_if_true, inner_if_false);
+ Node* inner_phi =
+ graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(1),
+ Int32Constant(2), inner_merge);
+
+ Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch);
+ Node* outer_merge =
+ graph()->NewNode(common()->Merge(2), inner_merge, outer_if_false);
+ Node* outer_phi = graph()->NewNode(common()->Phi(kMachInt32, 2), inner_phi,
+ Int32Constant(3), outer_merge);
+
+ Node* ret = graph()->NewNode(common()->Return(), outer_phi, graph()->start(),
+ outer_merge);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduce();
+
+ // Outer branch should not be rewritten, the inner branch should be discarded.
+ EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start()));
+ EXPECT_THAT(inner_phi,
+ IsPhi(kMachInt32, IsInt32Constant(1), IsInt32Constant(2),
+ IsMerge(outer_if_true, IsDead())));
+}
+
+
+TEST_F(BranchEliminationTest, NestedBranchSameFalse) {
+ // { return (x ? 1 : (x ? 2 : 3); }
+ // should be reduced to
+ // { return (x ? 1 : 3; }
+ Node* condition = Parameter(0);
+ Node* outer_branch =
+ graph()->NewNode(common()->Branch(), condition, graph()->start());
+
+ Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch);
+
+ Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch);
+ Node* inner_branch =
+ graph()->NewNode(common()->Branch(), condition, outer_if_false);
+ Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch);
+ Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch);
+ Node* inner_merge =
+ graph()->NewNode(common()->Merge(2), inner_if_true, inner_if_false);
+ Node* inner_phi =
+ graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(2),
+ Int32Constant(3), inner_merge);
+
+ Node* outer_merge =
+ graph()->NewNode(common()->Merge(2), outer_if_true, inner_merge);
+ Node* outer_phi = graph()->NewNode(common()->Phi(kMachInt32, 2),
+ Int32Constant(1), inner_phi, outer_merge);
+
+ Node* ret = graph()->NewNode(common()->Return(), outer_phi, graph()->start(),
+ outer_merge);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduce();
+
+ // Outer branch should not be rewritten, the inner branch should be discarded.
+ EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start()));
+ EXPECT_THAT(inner_phi,
+ IsPhi(kMachInt32, IsInt32Constant(2), IsInt32Constant(3),
+ IsMerge(IsDead(), outer_if_false)));
+}
+
+
+TEST_F(BranchEliminationTest, BranchAfterDiamond) {
+ // { var y = x ? 1 : 2; return y + x ? 3 : 4; }
+ // should not be reduced.
+ Node* condition = Parameter(0);
+
+ Node* branch1 =
+ graph()->NewNode(common()->Branch(), condition, graph()->start());
+ Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+ Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+ Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+ Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(1),
+ Int32Constant(2), merge1);
+
+ Node* branch2 = graph()->NewNode(common()->Branch(), condition, merge1);
+ Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
+ Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
+ Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
+ Node* phi2 = graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(3),
+ Int32Constant(4), merge1);
+
+
+ Node* add = graph()->NewNode(machine()->Int32Add(), phi1, phi2);
+ Node* ret =
+ graph()->NewNode(common()->Return(), add, graph()->start(), merge2);
+ graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
+
+ Reduce();
+
+ // Outer branch should not be rewritten, the inner branch condition should
+ // be true.
+ EXPECT_THAT(branch1, IsBranch(condition, graph()->start()));
+ EXPECT_THAT(branch2, IsBranch(condition, merge1));
+}
+
+
+TEST_F(BranchEliminationTest, BranchInsideLoopSame) {
+ // if (x) while (x) { return 2; } else { return 1; }
+ // should be rewritten to
+ // if (x) while (true) { return 2; } else { return 1; }
+
+ Node* condition = Parameter(0);
+
+ Node* outer_branch =
+ graph()->NewNode(common()->Branch(), condition, graph()->start());
+ Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch);
+
+
+ Node* loop = graph()->NewNode(common()->Loop(1), outer_if_true);
+ Node* effect =
+ graph()->NewNode(common()->EffectPhi(1), graph()->start(), loop);
+
+ Node* inner_branch = graph()->NewNode(common()->Branch(), condition, loop);
+
+ Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch);
+ Node* ret1 = graph()->NewNode(common()->Return(), Int32Constant(2), effect,
+ inner_if_true);
+
+ Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch);
+ loop->AppendInput(zone(), inner_if_false);
+ NodeProperties::ChangeOp(loop, common()->Loop(2));
+ effect->InsertInput(zone(), 1, effect);
+ NodeProperties::ChangeOp(effect, common()->EffectPhi(2));
+
+ Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch);
+ Node* outer_merge =
+ graph()->NewNode(common()->Merge(2), loop, outer_if_false);
+ Node* outer_ephi = graph()->NewNode(common()->EffectPhi(2), effect,
+ graph()->start(), outer_merge);
+
+ Node* ret2 = graph()->NewNode(common()->Return(), Int32Constant(1),
+ outer_ephi, outer_merge);
+
+ Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop);
+ graph()->SetEnd(graph()->NewNode(common()->End(3), ret1, ret2, terminate));
+
+ Reduce();
+
+ // Outer branch should not be rewritten, the inner branch should be discarded.
+ EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start()));
+ EXPECT_THAT(ret1, IsReturn(IsInt32Constant(2), effect, loop));
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc b/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc
index 22b9b893e8..27ff4ca359 100644
--- a/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc
+++ b/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc
@@ -51,8 +51,8 @@ Graph* BytecodeGraphBuilderTest::GetCompletedGraph() {
CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone());
JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone());
Graph* graph = new (zone()) Graph(zone());
- JSGraph* jsgraph =
- new (zone()) JSGraph(isolate(), graph, common, javascript, machine);
+ JSGraph* jsgraph = new (zone())
+ JSGraph(isolate(), graph, common, javascript, nullptr, machine);
Handle<String> name = factory()->NewStringFromStaticChars("test");
Handle<String> script = factory()->NewStringFromStaticChars("test() {}");
@@ -98,6 +98,7 @@ Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() {
TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) {
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadUndefined().Return();
@@ -113,6 +114,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) {
TEST_F(BytecodeGraphBuilderTest, ReturnNull) {
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadNull().Return();
@@ -126,6 +128,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnNull) {
TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) {
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadTheHole().Return();
@@ -141,6 +144,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) {
TEST_F(BytecodeGraphBuilderTest, ReturnTrue) {
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadTrue().Return();
@@ -156,6 +160,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnTrue) {
TEST_F(BytecodeGraphBuilderTest, ReturnFalse) {
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadFalse().Return();
@@ -172,6 +177,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnFalse) {
TEST_F(BytecodeGraphBuilderTest, ReturnInt8) {
static const int kValue = 3;
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadLiteral(Smi::FromInt(kValue)).Return();
@@ -188,6 +194,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnInt8) {
TEST_F(BytecodeGraphBuilderTest, ReturnDouble) {
const double kValue = 0.123456789;
array_builder()->set_locals_count(0);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()->LoadLiteral(factory()->NewHeapNumber(kValue));
array_builder()->Return();
@@ -204,10 +211,12 @@ TEST_F(BytecodeGraphBuilderTest, ReturnDouble) {
TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) {
array_builder()->set_locals_count(1);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(3);
array_builder()
->LoadAccumulatorWithRegister(array_builder()->Parameter(1))
- .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2))
+ .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2),
+ Strength::WEAK)
.StoreAccumulatorInRegister(interpreter::Register(0))
.Return();
@@ -226,12 +235,14 @@ TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) {
static const int kLeft = -655371;
static const int kRight = +2000000;
array_builder()->set_locals_count(1);
+ array_builder()->set_context_count(0);
array_builder()->set_parameter_count(1);
array_builder()
->LoadLiteral(Smi::FromInt(kLeft))
.StoreAccumulatorInRegister(interpreter::Register(0))
.LoadLiteral(Smi::FromInt(kRight))
- .BinaryOperation(Token::Value::ADD, interpreter::Register(0))
+ .BinaryOperation(Token::Value::ADD, interpreter::Register(0),
+ Strength::WEAK)
.Return();
Graph* graph = GetCompletedGraph();
diff --git a/deps/v8/test/unittests/compiler/change-lowering-unittest.cc b/deps/v8/test/unittests/compiler/change-lowering-unittest.cc
index fd2d7c4dae..aec568c9db 100644
--- a/deps/v8/test/unittests/compiler/change-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/change-lowering-unittest.cc
@@ -36,7 +36,8 @@ class ChangeLoweringTest : public TypedGraphTest {
Reduction Reduce(Node* node) {
MachineOperatorBuilder machine(zone(), WordRepresentation());
JSOperatorBuilder javascript(zone());
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
+ &machine);
ChangeLowering reducer(&jsgraph);
return reducer.Reduce(node);
}
@@ -120,24 +121,6 @@ TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) {
}
-TARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) {
- Node* value = Parameter(Type::Number());
- Reduction r =
- Reduce(graph()->NewNode(simplified()->ChangeFloat64ToTagged(), value));
- ASSERT_TRUE(r.Changed());
- Capture<Node*> heap_number;
- EXPECT_THAT(
- r.replacement(),
- IsFinish(
- AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(IsValueEffect(value), graph()->start())),
- IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
- CaptureEq(&heap_number),
- IsIntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag),
- value, CaptureEq(&heap_number), graph()->start())));
-}
-
-
TARGET_TEST_P(ChangeLoweringCommonTest, ChangeInt32ToTaggedWithSignedSmall) {
Node* value = Parameter(Type::SignedSmall());
Reduction r =
@@ -218,14 +201,15 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
EXPECT_THAT(
r.replacement(),
IsPhi(kMachAnyTagged,
- IsFinish(AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(_, CaptureEq(&if_true))),
- IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
- CaptureEq(&heap_number),
- IsIntPtrConstant(HeapNumber::kValueOffset -
- kHeapObjectTag),
- IsChangeInt32ToFloat64(value),
- CaptureEq(&heap_number), CaptureEq(&if_true))),
+ IsFinishRegion(
+ AllOf(CaptureEq(&heap_number),
+ IsAllocateHeapNumber(_, CaptureEq(&if_true))),
+ IsStore(
+ StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+ CaptureEq(&heap_number),
+ IsIntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag),
+ IsChangeInt32ToFloat64(value), CaptureEq(&heap_number),
+ CaptureEq(&if_true))),
IsProjection(0, AllOf(CaptureEq(&add),
IsInt32AddWithOverflow(value, value))),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
@@ -319,14 +303,15 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
IsPhi(
kMachAnyTagged,
IsWord32Shl(value, IsInt32Constant(kSmiTagSize + kSmiShiftSize)),
- IsFinish(AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(_, CaptureEq(&if_false))),
- IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
- CaptureEq(&heap_number),
- IsInt32Constant(HeapNumber::kValueOffset -
- kHeapObjectTag),
- IsChangeUint32ToFloat64(value),
- CaptureEq(&heap_number), CaptureEq(&if_false))),
+ IsFinishRegion(
+ AllOf(CaptureEq(&heap_number),
+ IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+ IsStore(
+ StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+ CaptureEq(&heap_number),
+ IsInt32Constant(HeapNumber::kValueOffset - kHeapObjectTag),
+ IsChangeUint32ToFloat64(value), CaptureEq(&heap_number),
+ CaptureEq(&if_false))),
IsMerge(IsIfTrue(AllOf(
CaptureEq(&branch),
IsBranch(IsUint32LessThanOrEqual(
@@ -443,14 +428,15 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
kMachAnyTagged,
IsWord64Shl(IsChangeUint32ToUint64(value),
IsInt64Constant(kSmiTagSize + kSmiShiftSize)),
- IsFinish(AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(_, CaptureEq(&if_false))),
- IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
- CaptureEq(&heap_number),
- IsInt64Constant(HeapNumber::kValueOffset -
- kHeapObjectTag),
- IsChangeUint32ToFloat64(value),
- CaptureEq(&heap_number), CaptureEq(&if_false))),
+ IsFinishRegion(
+ AllOf(CaptureEq(&heap_number),
+ IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+ IsStore(
+ StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+ CaptureEq(&heap_number),
+ IsInt64Constant(HeapNumber::kValueOffset - kHeapObjectTag),
+ IsChangeUint32ToFloat64(value), CaptureEq(&heap_number),
+ CaptureEq(&if_false))),
IsMerge(IsIfTrue(AllOf(
CaptureEq(&branch),
IsBranch(IsUint32LessThanOrEqual(
diff --git a/deps/v8/test/unittests/compiler/common-operator-unittest.cc b/deps/v8/test/unittests/compiler/common-operator-unittest.cc
index 66eb140d27..64c5f73d27 100644
--- a/deps/v8/test/unittests/compiler/common-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/common-operator-unittest.cc
@@ -53,7 +53,6 @@ const SharedOperator kSharedOperators[] = {
SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1),
- SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1),
SHARED(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)
#undef SHARED
};
@@ -188,6 +187,22 @@ TEST_F(CommonOperatorTest, End) {
}
+TEST_F(CommonOperatorTest, Return) {
+ TRACED_FOREACH(int, input_count, kArguments) {
+ const Operator* const op = common()->Return(input_count);
+ EXPECT_EQ(IrOpcode::kReturn, op->opcode());
+ EXPECT_EQ(Operator::kNoThrow, op->properties());
+ EXPECT_EQ(input_count, op->ValueInputCount());
+ EXPECT_EQ(1, op->EffectInputCount());
+ EXPECT_EQ(1, op->ControlInputCount());
+ EXPECT_EQ(2 + input_count, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, op->ValueOutputCount());
+ EXPECT_EQ(0, op->EffectOutputCount());
+ EXPECT_EQ(1, op->ControlOutputCount());
+ }
+}
+
+
TEST_F(CommonOperatorTest, Branch) {
TRACED_FOREACH(BranchHint, hint, kBranchHints) {
const Operator* const op = common()->Branch(hint);
@@ -343,28 +358,24 @@ TEST_F(CommonOperatorTest, NumberConstant) {
}
-TEST_F(CommonOperatorTest, ValueEffect) {
- TRACED_FOREACH(int, arguments, kArguments) {
- const Operator* op = common()->ValueEffect(arguments);
- EXPECT_EQ(arguments, op->ValueInputCount());
- EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
- EXPECT_EQ(0, op->ControlOutputCount());
- EXPECT_EQ(1, op->EffectOutputCount());
- EXPECT_EQ(0, op->ValueOutputCount());
- }
+TEST_F(CommonOperatorTest, BeginRegion) {
+ const Operator* op = common()->BeginRegion();
+ EXPECT_EQ(1, op->EffectInputCount());
+ EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, op->ControlOutputCount());
+ EXPECT_EQ(1, op->EffectOutputCount());
+ EXPECT_EQ(0, op->ValueOutputCount());
}
-TEST_F(CommonOperatorTest, Finish) {
- TRACED_FOREACH(int, arguments, kArguments) {
- const Operator* op = common()->Finish(arguments);
- EXPECT_EQ(1, op->ValueInputCount());
- EXPECT_EQ(arguments, op->EffectInputCount());
- EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
- EXPECT_EQ(0, op->ControlOutputCount());
- EXPECT_EQ(0, op->EffectOutputCount());
- EXPECT_EQ(1, op->ValueOutputCount());
- }
+TEST_F(CommonOperatorTest, FinishRegion) {
+ const Operator* op = common()->FinishRegion();
+ EXPECT_EQ(1, op->ValueInputCount());
+ EXPECT_EQ(1, op->EffectInputCount());
+ EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, op->ControlOutputCount());
+ EXPECT_EQ(1, op->EffectOutputCount());
+ EXPECT_EQ(1, op->ValueOutputCount());
}
} // namespace compiler
diff --git a/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc b/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc
index 4c8e0c0431..1e07d7a41b 100644
--- a/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc
+++ b/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc
@@ -249,7 +249,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+ m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -263,7 +264,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, base, kImmediates) {
StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1));
+ m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -284,8 +286,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
const MemoryAccess memacc = GetParam();
TRACED_FOREACH(int32_t, index, kImmediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -319,7 +321,7 @@ class AddressingModeUnitTest : public InstructionSelectorTest {
void Run(Node* base, Node* load_index, Node* store_index,
AddressingMode mode) {
Node* load = m->Load(kMachInt32, base, load_index);
- m->Store(kMachInt32, base, store_index, load);
+ m->Store(kMachInt32, base, store_index, load, kNoWriteBarrier);
m->Return(m->Int32Constant(0));
Stream s = m->Build();
ASSERT_EQ(2U, s.size());
diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc
index e14382e914..8b182a76ba 100644
--- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc
+++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc
@@ -4,6 +4,7 @@
#include "test/unittests/compiler/instruction-selector-unittest.h"
+#include "src/code-factory.h"
#include "src/compiler/graph.h"
#include "src/compiler/schedule.h"
#include "src/flags.h"
@@ -51,7 +52,8 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
if (FLAG_trace_turbo) {
OFStream out(stdout);
PrintableInstructionSequence printable = {
- RegisterConfiguration::ArchDefault(), &sequence};
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
+ &sequence};
out << "=== Code sequence after instruction selection ===" << std::endl
<< printable;
}
@@ -127,8 +129,7 @@ bool InstructionSelectorTest::Stream::IsFixed(const InstructionOperand* operand,
if (!operand->IsUnallocated()) return false;
const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
if (!unallocated->HasFixedRegisterPolicy()) return false;
- const int index = Register::ToAllocationIndex(reg);
- return unallocated->fixed_register_index() == index;
+ return unallocated->fixed_register_index() == reg.code();
}
@@ -242,13 +243,14 @@ TARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) {
// -----------------------------------------------------------------------------
-// Finish.
+// FinishRegion.
-TARGET_TEST_F(InstructionSelectorTest, Finish) {
+TARGET_TEST_F(InstructionSelectorTest, FinishRegion) {
StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
Node* param = m.Parameter(0);
- Node* finish = m.AddNode(m.common()->Finish(1), param, m.graph()->start());
+ Node* finish =
+ m.AddNode(m.common()->FinishRegion(), param, m.graph()->start());
m.Return(finish);
Stream s = m.Build(kAllInstructions);
ASSERT_EQ(4U, s.size());
@@ -334,8 +336,9 @@ TARGET_TEST_F(InstructionSelectorTest, ValueEffect) {
Stream s1 = m1.Build(kAllInstructions);
StreamBuilder m2(this, kMachInt32, kMachPtr);
Node* p2 = m2.Parameter(0);
- m2.Return(m2.AddNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0),
- m2.AddNode(m2.common()->ValueEffect(1), p2)));
+ m2.Return(
+ m2.AddNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0),
+ m2.AddNode(m2.common()->BeginRegion(), m2.graph()->start())));
Stream s2 = m2.Build(kAllInstructions);
EXPECT_LE(3U, s1.size());
ASSERT_EQ(s1.size(), s2.size());
@@ -369,18 +372,20 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(
zone(), false, 1, CallDescriptor::kNeedsFrameState);
+ // Build frame state for the state before the call.
Node* parameters =
m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(1));
Node* locals = m.AddNode(m.common()->TypedStateValues(&empty_types));
Node* stack = m.AddNode(m.common()->TypedStateValues(&empty_types));
- Node* context_dummy = m.Int32Constant(0);
-
+ Node* context_sentinel = m.Int32Constant(0);
Node* state_node = m.AddNode(
m.common()->FrameState(bailout_id, OutputFrameStateCombine::Push(),
m.GetFrameStateFunctionInfo(1, 0)),
- parameters, locals, stack, context_dummy, function_node,
+ parameters, locals, stack, context_sentinel, function_node,
m.UndefinedConstant());
- Node* args[] = {receiver, context};
+
+ // Build the call.
+ Node* args[] = {receiver, m.Int32Constant(1), context};
Node* call =
m.CallNWithFrameState(descriptor, function_node, args, state_node);
m.Return(call);
@@ -402,7 +407,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
}
-TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
+TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeopt) {
StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
kMachAnyTagged);
@@ -417,6 +422,11 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
ZoneVector<MachineType> float64_type(1, kMachFloat64, zone());
ZoneVector<MachineType> tagged_type(1, kMachAnyTagged, zone());
+ Callable callable = CodeFactory::ToObject(isolate());
+ CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), 1,
+ CallDescriptor::kNeedsFrameState, Operator::kNoProperties);
+
// Build frame state for the state before the call.
Node* parameters =
m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43));
@@ -424,18 +434,17 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
m.Float64Constant(0.5));
Node* stack = m.AddNode(m.common()->TypedStateValues(&tagged_type),
m.UndefinedConstant());
-
Node* context_sentinel = m.Int32Constant(0);
- Node* frame_state_before = m.AddNode(
+ Node* state_node = m.AddNode(
m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(),
m.GetFrameStateFunctionInfo(1, 1)),
parameters, locals, stack, context_sentinel, function_node,
m.UndefinedConstant());
// Build the call.
- Node* call = m.CallFunctionStub0(function_node, receiver, context,
- frame_state_before, CALL_AS_METHOD);
-
+ Node* args[] = {function_node, receiver, context};
+ Node* stub_code = m.HeapConstant(callable.code());
+ Node* call = m.CallNWithFrameState(descriptor, stub_code, args, state_node);
m.Return(call);
Stream s = m.Build(kAllExceptNopInstructions);
@@ -496,8 +505,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
}
-TARGET_TEST_F(InstructionSelectorTest,
- CallFunctionStubDeoptRecursiveFrameState) {
+TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) {
StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
kMachAnyTagged);
@@ -508,11 +516,17 @@ TARGET_TEST_F(InstructionSelectorTest,
Node* function_node = m.Parameter(0);
Node* receiver = m.Parameter(1);
Node* context = m.Int32Constant(66);
+ Node* context2 = m.Int32Constant(46);
ZoneVector<MachineType> int32_type(1, kMachInt32, zone());
ZoneVector<MachineType> int32x2_type(2, kMachInt32, zone());
ZoneVector<MachineType> float64_type(1, kMachFloat64, zone());
+ Callable callable = CodeFactory::ToObject(isolate());
+ CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), 1,
+ CallDescriptor::kNeedsFrameState, Operator::kNoProperties);
+
// Build frame state for the state before the call.
Node* parameters =
m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(63));
@@ -526,23 +540,22 @@ TARGET_TEST_F(InstructionSelectorTest,
m.GetFrameStateFunctionInfo(1, 1)),
parameters, locals, stack, context, function_node, m.UndefinedConstant());
- Node* context2 = m.Int32Constant(46);
Node* parameters2 =
m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43));
Node* locals2 = m.AddNode(m.common()->TypedStateValues(&float64_type),
m.Float64Constant(0.25));
Node* stack2 = m.AddNode(m.common()->TypedStateValues(&int32x2_type),
m.Int32Constant(44), m.Int32Constant(45));
- Node* frame_state_before = m.AddNode(
+ Node* state_node = m.AddNode(
m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(),
m.GetFrameStateFunctionInfo(1, 1)),
parameters2, locals2, stack2, context2, function_node,
frame_state_parent);
// Build the call.
- Node* call = m.CallFunctionStub0(function_node, receiver, context2,
- frame_state_before, CALL_AS_METHOD);
-
+ Node* args[] = {function_node, receiver, context2};
+ Node* stub_code = m.HeapConstant(callable.code());
+ Node* call = m.CallNWithFrameState(descriptor, stub_code, args, state_node);
m.Return(call);
Stream s = m.Build(kAllExceptNopInstructions);
diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc
index 65a7f299c5..51112a6470 100644
--- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc
+++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc
@@ -20,6 +20,14 @@ static char register_names_[10 * (RegisterConfiguration::kMaxGeneralRegisters +
RegisterConfiguration::kMaxDoubleRegisters)];
+namespace {
+static int allocatable_codes[InstructionSequenceTest::kDefaultNRegs] = {
+ 0, 1, 2, 3, 4, 5, 6, 7};
+static int allocatable_double_codes[InstructionSequenceTest::kDefaultNRegs] = {
+ 0, 1, 2, 3, 4, 5, 6, 7};
+}
+
+
static void InitializeRegisterNames() {
char* loc = register_names_;
for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) {
@@ -59,8 +67,10 @@ void InstructionSequenceTest::SetNumRegs(int num_general_registers,
RegisterConfiguration* InstructionSequenceTest::config() {
if (config_.is_empty()) {
config_.Reset(new RegisterConfiguration(
- num_general_registers_, num_double_registers_, num_double_registers_,
- general_register_names_, double_register_names_));
+ num_general_registers_, num_double_registers_, num_general_registers_,
+ num_double_registers_, num_double_registers_, allocatable_codes,
+ allocatable_double_codes, general_register_names_,
+ double_register_names_));
}
return config_.get();
}
diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h
index 54317ede21..eb86bd9174 100644
--- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h
+++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h
@@ -15,7 +15,7 @@ namespace compiler {
class InstructionSequenceTest : public TestWithIsolateAndZone {
public:
- static const int kDefaultNRegs = 4;
+ static const int kDefaultNRegs = 8;
static const int kNoValue = kMinInt;
typedef RpoNumber Rpo;
@@ -36,6 +36,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
kFixedRegister,
kSlot,
kFixedSlot,
+ kExplicit,
kImmediate,
kNone,
kConstant,
@@ -57,6 +58,11 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
static TestOperand Same() { return TestOperand(kSameAsFirst, VReg()); }
+ static TestOperand ExplicitReg(int index) {
+ TestOperandType type = kExplicit;
+ return TestOperand(type, VReg(), index);
+ }
+
static TestOperand Reg(VReg vreg, int index = kNoValue) {
TestOperandType type = kRegister;
if (index != kNoValue) type = kFixedRegister;
diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc
index 48aa8f1ec4..a7712880f7 100644
--- a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc
+++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc
@@ -59,6 +59,13 @@ Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
}
+Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher) {
+ return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher)
+ : IsWord32Or(lhs_matcher, rhs_matcher);
+}
+
+
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad(
const Matcher<LoadRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) {
@@ -87,20 +94,20 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsCall(
Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand(
- int operand) {
+ int offset) {
return IsLoad(
kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
- IsInt32Constant(1 + operand)));
+ IsInt32Constant(offset)));
}
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
- IsBytecodeOperandSignExtended(int operand) {
+ IsBytecodeOperandSignExtended(int offset) {
Matcher<Node*> load_matcher = IsLoad(
kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
- IsInt32Constant(1 + operand)));
+ IsInt32Constant(offset)));
if (kPointerSize == 8) {
load_matcher = IsChangeInt32ToInt64(load_matcher);
}
@@ -108,6 +115,36 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
}
+Matcher<Node*>
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort(
+ int offset) {
+ if (TargetSupportsUnalignedAccess()) {
+ return IsLoad(
+ kMachUint16, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
+ IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
+ IsInt32Constant(offset)));
+ } else {
+ Matcher<Node*> first_byte = IsLoad(
+ kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
+ IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
+ IsInt32Constant(offset)));
+ Matcher<Node*> second_byte = IsLoad(
+ kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
+ IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
+ IsInt32Constant(offset + 1)));
+#if V8_TARGET_LITTLE_ENDIAN
+ return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)),
+ first_byte);
+#elif V8_TARGET_BIG_ENDIAN
+ return IsWordOr(IsWordShl(first_byte, IsInt32Constant(kBitsPerByte)),
+ second_byte);
+#else
+#error "Unknown Architecture"
+#endif
+ }
+}
+
+
Graph*
InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() {
End();
@@ -268,20 +305,26 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
InterpreterAssemblerForTest m(this, bytecode);
int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode);
for (int i = 0; i < number_of_operands; i++) {
+ int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i);
switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) {
- case interpreter::OperandType::kCount:
- EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(i));
+ case interpreter::OperandType::kCount8:
+ EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset));
break;
- case interpreter::OperandType::kIdx:
- EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(i));
+ case interpreter::OperandType::kIdx8:
+ EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(offset));
break;
case interpreter::OperandType::kImm8:
- EXPECT_THAT(m.BytecodeOperandImm8(i),
- m.IsBytecodeOperandSignExtended(i));
+ EXPECT_THAT(m.BytecodeOperandImm(i),
+ m.IsBytecodeOperandSignExtended(offset));
break;
- case interpreter::OperandType::kReg:
+ case interpreter::OperandType::kMaybeReg8:
+ case interpreter::OperandType::kReg8:
EXPECT_THAT(m.BytecodeOperandReg(i),
- m.IsBytecodeOperandSignExtended(i));
+ m.IsBytecodeOperandSignExtended(offset));
+ break;
+ case interpreter::OperandType::kIdx16:
+ EXPECT_THAT(m.BytecodeOperandIdx(i),
+ m.IsBytecodeOperandShort(offset));
break;
case interpreter::OperandType::kNone:
UNREACHABLE();
@@ -429,21 +472,19 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
}
-TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
+TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
- Node* load_from_current_context = m.LoadContextSlot(22);
- Matcher<Node*> load_from_current_context_matcher = m.IsLoad(
- kMachAnyTagged, IsParameter(Linkage::kInterpreterContextParameter),
- IsIntPtrConstant(Context::SlotOffset(22)));
- EXPECT_THAT(load_from_current_context, load_from_current_context_matcher);
-
- // Let's imagine that the loaded context slot is another context.
- Node* load_from_any_context =
- m.LoadContextSlot(load_from_current_context, 23);
- EXPECT_THAT(load_from_any_context,
- m.IsLoad(kMachAnyTagged, load_from_current_context_matcher,
- IsIntPtrConstant(Context::SlotOffset(23))));
+ int index = 3;
+ Node* fixed_array = m.IntPtrConstant(0xdeadbeef);
+ Node* load_element = m.LoadFixedArrayElement(fixed_array, index);
+ EXPECT_THAT(
+ load_element,
+ m.IsLoad(kMachAnyTagged, fixed_array,
+ IsIntPtrAdd(
+ IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
+ IsWordShl(IsInt32Constant(index),
+ IsInt32Constant(kPointerSizeLog2)))));
}
}
@@ -461,7 +502,41 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
}
-TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
+TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
+ TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
+ InterpreterAssemblerForTest m(this, bytecode);
+ Node* context = m.Int32Constant(1);
+ Node* slot_index = m.Int32Constant(22);
+ Node* load_context_slot = m.LoadContextSlot(context, slot_index);
+
+ Matcher<Node*> offset =
+ IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
+ IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
+ EXPECT_THAT(load_context_slot, m.IsLoad(kMachAnyTagged, context, offset));
+ }
+}
+
+
+TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
+ TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
+ InterpreterAssemblerForTest m(this, bytecode);
+ Node* context = m.Int32Constant(1);
+ Node* slot_index = m.Int32Constant(22);
+ Node* value = m.Int32Constant(100);
+ Node* store_context_slot = m.StoreContextSlot(context, slot_index, value);
+
+ Matcher<Node*> offset =
+ IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)),
+ IsInt32Constant(Context::kHeaderSize - kHeapObjectTag));
+ EXPECT_THAT(
+ store_context_slot,
+ m.IsStore(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier),
+ context, offset, value));
+ }
+}
+
+
+TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
Node* arg1 = m.Int32Constant(2);
@@ -474,6 +549,33 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
}
+TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
+ TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
+ InterpreterAssemblerForTest m(this, bytecode);
+ Callable builtin = CodeFactory::InterpreterCEntry(isolate());
+
+ Node* function_id = m.Int32Constant(0);
+ Node* first_arg = m.Int32Constant(1);
+ Node* arg_count = m.Int32Constant(2);
+
+ Matcher<Node*> function_table = IsExternalConstant(
+ ExternalReference::runtime_function_table_address(isolate()));
+ Matcher<Node*> function = IsIntPtrAdd(
+ function_table,
+ IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function))));
+ Matcher<Node*> function_entry =
+ m.IsLoad(kMachPtr, function,
+ IsInt32Constant(offsetof(Runtime::Function, entry)));
+
+ Node* call_runtime = m.CallRuntime(function_id, first_arg, arg_count);
+ EXPECT_THAT(call_runtime,
+ m.IsCall(_, IsHeapConstant(builtin.code()), arg_count,
+ first_arg, function_entry,
+ IsParameter(Linkage::kInterpreterContextParameter)));
+ }
+}
+
+
TARGET_TEST_F(InterpreterAssemblerTest, CallIC) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
@@ -494,7 +596,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallIC) {
TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
- Callable builtin = CodeFactory::PushArgsAndCall(isolate());
+ Callable builtin = CodeFactory::InterpreterPushArgsAndCall(isolate());
Node* function = m.Int32Constant(0);
Node* first_arg = m.Int32Constant(1);
Node* arg_count = m.Int32Constant(2);
diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h
index 0ed91eb401..49c1c2ad29 100644
--- a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h
+++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h
@@ -43,8 +43,9 @@ class InterpreterAssemblerTest : public TestWithIsolateAndZone {
const Matcher<const CallDescriptor*>& descriptor_matcher,
A... args);
- Matcher<Node*> IsBytecodeOperand(int operand);
- Matcher<Node*> IsBytecodeOperandSignExtended(int operand);
+ Matcher<Node*> IsBytecodeOperand(int offset);
+ Matcher<Node*> IsBytecodeOperandSignExtended(int offset);
+ Matcher<Node*> IsBytecodeOperandShort(int offset);
using InterpreterAssembler::call_descriptor;
using InterpreterAssembler::graph;
diff --git a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
index 9e0cee0d3d..ae367aa395 100644
--- a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
@@ -5,6 +5,7 @@
#include "src/compiler/js-builtin-reducer.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-properties.h"
+#include "src/compiler/simplified-operator.h"
#include "src/compiler/typer.h"
#include "src/isolate-inl.h"
#include "test/unittests/compiler/graph-unittest.h"
@@ -26,7 +27,9 @@ class JSBuiltinReducerTest : public TypedGraphTest {
Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::Flag::kNoFlags) {
MachineOperatorBuilder machine(zone(), kMachPtr, flags);
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ SimplifiedOperatorBuilder simplified(zone());
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
+ &machine);
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
JSBuiltinReducer reducer(&graph_reducer, &jsgraph);
@@ -82,12 +85,12 @@ TEST_F(JSBuiltinReducerTest, MathMax0) {
Node* effect = graph()->start();
Node* control = graph()->start();
+ Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
- Node* call = graph()->NewNode(
- javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), frame_state, frame_state, effect,
- control);
+ Node* call = graph()->NewNode(javascript()->CallFunction(2, language_mode),
+ function, UndefinedConstant(), context,
+ frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -101,14 +104,15 @@ TEST_F(JSBuiltinReducerTest, MathMax1) {
Node* effect = graph()->start();
Node* control = graph()->start();
+ Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kNumberTypes) {
Node* p0 = Parameter(t0, 0);
- Node* call = graph()->NewNode(
- javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0, frame_state, frame_state, effect,
- control);
+ Node* call =
+ graph()->NewNode(javascript()->CallFunction(3, language_mode),
+ function, UndefinedConstant(), p0, context,
+ frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -123,6 +127,7 @@ TEST_F(JSBuiltinReducerTest, MathMax2) {
Node* effect = graph()->start();
Node* control = graph()->start();
+ Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kIntegral32Types) {
@@ -130,10 +135,9 @@ TEST_F(JSBuiltinReducerTest, MathMax2) {
Node* p0 = Parameter(t0, 0);
Node* p1 = Parameter(t1, 1);
Node* call =
- graph()->NewNode(javascript()->CallFunction(
- 4, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0, p1, frame_state,
- frame_state, effect, control);
+ graph()->NewNode(javascript()->CallFunction(4, language_mode),
+ function, UndefinedConstant(), p0, p1, context,
+ frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -154,6 +158,7 @@ TEST_F(JSBuiltinReducerTest, MathImul) {
Node* effect = graph()->start();
Node* control = graph()->start();
+ Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kIntegral32Types) {
@@ -161,10 +166,9 @@ TEST_F(JSBuiltinReducerTest, MathImul) {
Node* p0 = Parameter(t0, 0);
Node* p1 = Parameter(t1, 1);
Node* call =
- graph()->NewNode(javascript()->CallFunction(
- 4, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0, p1, frame_state,
- frame_state, effect, control);
+ graph()->NewNode(javascript()->CallFunction(4, language_mode),
+ function, UndefinedConstant(), p0, p1, context,
+ frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
@@ -184,14 +188,15 @@ TEST_F(JSBuiltinReducerTest, MathFround) {
Node* effect = graph()->start();
Node* control = graph()->start();
+ Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kNumberTypes) {
Node* p0 = Parameter(t0, 0);
- Node* call = graph()->NewNode(
- javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode),
- function, UndefinedConstant(), p0, frame_state, frame_state, effect,
- control);
+ Node* call =
+ graph()->NewNode(javascript()->CallFunction(3, language_mode),
+ function, UndefinedConstant(), p0, context,
+ frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
diff --git a/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc
index 4cc8f17509..0fcf9f7087 100644
--- a/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc
@@ -20,7 +20,8 @@ class JSContextRelaxationTest : public GraphTest {
Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kNoFlags) {
MachineOperatorBuilder machine(zone(), kMachPtr, flags);
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr,
+ &machine);
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
JSContextRelaxation reducer;
@@ -29,7 +30,8 @@ class JSContextRelaxationTest : public GraphTest {
Node* EmptyFrameState() {
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr,
+ &machine);
return jsgraph.EmptyFrameState();
}
@@ -80,10 +82,9 @@ TEST_F(JSContextRelaxationTest,
ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
@@ -99,10 +100,9 @@ TEST_F(JSContextRelaxationTest,
ShallowFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_FALSE(r.Changed());
EXPECT_EQ(context, NodeProperties::GetContextInput(node));
@@ -118,10 +118,9 @@ TEST_F(JSContextRelaxationTest,
DeepFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
@@ -137,10 +136,9 @@ TEST_F(JSContextRelaxationTest,
DeepFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_FALSE(r.Changed());
EXPECT_EQ(context, NodeProperties::GetContextInput(node));
@@ -159,10 +157,9 @@ TEST_F(JSContextRelaxationTest,
op, graph()->start(), graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state_2, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
@@ -185,10 +182,9 @@ TEST_F(JSContextRelaxationTest,
frame_state_1, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state_2, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
@@ -209,10 +205,9 @@ TEST_F(JSContextRelaxationTest,
graph()->NewNode(op, graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state_2, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
@@ -235,10 +230,9 @@ TEST_F(JSContextRelaxationTest,
frame_state_1, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state_2, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node));
@@ -258,10 +252,9 @@ TEST_F(JSContextRelaxationTest,
op, graph()->start(), graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state_2, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node));
@@ -274,17 +267,16 @@ TEST_F(JSContextRelaxationTest,
Node* const input1 = Parameter(1);
Node* const context = Parameter(2);
Node* const outer_context = Parameter(3);
- const Operator* op = javascript()->CreateFunctionContext();
+ const Operator* op = javascript()->CreateFunctionContext(0);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Node* nested_context =
graph()->NewNode(op, graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
- Node* node =
- graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
- STRICT, VectorSlotPair()),
- input0, input1, context, frame_state_2, effect, control);
+ Node* node = graph()->NewNode(
+ javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
+ context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_FALSE(r.Changed());
EXPECT_EQ(context, NodeProperties::GetContextInput(node));
diff --git a/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
index 9d5b649471..a22f660c21 100644
--- a/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc
@@ -32,7 +32,9 @@ class JSIntrinsicLoweringTest : public GraphTest {
Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kNoFlags) {
MachineOperatorBuilder machine(zone(), kMachPtr, flags);
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ SimplifiedOperatorBuilder simplified(zone());
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
+ &machine);
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
JSIntrinsicLowering reducer(&graph_reducer, &jsgraph,
@@ -42,7 +44,8 @@ class JSIntrinsicLoweringTest : public GraphTest {
Node* EmptyFrameState() {
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr,
+ &machine);
return jsgraph.EmptyFrameState();
}
@@ -299,30 +302,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineJSValueGetValue) {
// -----------------------------------------------------------------------------
-// %_Likely
-
-TEST_F(JSIntrinsicLoweringTest, Likely) {
- Node* const input = Parameter(0);
- Node* const context = Parameter(1);
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Node* const likely =
- graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineLikely, 1),
- input, context, effect, control);
- Node* const to_boolean =
- graph()->NewNode(javascript()->ToBoolean(), likely, context, effect);
- Diamond d(graph(), common(), to_boolean);
- graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge));
-
- ASSERT_EQ(BranchHint::kNone, BranchHintOf(d.branch->op()));
- Reduction const r = Reduce(likely);
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), input);
- ASSERT_EQ(BranchHint::kTrue, BranchHintOf(d.branch->op()));
-}
-
-
-// -----------------------------------------------------------------------------
// %_MathFloor
@@ -370,9 +349,8 @@ TEST_F(JSIntrinsicLoweringTest, InlineStringGetLength) {
javascript()->CallRuntime(Runtime::kInlineStringGetLength, 1), input,
context, effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsLoadField(AccessBuilder::ForStringLength(zone()), input, effect,
- control));
+ EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(),
+ input, effect, control));
}
@@ -394,30 +372,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineMathClz32) {
// -----------------------------------------------------------------------------
-// %_Unlikely
-
-TEST_F(JSIntrinsicLoweringTest, Unlikely) {
- Node* const input = Parameter(0);
- Node* const context = Parameter(1);
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Node* const unlikely =
- graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineUnlikely, 1),
- input, context, effect, control);
- Node* const to_boolean =
- graph()->NewNode(javascript()->ToBoolean(), unlikely, context, effect);
- Diamond d(graph(), common(), to_boolean);
- graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge));
-
- ASSERT_EQ(BranchHint::kNone, BranchHintOf(d.branch->op()));
- Reduction const r = Reduce(unlikely);
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), input);
- ASSERT_EQ(BranchHint::kFalse, BranchHintOf(d.branch->op()));
-}
-
-
-// -----------------------------------------------------------------------------
// %_ValueOf
diff --git a/deps/v8/test/unittests/compiler/js-operator-unittest.cc b/deps/v8/test/unittests/compiler/js-operator-unittest.cc
index a1f3973734..0461a0d625 100644
--- a/deps/v8/test/unittests/compiler/js-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-operator-unittest.cc
@@ -74,7 +74,7 @@ const SharedOperator kSharedOperators[] = {
SHARED(UnaryNot, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
SHARED(ToBoolean, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
- SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
+ SHARED(ToString, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
@@ -82,7 +82,6 @@ const SharedOperator kSharedOperators[] = {
SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(TypeOf, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
- SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
SHARED(CreateWithContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2),
#undef SHARED
diff --git a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc
index f3f1b733fc..dece25def1 100644
--- a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc
@@ -40,7 +40,9 @@ class JSTypeFeedbackTest : public TypedGraphTest {
isolate()->native_context()->global_object(), isolate());
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ SimplifiedOperatorBuilder simplified(zone());
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
+ &machine);
JSTypeFeedbackTable table(zone());
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
@@ -51,7 +53,8 @@ class JSTypeFeedbackTest : public TypedGraphTest {
Node* EmptyFrameState() {
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr,
+ &machine);
return jsgraph.EmptyFrameState();
}
@@ -78,15 +81,13 @@ class JSTypeFeedbackTest : public TypedGraphTest {
const char* string, Node* effect, Node* control,
JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
VectorSlotPair feedback;
- Node* global = UndefinedConstant();
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Handle<Name> name = isolate()->factory()->InternalizeUtf8String(string);
const Operator* op = javascript()->LoadGlobal(name, feedback);
- Node* load =
- graph()->NewNode(op, context, global, vector, context,
- EmptyFrameState(), EmptyFrameState(), effect, control);
+ Node* load = graph()->NewNode(op, vector, context, EmptyFrameState(),
+ EmptyFrameState(), effect, control);
Node* if_success = graph()->NewNode(common()->IfSuccess(), load);
return graph()->NewNode(common()->Return(), load, load, if_success);
}
diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
index da964db23a..37dc1f3eb5 100644
--- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
@@ -74,19 +74,36 @@ const LanguageMode kLanguageModes[] = {SLOPPY, STRICT, STRONG};
class JSTypedLoweringTest : public TypedGraphTest {
public:
- JSTypedLoweringTest() : TypedGraphTest(3), javascript_(zone()) {}
+ JSTypedLoweringTest()
+ : TypedGraphTest(3), javascript_(zone()), deps_(isolate(), zone()) {}
~JSTypedLoweringTest() override {}
protected:
Reduction Reduce(Node* node) {
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
+ SimplifiedOperatorBuilder simplified(zone());
+ JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
+ &machine);
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
- JSTypedLowering reducer(&graph_reducer, &jsgraph, zone());
+ JSTypedLowering reducer(&graph_reducer, &deps_,
+ JSTypedLowering::kDeoptimizationEnabled, &jsgraph,
+ zone());
return reducer.Reduce(node);
}
+ Node* FrameState(Handle<SharedFunctionInfo> shared, Node* outer_frame_state) {
+ Node* state_values = graph()->NewNode(common()->StateValues(0));
+ return graph()->NewNode(
+ common()->FrameState(BailoutId::None(),
+ OutputFrameStateCombine::Ignore(),
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kJavaScriptFunction, 1, 0,
+ shared, CALL_MAINTAINS_NATIVE_CONTEXT)),
+ state_values, state_values, state_values, NumberConstant(0),
+ UndefinedConstant(), outer_frame_state);
+ }
+
Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) {
Handle<JSArrayBuffer> buffer = factory()->NewJSArrayBuffer();
JSArrayBuffer::Setup(buffer, isolate(), true, bytes, byte_length);
@@ -102,6 +119,7 @@ class JSTypedLoweringTest : public TypedGraphTest {
private:
JSOperatorBuilder javascript_;
+ CompilationDependencies deps_;
};
@@ -189,11 +207,10 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithString) {
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
context, graph()->start()));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(zone()), input,
- graph()->start(), graph()->start()),
- IsNumberConstant(0.0)));
+ EXPECT_THAT(r.replacement(),
+ IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), input,
+ graph()->start(), graph()->start()),
+ IsNumberConstant(0.0)));
}
@@ -388,8 +405,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
EXPECT_THAT(
r.replacement(),
IsNumberLessThan(IsNumberConstant(0.0),
- IsLoadField(AccessBuilder::ForStringLength(zone()),
- input, graph()->start(), graph()->start())));
+ IsLoadField(AccessBuilder::ForStringLength(), input,
+ graph()->start(), graph()->start())));
}
@@ -421,6 +438,56 @@ TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) {
// -----------------------------------------------------------------------------
+// JSToObject
+
+
+TEST_F(JSTypedLoweringTest, JSToObjectWithAny) {
+ Node* const input = Parameter(Type::Any(), 0);
+ Node* const context = Parameter(Type::Any(), 1);
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(javascript()->ToObject(), input,
+ context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsPhi(kMachAnyTagged, _, _, _));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSToObjectWithReceiver) {
+ Node* const input = Parameter(Type::Receiver(), 0);
+ Node* const context = Parameter(Type::Any(), 1);
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(javascript()->ToObject(), input,
+ context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(input, r.replacement());
+}
+
+
+// -----------------------------------------------------------------------------
+// JSToString
+
+
+TEST_F(JSTypedLoweringTest, JSToStringWithBoolean) {
+ Node* const input = Parameter(Type::Boolean(), 0);
+ Node* const context = Parameter(Type::Any(), 1);
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction r = Reduce(graph()->NewNode(javascript()->ToString(), input,
+ context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsSelect(kMachAnyTagged, input, IsHeapConstant(factory()->true_string()),
+ IsHeapConstant(factory()->false_string())));
+}
+
+
+// -----------------------------------------------------------------------------
// JSStrictEqual
@@ -659,7 +726,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(
- graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
+ graph()->NewNode(javascript()->LoadProperty(language_mode, feedback),
base, key, vector, context, EmptyFrameState(),
EmptyFrameState(), effect, control));
@@ -703,7 +770,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(
- graph()->NewNode(javascript()->LoadProperty(feedback, language_mode),
+ graph()->NewNode(javascript()->LoadProperty(language_mode, feedback),
base, key, vector, context, EmptyFrameState(),
EmptyFrameState(), effect, control));
@@ -862,41 +929,6 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
// -----------------------------------------------------------------------------
-// JSLoadGlobal
-
-
-TEST_F(JSTypedLoweringTest, JSLoadGlobalConstants) {
- Handle<String> names[] = {
- Handle<String>(isolate()->heap()->undefined_string(), isolate()),
- Handle<String>(isolate()->heap()->infinity_string(), isolate()),
- Handle<String>(isolate()->heap()->nan_string(), isolate()) // --
- };
- Matcher<Node*> matches[] = {
- IsHeapConstant(
- Handle<HeapObject>(isolate()->heap()->undefined_value(), isolate())),
- IsNumberConstant(std::numeric_limits<double>::infinity()),
- IsNumberConstant(IsNaN()) // --
- };
-
- VectorSlotPair feedback;
- Node* global = UndefinedConstant();
- Node* vector = UndefinedConstant();
- Node* context = UndefinedConstant();
- Node* effect = graph()->start();
- Node* control = graph()->start();
-
- for (size_t i = 0; i < arraysize(names); i++) {
- Reduction r = Reduce(graph()->NewNode(
- javascript()->LoadGlobal(names[i], feedback), context, global, vector,
- context, EmptyFrameState(), EmptyFrameState(), effect, control));
-
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), matches[i]);
- }
-}
-
-
-// -----------------------------------------------------------------------------
// JSLoadNamed
@@ -910,83 +942,12 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) {
Node* const control = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Reduction const r = Reduce(
- graph()->NewNode(javascript()->LoadNamed(name, feedback, language_mode),
+ graph()->NewNode(javascript()->LoadNamed(language_mode, name, feedback),
receiver, vector, context, EmptyFrameState(),
EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsLoadField(AccessBuilder::ForStringLength(zone()), receiver,
- effect, control));
- }
-}
-
-
-// -----------------------------------------------------------------------------
-// JSLoadDynamicGlobal
-
-
-TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) {
- Node* const context = Parameter(Type::Any());
- Node* const vector = UndefinedConstant();
- Node* const frame_state = EmptyFrameState();
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Handle<String> name = factory()->object_string();
- VectorSlotPair feedback;
- for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) {
- uint32_t bitset = 1 << i; // Only single check.
- Reduction r = Reduce(graph()->NewNode(
- javascript()->LoadDynamicGlobal(name, bitset, feedback,
- NOT_INSIDE_TYPEOF),
- vector, context, context, frame_state, frame_state, effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsPhi(kMachAnyTagged, _, _,
- IsMerge(
- IsIfTrue(IsBranch(
- IsReferenceEqual(
- Type::Tagged(),
- IsLoadContext(
- ContextAccess(i, Context::EXTENSION_INDEX, false),
- context),
- IsNumberConstant(BitEq(0.0))),
- control)),
- _)));
- }
-}
-
-
-// -----------------------------------------------------------------------------
-// JSLoadDynamicContext
-
-
-TEST_F(JSTypedLoweringTest, JSLoadDynamicContext) {
- Node* const context = Parameter(Type::Any());
- Node* const frame_state = EmptyFrameState();
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Handle<String> name = factory()->object_string();
- for (int i = 0; i < DynamicContextAccess::kMaxCheckDepth; ++i) {
- uint32_t bitset = 1 << i; // Only single check.
- Reduction r = Reduce(
- graph()->NewNode(javascript()->LoadDynamicContext(name, bitset, 23, 42),
- context, context, frame_state, effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsPhi(kMachAnyTagged,
- IsLoadContext(ContextAccess(23, 42, false), context), _,
- IsMerge(
- IsIfTrue(IsBranch(
- IsReferenceEqual(
- Type::Tagged(),
- IsLoadContext(
- ContextAccess(i, Context::EXTENSION_INDEX, false),
- context),
- IsNumberConstant(BitEq(0.0))),
- control)),
- _)));
+ EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(),
+ receiver, effect, control));
}
}
@@ -1018,6 +979,72 @@ TEST_F(JSTypedLoweringTest, JSAddWithString) {
// -----------------------------------------------------------------------------
+// JSCreateArguments
+
+
+TEST_F(JSTypedLoweringTest, JSCreateArgumentsViaStub) {
+ Node* const closure = Parameter(Type::Any());
+ Node* const context = UndefinedConstant();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared());
+ Node* const frame_state = FrameState(shared, graph()->start());
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->CreateArguments(
+ CreateArgumentsParameters::kMappedArguments, 0),
+ closure, context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsCall(_, IsHeapConstant(CodeFactory::ArgumentsAccess(
+ isolate(), false, false)
+ .code()),
+ closure, IsNumberConstant(0), _, effect, control));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSCreateArgumentsInlinedMapped) {
+ Node* const closure = Parameter(Type::Any());
+ Node* const context = UndefinedConstant();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared());
+ Node* const frame_state_outer = FrameState(shared, graph()->start());
+ Node* const frame_state_inner = FrameState(shared, frame_state_outer);
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->CreateArguments(
+ CreateArgumentsParameters::kMappedArguments, 0),
+ closure, context, frame_state_inner, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFinishRegion(
+ IsAllocate(IsNumberConstant(Heap::kSloppyArgumentsObjectSize),
+ IsBeginRegion(effect), control),
+ _));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSCreateArgumentsInlinedUnmapped) {
+ Node* const closure = Parameter(Type::Any());
+ Node* const context = UndefinedConstant();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared());
+ Node* const frame_state_outer = FrameState(shared, graph()->start());
+ Node* const frame_state_inner = FrameState(shared, frame_state_outer);
+ Reduction r = Reduce(
+ graph()->NewNode(javascript()->CreateArguments(
+ CreateArgumentsParameters::kUnmappedArguments, 0),
+ closure, context, frame_state_inner, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFinishRegion(
+ IsAllocate(IsNumberConstant(Heap::kStrictArgumentsObjectSize),
+ IsBeginRegion(effect), control),
+ _));
+}
+
+
+// -----------------------------------------------------------------------------
// JSCreateClosure
@@ -1087,11 +1114,47 @@ TEST_F(JSTypedLoweringTest, JSCreateLiteralObject) {
// -----------------------------------------------------------------------------
+// JSCreateFunctionContext
+
+
+TEST_F(JSTypedLoweringTest, JSCreateFunctionContextViaInlinedAllocation) {
+ Node* const closure = Parameter(Type::Any());
+ Node* const context = Parameter(Type::Any());
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction const r =
+ Reduce(graph()->NewNode(javascript()->CreateFunctionContext(8), closure,
+ context, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsFinishRegion(IsAllocate(IsNumberConstant(Context::SizeFor(
+ 8 + Context::MIN_CONTEXT_SLOTS)),
+ IsBeginRegion(effect), control),
+ _));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSCreateFunctionContextViaStub) {
+ Node* const closure = Parameter(Type::Any());
+ Node* const context = Parameter(Type::Any());
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction const r =
+ Reduce(graph()->NewNode(javascript()->CreateFunctionContext(32), closure,
+ context, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsCall(_, IsHeapConstant(
+ CodeFactory::FastNewContext(isolate(), 32).code()),
+ closure, context, effect, control));
+}
+
+
+// -----------------------------------------------------------------------------
// JSCreateWithContext
TEST_F(JSTypedLoweringTest, JSCreateWithContext) {
- FLAG_turbo_allocate = true;
Node* const object = Parameter(Type::Receiver());
Node* const closure = Parameter(Type::Any());
Node* const context = Parameter(Type::Any());
@@ -1103,10 +1166,74 @@ TEST_F(JSTypedLoweringTest, JSCreateWithContext) {
closure, context, frame_state, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
- IsFinish(IsAllocate(IsNumberConstant(Context::SizeFor(
- Context::MIN_CONTEXT_SLOTS)),
- effect, control),
- _));
+ IsFinishRegion(IsAllocate(IsNumberConstant(Context::SizeFor(
+ Context::MIN_CONTEXT_SLOTS)),
+ IsBeginRegion(effect), control),
+ _));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSInstanceOf
+// Test that instanceOf is reduced if and only if the right-hand side is a
+// function constant. Functional correctness is ensured elsewhere.
+
+
+TEST_F(JSTypedLoweringTest, JSInstanceOfSpecializationWithoutSmiCheck) {
+ Node* const context = Parameter(Type::Any());
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+
+ // Reduce if left-hand side is known to be an object.
+ Node* instanceOf =
+ graph()->NewNode(javascript()->InstanceOf(), Parameter(Type::Object(), 0),
+ HeapConstant(isolate()->object_function()), context,
+ frame_state, effect, control);
+ Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(instanceOf);
+ ASSERT_TRUE(r.Changed());
+ ASSERT_EQ(r.replacement(), dummy->InputAt(0));
+ ASSERT_NE(instanceOf, dummy->InputAt(0));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSInstanceOfSpecializationWithSmiCheck) {
+ Node* const context = Parameter(Type::Any());
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+
+ // Reduce if left-hand side could be a Smi.
+ Node* instanceOf =
+ graph()->NewNode(javascript()->InstanceOf(), Parameter(Type::Any(), 0),
+ HeapConstant(isolate()->object_function()), context,
+ frame_state, effect, control);
+ Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(instanceOf);
+ ASSERT_TRUE(r.Changed());
+ ASSERT_EQ(r.replacement(), dummy->InputAt(0));
+ ASSERT_NE(instanceOf, dummy->InputAt(0));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSInstanceOfNoSpecialization) {
+ Node* const context = Parameter(Type::Any());
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+
+ // Do not reduce if right-hand side is not a function constant.
+ Node* instanceOf = graph()->NewNode(
+ javascript()->InstanceOf(), Parameter(Type::Any(), 0),
+ Parameter(Type::Any()), context, frame_state, effect, control);
+ Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context,
+ frame_state, effect, control);
+ Reduction r = Reduce(instanceOf);
+ ASSERT_FALSE(r.Changed());
+ ASSERT_EQ(instanceOf, dummy->InputAt(0));
}
} // namespace compiler
diff --git a/deps/v8/test/unittests/compiler/live-range-unittest.cc b/deps/v8/test/unittests/compiler/live-range-unittest.cc
index 886a8121c7..e802aedff1 100644
--- a/deps/v8/test/unittests/compiler/live-range-unittest.cc
+++ b/deps/v8/test/unittests/compiler/live-range-unittest.cc
@@ -32,11 +32,14 @@ class LiveRangeUnitTest : public TestWithZone {
TopLevelLiveRange* Splinter(TopLevelLiveRange* top, int start, int end,
int new_id = 0) {
- TopLevelLiveRange* ret =
- new (zone()) TopLevelLiveRange(new_id, MachineType::kRepTagged);
+ if (top->splinter() == nullptr) {
+ TopLevelLiveRange* ret =
+ new (zone()) TopLevelLiveRange(new_id, MachineType::kRepTagged);
+ top->SetSplinter(ret);
+ }
top->Splinter(LifetimePosition::FromInt(start),
- LifetimePosition::FromInt(end), ret, zone());
- return ret;
+ LifetimePosition::FromInt(end), zone());
+ return top->splinter();
}
// Ranges first and second match structurally.
@@ -377,6 +380,25 @@ TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsRight) {
}
+TEST_F(LiveRangeUnitTest, SplinterMergeMultipleTimes) {
+ TopLevelLiveRange* range =
+ TestRangeBuilder(zone()).Add(0, 3).Add(5, 10).Add(12, 16).Build();
+ Splinter(range, 4, 6);
+ Splinter(range, 8, 14);
+ TopLevelLiveRange* splinter = range->splinter();
+ EXPECT_EQ(nullptr, range->next());
+ EXPECT_EQ(nullptr, splinter->next());
+ EXPECT_EQ(range, splinter->splintered_from());
+
+ TopLevelLiveRange* expected_source =
+ TestRangeBuilder(zone()).Add(0, 3).Add(6, 8).Add(14, 16).Build();
+ TopLevelLiveRange* expected_splinter =
+ TestRangeBuilder(zone()).Add(5, 6).Add(8, 10).Add(12, 14).Build();
+ EXPECT_TRUE(RangesMatch(expected_source, range));
+ EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
+}
+
+
TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsRight) {
TopLevelLiveRange* original =
TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
@@ -416,8 +438,9 @@ TEST_F(LiveRangeUnitTest, IDGeneration) {
TopLevelLiveRange* splinter =
new (zone()) TopLevelLiveRange(101, MachineType::kRepTagged);
+ vreg->SetSplinter(splinter);
vreg->Splinter(LifetimePosition::FromInt(4), LifetimePosition::FromInt(12),
- splinter, zone());
+ zone());
EXPECT_EQ(101, splinter->vreg());
EXPECT_EQ(1, splinter->relative_id());
diff --git a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc
index 9016e04e25..3f6a658e82 100644
--- a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc
@@ -25,7 +25,8 @@ class LivenessAnalysisTest : public GraphTest {
: locals_count_(locals_count),
machine_(zone(), kRepWord32),
javascript_(zone()),
- jsgraph_(isolate(), graph(), common(), &javascript_, &machine_),
+ jsgraph_(isolate(), graph(), common(), &javascript_, nullptr,
+ &machine_),
analyzer_(locals_count, zone()),
empty_values_(graph()->NewNode(common()->StateValues(0), 0, nullptr)),
next_checkpoint_id_(0),
diff --git a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
index 13a5b6f3bb..6f7ed3aca4 100644
--- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -29,7 +29,8 @@ class MachineOperatorReducerTest : public TypedGraphTest {
protected:
Reduction Reduce(Node* node) {
JSOperatorBuilder javascript(zone());
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine_);
+ JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
+ &machine_);
MachineOperatorReducer reducer(&jsgraph);
return reducer.Reduce(node);
}
@@ -1645,6 +1646,18 @@ TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
}
}
+
+TEST_F(MachineOperatorReducerTest, RoundPlusTruncate) {
+ Node* p0 = Parameter(0);
+ Node* t0 = graph()->NewNode(machine()->RoundInt64ToFloat64(), p0);
+ Node* t1 = graph()->NewNode(
+ machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript), t0);
+
+ Reduction r = Reduce(t1);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), p0);
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc b/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
index b88f4695c8..a16ad7a31f 100644
--- a/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
+++ b/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
@@ -646,7 +646,7 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Parameter(1), kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -696,8 +696,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
const MemoryAccessImm memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -748,8 +748,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
const MemoryAccessImm1 memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
@@ -845,6 +845,71 @@ TEST_F(InstructionSelectorTest, Float64Abs) {
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
}
+
+TEST_F(InstructionSelectorTest, Float32Max) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float32Max(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float32Max is `(b < a) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMipsFloat32Max, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float32Min) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float32Min(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float32Min is `(a < b) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMipsFloat32Min, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Max) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float64Max(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float64Max is `(b < a) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMipsFloat64Max, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Min) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float64Min(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float64Min is `(a < b) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMipsFloat64Min, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc b/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc
index fe57eb5e28..148667333b 100644
--- a/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc
@@ -649,7 +649,7 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Parameter(1), kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -697,8 +697,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
const MemoryAccessImm memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@@ -746,8 +746,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
const MemoryAccessImm1 memacc = GetParam();
TRACED_FOREACH(int32_t, index, memacc.immediates) {
StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
- m.Parameter(1));
+ m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
@@ -841,6 +841,21 @@ TEST_F(InstructionSelectorTest, Word32Clz) {
}
+TEST_F(InstructionSelectorTest, Word64Clz) {
+ StreamBuilder m(this, kMachUint64, kMachUint64);
+ Node* const p0 = m.Parameter(0);
+ Node* const n = m.Word64Clz(p0);
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMips64Dclz, s[0]->arch_opcode());
+ ASSERT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
TEST_F(InstructionSelectorTest, Float32Abs) {
StreamBuilder m(this, kMachFloat32, kMachFloat32);
Node* const p0 = m.Parameter(0);
@@ -870,6 +885,70 @@ TEST_F(InstructionSelectorTest, Float64Abs) {
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
}
+
+TEST_F(InstructionSelectorTest, Float32Max) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float32Max(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float32Max is `(b < a) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMips64Float32Max, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float32Min) {
+ StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float32Min(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float32Min is `(a < b) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMips64Float32Min, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Max) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float64Max(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float64Max is `(b < a) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMips64Float64Max, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64Min) {
+ StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+ Node* const p0 = m.Parameter(0);
+ Node* const p1 = m.Parameter(1);
+ Node* const n = m.Float64Min(p0, p1);
+ m.Return(n);
+ Stream s = m.Build();
+ // Float64Min is `(a < b) ? a : b`.
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMips64Float64Min, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc b/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc
index fb2b6ad457..66eb9abc4f 100644
--- a/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc
@@ -67,10 +67,16 @@ class MoveOptimizerTest : public InstructionSequenceTest {
case kConstant:
return ConstantOperand(op.value_);
case kFixedSlot:
- return StackSlotOperand(kRepWord32, op.value_);
+ return AllocatedOperand(LocationOperand::STACK_SLOT, kRepWord32,
+ op.value_);
case kFixedRegister:
CHECK(0 <= op.value_ && op.value_ < num_general_registers());
- return RegisterOperand(kRepWord32, op.value_);
+ return AllocatedOperand(LocationOperand::REGISTER, kRepWord32,
+ op.value_);
+ case kExplicit:
+ CHECK(0 <= op.value_ && op.value_ < num_general_registers());
+ return ExplicitOperand(LocationOperand::REGISTER, kRepWord32,
+ op.value_);
default:
break;
}
@@ -97,6 +103,30 @@ TEST_F(MoveOptimizerTest, RemovesRedundant) {
}
+TEST_F(MoveOptimizerTest, RemovesRedundantExplicit) {
+ int first_reg_index =
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableGeneralCode(0);
+ int second_reg_index =
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+ ->GetAllocatableGeneralCode(1);
+
+ StartBlock();
+ auto first_instr = EmitNop();
+ AddMove(first_instr, Reg(first_reg_index), ExplicitReg(second_reg_index));
+ auto last_instr = EmitNop();
+ AddMove(last_instr, Reg(second_reg_index), Reg(first_reg_index));
+ EndBlock(Last());
+
+ Optimize();
+
+ CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0]));
+ auto move = last_instr->parallel_moves()[0];
+ CHECK_EQ(1, NonRedundantSize(move));
+ CHECK(Contains(move, Reg(first_reg_index), ExplicitReg(second_reg_index)));
+}
+
+
TEST_F(MoveOptimizerTest, SplitsConstants) {
StartBlock();
EndBlock(Last());
@@ -177,6 +207,45 @@ TEST_F(MoveOptimizerTest, SimpleMergeCycle) {
CHECK(Contains(move, Reg(1), Reg(0)));
}
+
+TEST_F(MoveOptimizerTest, GapsCanMoveOverInstruction) {
+ StartBlock();
+ int const_index = 1;
+ DefineConstant(const_index);
+ Instruction* ctant_def = LastInstruction();
+ AddMove(ctant_def, Reg(1), Reg(0));
+
+ Instruction* last = EmitNop();
+ AddMove(last, Const(const_index), Reg(0));
+ AddMove(last, Reg(0), Reg(1));
+ EndBlock(Last());
+ Optimize();
+
+ ParallelMove* inst1_start =
+ ctant_def->GetParallelMove(Instruction::GapPosition::START);
+ ParallelMove* inst1_end =
+ ctant_def->GetParallelMove(Instruction::GapPosition::END);
+ ParallelMove* last_start =
+ last->GetParallelMove(Instruction::GapPosition::START);
+ CHECK(inst1_start == nullptr || inst1_start->size() == 0);
+ CHECK(inst1_end == nullptr || inst1_end->size() == 0);
+ CHECK(last_start->size() == 2);
+ int redundants = 0;
+ int assignment = 0;
+ for (MoveOperands* move : *last_start) {
+ if (move->IsRedundant()) {
+ ++redundants;
+ } else {
+ ++assignment;
+ CHECK(move->destination().IsRegister());
+ CHECK(move->source().IsConstant());
+ }
+ }
+ CHECK_EQ(1, redundants);
+ CHECK_EQ(1, assignment);
+}
+
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/node-matchers-unittest.cc b/deps/v8/test/unittests/compiler/node-matchers-unittest.cc
index 57174cc56b..f0cc407445 100644
--- a/deps/v8/test/unittests/compiler/node-matchers-unittest.cc
+++ b/deps/v8/test/unittests/compiler/node-matchers-unittest.cc
@@ -38,7 +38,8 @@ void CheckBaseWithIndexAndDisplacement(Matcher* matcher, Node* index, int scale,
EXPECT_EQ(base, matcher->base());
EXPECT_EQ(displacement, matcher->displacement());
}
-};
+
+} // namespace
TEST_F(NodeMatcherTest, ScaledWithOffset32Matcher) {
diff --git a/deps/v8/test/unittests/compiler/node-test-utils.cc b/deps/v8/test/unittests/compiler/node-test-utils.cc
index 2ca1b78d09..34afc8822b 100644
--- a/deps/v8/test/unittests/compiler/node-test-utils.cc
+++ b/deps/v8/test/unittests/compiler/node-test-utils.cc
@@ -261,11 +261,34 @@ class IsControl3Matcher final : public NodeMatcher {
};
-class IsFinishMatcher final : public NodeMatcher {
+class IsBeginRegionMatcher final : public NodeMatcher {
public:
- IsFinishMatcher(const Matcher<Node*>& value_matcher,
- const Matcher<Node*>& effect_matcher)
- : NodeMatcher(IrOpcode::kFinish),
+ explicit IsBeginRegionMatcher(const Matcher<Node*>& effect_matcher)
+ : NodeMatcher(IrOpcode::kBeginRegion), effect_matcher_(effect_matcher) {}
+
+ void DescribeTo(std::ostream* os) const final {
+ NodeMatcher::DescribeTo(os);
+ *os << " whose effect (";
+ effect_matcher_.DescribeTo(os);
+ *os << ")";
+ }
+
+ bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
+ return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+ effect_matcher_, listener));
+ }
+
+ private:
+ const Matcher<Node*> effect_matcher_;
+};
+
+
+class IsFinishRegionMatcher final : public NodeMatcher {
+ public:
+ IsFinishRegionMatcher(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& effect_matcher)
+ : NodeMatcher(IrOpcode::kFinishRegion),
value_matcher_(value_matcher),
effect_matcher_(effect_matcher) {}
@@ -1501,14 +1524,14 @@ Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) {
}
-Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
- return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
+Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher) {
+ return MakeMatcher(new IsBeginRegionMatcher(effect_matcher));
}
-Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
- const Matcher<Node*>& effect_matcher) {
- return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
+Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& effect_matcher) {
+ return MakeMatcher(new IsFinishRegionMatcher(value_matcher, effect_matcher));
}
@@ -1989,14 +2012,17 @@ IS_BINOP_MATCHER(NumberShiftLeft)
IS_BINOP_MATCHER(NumberShiftRight)
IS_BINOP_MATCHER(NumberShiftRightLogical)
IS_BINOP_MATCHER(Word32And)
+IS_BINOP_MATCHER(Word32Or)
IS_BINOP_MATCHER(Word32Sar)
IS_BINOP_MATCHER(Word32Shl)
IS_BINOP_MATCHER(Word32Shr)
IS_BINOP_MATCHER(Word32Ror)
IS_BINOP_MATCHER(Word32Equal)
IS_BINOP_MATCHER(Word64And)
+IS_BINOP_MATCHER(Word64Or)
IS_BINOP_MATCHER(Word64Sar)
IS_BINOP_MATCHER(Word64Shl)
+IS_BINOP_MATCHER(Word64Shr)
IS_BINOP_MATCHER(Word64Equal)
IS_BINOP_MATCHER(Int32AddWithOverflow)
IS_BINOP_MATCHER(Int32Add)
@@ -2008,6 +2034,7 @@ IS_BINOP_MATCHER(Uint32LessThan)
IS_BINOP_MATCHER(Uint32LessThanOrEqual)
IS_BINOP_MATCHER(Int64Add)
IS_BINOP_MATCHER(Int64Sub)
+IS_BINOP_MATCHER(Int64Mul)
IS_BINOP_MATCHER(JSAdd)
IS_BINOP_MATCHER(Float32Max)
IS_BINOP_MATCHER(Float32Min)
@@ -2036,6 +2063,7 @@ IS_UNOP_MATCHER(ChangeUint32ToUint64)
IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
IS_UNOP_MATCHER(TruncateFloat64ToInt32)
IS_UNOP_MATCHER(TruncateInt64ToInt32)
+IS_UNOP_MATCHER(RoundInt64ToFloat64)
IS_UNOP_MATCHER(Float32Abs)
IS_UNOP_MATCHER(Float64Abs)
IS_UNOP_MATCHER(Float64Sqrt)
diff --git a/deps/v8/test/unittests/compiler/node-test-utils.h b/deps/v8/test/unittests/compiler/node-test-utils.h
index 7042d9943b..ffdad5812a 100644
--- a/deps/v8/test/unittests/compiler/node-test-utils.h
+++ b/deps/v8/test/unittests/compiler/node-test-utils.h
@@ -63,9 +63,9 @@ Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher,
Matcher<Node*> IsIfValue(const Matcher<int32_t>& value_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher);
-Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
- const Matcher<Node*>& effect_matcher);
+Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher);
+Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& effect_matcher);
Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
@@ -256,6 +256,8 @@ Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Or(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord32Shl(const Matcher<Node*>& lhs_matcher,
@@ -269,8 +271,12 @@ Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
Matcher<Node*> IsWord32Clz(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Or(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Shr(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
@@ -295,6 +301,8 @@ Matcher<Node*> IsInt64Add(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsInt64Sub(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt64Mul(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsJSAdd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher);
@@ -306,6 +314,7 @@ Matcher<Node*> IsChangeUint32ToUint64(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateFloat64ToFloat32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateFloat64ToInt32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsRoundInt64ToFloat64(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat32Max(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsFloat32Min(const Matcher<Node*>& lhs_matcher,
diff --git a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc
index 23a118b6ad..c5ff90f301 100644
--- a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc
@@ -41,7 +41,8 @@ bool AllocatedOperandMatches(
const AllocatedOperand& op,
const InstructionSequenceTest::TestOperand& test_op) {
return AreOperandsOfSameType(op, test_op) &&
- (op.index() == test_op.value_ ||
+ ((op.IsRegister() ? op.GetRegister().code() : op.index()) ==
+ test_op.value_ ||
test_op.value_ == InstructionSequenceTest::kNoValue);
}
@@ -75,7 +76,8 @@ bool IsParallelMovePresent(int instr_index, Instruction::GapPosition gap_pos,
}
return found_match;
}
-}
+
+} // namespace
class RegisterAllocatorTest : public InstructionSequenceTest {
@@ -722,7 +724,8 @@ class SlotConstraintTest : public RegisterAllocatorTest,
private:
typedef ::testing::WithParamInterface<::testing::tuple<ParameterType, int>> B;
};
-}
+
+} // namespace
#if GTEST_HAS_COMBINE
diff --git a/deps/v8/test/unittests/compiler/scheduler-unittest.cc b/deps/v8/test/unittests/compiler/scheduler-unittest.cc
index 45d555d7a1..af43b2efff 100644
--- a/deps/v8/test/unittests/compiler/scheduler-unittest.cc
+++ b/deps/v8/test/unittests/compiler/scheduler-unittest.cc
@@ -1124,13 +1124,11 @@ TARGET_TEST_F(SchedulerTest, Terminate) {
Node* loop = graph()->NewNode(common()->Loop(2), start, start);
loop->ReplaceInput(1, loop); // self loop, NTL.
- Node* effect = graph()->NewNode(common()->EffectPhi(1), start, loop);
+ Node* effect = graph()->NewNode(common()->EffectPhi(2), start, start, loop);
+ effect->ReplaceInput(1, effect); // self loop.
Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop);
- effect->ReplaceInput(1, terminate);
-
Node* end = graph()->NewNode(common()->End(1), terminate);
-
graph()->SetEnd(end);
Schedule* schedule = ComputeAndVerifySchedule(6);
diff --git a/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
index 79e530f228..f571898107 100644
--- a/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
@@ -30,7 +30,8 @@ class SimplifiedOperatorReducerTest : public TypedGraphTest {
Reduction Reduce(Node* node) {
MachineOperatorBuilder machine(zone());
JSOperatorBuilder javascript(zone());
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(),
+ &machine);
SimplifiedOperatorReducer reducer(&jsgraph);
return reducer.Reduce(node);
}
diff --git a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
index 7e4329ea3a..b09840710a 100644
--- a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
@@ -48,6 +48,12 @@ const PureOperator kPureOperators[] = {
PURE(NumberMultiply, Operator::kCommutative, 2),
PURE(NumberDivide, Operator::kNoProperties, 2),
PURE(NumberModulus, Operator::kNoProperties, 2),
+ PURE(NumberBitwiseOr, Operator::kCommutative, 2),
+ PURE(NumberBitwiseXor, Operator::kCommutative, 2),
+ PURE(NumberBitwiseAnd, Operator::kCommutative, 2),
+ PURE(NumberShiftLeft, Operator::kNoProperties, 2),
+ PURE(NumberShiftRight, Operator::kNoProperties, 2),
+ PURE(NumberShiftRightLogical, Operator::kNoProperties, 2),
PURE(NumberToInt32, Operator::kNoProperties, 1),
PURE(NumberToUint32, Operator::kNoProperties, 1),
PURE(PlainPrimitiveToNumber, Operator::kNoProperties, 1),
diff --git a/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc b/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc
index e6f4701598..311b90a8d1 100644
--- a/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc
+++ b/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc
@@ -95,7 +95,8 @@ TEST_F(StateValuesIteratorTest, TreeFromVector) {
TRACED_FOREACH(int, count, sizes) {
JSOperatorBuilder javascript(zone());
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
+ &machine);
// Generate the input vector.
NodeVector inputs(zone());
@@ -124,7 +125,8 @@ TEST_F(StateValuesIteratorTest, BuildTreeIdentical) {
TRACED_FOREACH(int, count, sizes) {
JSOperatorBuilder javascript(zone());
MachineOperatorBuilder machine(zone());
- JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
+ JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
+ &machine);
// Generate the input vector.
NodeVector inputs(zone());
diff --git a/deps/v8/test/unittests/compiler/typer-unittest.cc b/deps/v8/test/unittests/compiler/typer-unittest.cc
index 7113bf2eec..4a462cef10 100644
--- a/deps/v8/test/unittests/compiler/typer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/typer-unittest.cc
@@ -11,9 +11,9 @@
#include "test/cctest/types-fuzz.h"
#include "test/unittests/compiler/graph-unittest.h"
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
+namespace v8 {
+namespace internal {
+namespace compiler {
// TODO(titzer): generate a large set of deterministic inputs for these tests.
class TyperTest : public TypedGraphTest {
@@ -417,3 +417,7 @@ TEST_F(TyperTest, TypeRegressInt32Constant) {
EXPECT_TRUE(type->Is(NewRange(i, i)));
}
}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc b/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc
index 0b46b32306..f28087c54c 100644
--- a/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc
@@ -124,7 +124,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
const MemoryAccess memacc = GetParam();
StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
- m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+ m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ kNoWriteBarrier);
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());