OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compilation-dependencies.h" | 5 #include "src/compilation-dependencies.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/js-typed-lowering.h" | 7 #include "src/compiler/js-typed-lowering.h" |
8 #include "src/compiler/machine-operator.h" | 8 #include "src/compiler/machine-operator.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
11 #include "src/compiler/operator-properties.h" | 11 #include "src/compiler/operator-properties.h" |
12 #include "src/compiler/simplified-operator.h" | 12 #include "src/compiler/simplified-operator.h" |
13 #include "src/compiler/typer.h" | 13 #include "src/compiler/typer.h" |
14 #include "test/cctest/cctest.h" | 14 #include "test/cctest/cctest.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace compiler { | 18 namespace compiler { |
19 | 19 |
20 class JSTypedLoweringTester : public HandleAndZoneScope { | 20 class JSTypedLoweringTester : public HandleAndZoneScope { |
21 public: | 21 public: |
22 explicit JSTypedLoweringTester(int num_parameters = 0) | 22 JSTypedLoweringTester( |
| 23 int num_parameters = 0, |
| 24 JSTypedLowering::Flags flags = JSTypedLowering::kDeoptimizationEnabled) |
23 : isolate(main_isolate()), | 25 : isolate(main_isolate()), |
24 binop(NULL), | 26 binop(NULL), |
25 unop(NULL), | 27 unop(NULL), |
26 javascript(main_zone()), | 28 javascript(main_zone()), |
27 machine(main_zone()), | 29 machine(main_zone()), |
28 simplified(main_zone()), | 30 simplified(main_zone()), |
29 common(main_zone()), | 31 common(main_zone()), |
30 deps(main_isolate(), main_zone()), | 32 deps(main_isolate(), main_zone()), |
31 graph(main_zone()), | 33 graph(main_zone()), |
32 typer(main_isolate(), &graph), | 34 typer(main_isolate(), &graph), |
33 context_node(NULL) { | 35 context_node(NULL), |
| 36 flags(flags) { |
34 graph.SetStart(graph.NewNode(common.Start(num_parameters))); | 37 graph.SetStart(graph.NewNode(common.Start(num_parameters))); |
35 graph.SetEnd(graph.NewNode(common.End(1), graph.start())); | 38 graph.SetEnd(graph.NewNode(common.End(1), graph.start())); |
36 typer.Run(); | 39 typer.Run(); |
37 } | 40 } |
38 | 41 |
39 Isolate* isolate; | 42 Isolate* isolate; |
40 const Operator* binop; | 43 const Operator* binop; |
41 const Operator* unop; | 44 const Operator* unop; |
42 JSOperatorBuilder javascript; | 45 JSOperatorBuilder javascript; |
43 MachineOperatorBuilder machine; | 46 MachineOperatorBuilder machine; |
44 SimplifiedOperatorBuilder simplified; | 47 SimplifiedOperatorBuilder simplified; |
45 CommonOperatorBuilder common; | 48 CommonOperatorBuilder common; |
46 CompilationDependencies deps; | 49 CompilationDependencies deps; |
47 Graph graph; | 50 Graph graph; |
48 Typer typer; | 51 Typer typer; |
49 Node* context_node; | 52 Node* context_node; |
| 53 JSTypedLowering::Flags flags; |
50 BinaryOperationHints const binop_hints = BinaryOperationHints::Any(); | 54 BinaryOperationHints const binop_hints = BinaryOperationHints::Any(); |
51 CompareOperationHints const compare_hints = CompareOperationHints::Any(); | 55 CompareOperationHints const compare_hints = CompareOperationHints::Any(); |
52 | 56 |
53 Node* Parameter(Type* t, int32_t index = 0) { | 57 Node* Parameter(Type* t, int32_t index = 0) { |
54 Node* n = graph.NewNode(common.Parameter(index), graph.start()); | 58 Node* n = graph.NewNode(common.Parameter(index), graph.start()); |
55 NodeProperties::SetType(n, t); | 59 NodeProperties::SetType(n, t); |
56 return n; | 60 return n; |
57 } | 61 } |
58 | 62 |
59 Node* UndefinedConstant() { | 63 Node* UndefinedConstant() { |
(...skipping 16 matching lines...) Expand all Loading... |
76 parameters, locals, stack, context, UndefinedConstant(), graph.start()); | 80 parameters, locals, stack, context, UndefinedConstant(), graph.start()); |
77 | 81 |
78 return state_node; | 82 return state_node; |
79 } | 83 } |
80 | 84 |
81 Node* reduce(Node* node) { | 85 Node* reduce(Node* node) { |
82 JSGraph jsgraph(main_isolate(), &graph, &common, &javascript, &simplified, | 86 JSGraph jsgraph(main_isolate(), &graph, &common, &javascript, &simplified, |
83 &machine); | 87 &machine); |
84 // TODO(titzer): mock the GraphReducer here for better unit testing. | 88 // TODO(titzer): mock the GraphReducer here for better unit testing. |
85 GraphReducer graph_reducer(main_zone(), &graph); | 89 GraphReducer graph_reducer(main_zone(), &graph); |
86 JSTypedLowering reducer(&graph_reducer, &deps, | 90 JSTypedLowering reducer(&graph_reducer, &deps, flags, &jsgraph, |
87 JSTypedLowering::kDeoptimizationEnabled, &jsgraph, | |
88 main_zone()); | 91 main_zone()); |
89 Reduction reduction = reducer.Reduce(node); | 92 Reduction reduction = reducer.Reduce(node); |
90 if (reduction.Changed()) return reduction.replacement(); | 93 if (reduction.Changed()) return reduction.replacement(); |
91 return node; | 94 return node; |
92 } | 95 } |
93 | 96 |
94 Node* start() { return graph.start(); } | 97 Node* start() { return graph.start(); } |
95 | 98 |
96 Node* context() { | 99 Node* context() { |
97 if (context_node == NULL) { | 100 if (context_node == NULL) { |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 } | 745 } |
743 } | 746 } |
744 | 747 |
745 CHECK(!effect_use); // should have done all cases above. | 748 CHECK(!effect_use); // should have done all cases above. |
746 } | 749 } |
747 | 750 |
748 | 751 |
749 // Helper class for testing the reduction of a single binop. | 752 // Helper class for testing the reduction of a single binop. |
750 class BinopEffectsTester { | 753 class BinopEffectsTester { |
751 public: | 754 public: |
752 explicit BinopEffectsTester(const Operator* op, Type* t0, Type* t1) | 755 BinopEffectsTester( |
753 : R(), | 756 const Operator* op, Type* t0, Type* t1, |
| 757 JSTypedLowering::Flags flags = JSTypedLowering::kDeoptimizationEnabled) |
| 758 : R(0, flags), |
754 p0(R.Parameter(t0, 0)), | 759 p0(R.Parameter(t0, 0)), |
755 p1(R.Parameter(t1, 1)), | 760 p1(R.Parameter(t1, 1)), |
756 binop(R.Binop(op, p0, p1)), | 761 binop(R.Binop(op, p0, p1)), |
757 effect_use(R.graph.NewNode(R.common.EffectPhi(1), binop, R.start())) { | 762 effect_use(R.graph.NewNode(R.common.EffectPhi(1), binop, R.start())) { |
758 // Effects should be ordered start -> binop -> effect_use | 763 // Effects should be ordered start -> binop -> effect_use |
759 R.CheckEffectInput(R.start(), binop); | 764 R.CheckEffectInput(R.start(), binop); |
760 R.CheckEffectInput(binop, effect_use); | 765 R.CheckEffectInput(binop, effect_use); |
761 result = R.reduce(binop); | 766 result = R.reduce(binop); |
762 } | 767 } |
763 | 768 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 TEST(OrderNumberBinopEffects1) { | 928 TEST(OrderNumberBinopEffects1) { |
924 JSTypedLoweringTester R; | 929 JSTypedLoweringTester R; |
925 | 930 |
926 const Operator* ops[] = { | 931 const Operator* ops[] = { |
927 R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), | 932 R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), |
928 R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), | 933 R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), |
929 R.javascript.Divide(R.binop_hints), R.simplified.NumberDivide(), | 934 R.javascript.Divide(R.binop_hints), R.simplified.NumberDivide(), |
930 }; | 935 }; |
931 | 936 |
932 for (size_t j = 0; j < arraysize(ops); j += 2) { | 937 for (size_t j = 0; j < arraysize(ops); j += 2) { |
933 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol()); | 938 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol(), |
| 939 JSTypedLowering::kNoFlags); |
934 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 940 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
935 | 941 |
936 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 942 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
937 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 943 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
938 | 944 |
939 CHECK_EQ(B.p0, i0->InputAt(0)); | 945 CHECK_EQ(B.p0, i0->InputAt(0)); |
940 CHECK_EQ(B.p1, i1->InputAt(0)); | 946 CHECK_EQ(B.p1, i1->InputAt(0)); |
941 | 947 |
942 // Effects should be ordered start -> i0 -> i1 -> effect_use | 948 // Effects should be ordered start -> i0 -> i1 -> effect_use |
943 B.CheckEffectOrdering(i0, i1); | 949 B.CheckEffectOrdering(i0, i1); |
944 } | 950 } |
945 } | 951 } |
946 | 952 |
947 | 953 |
948 TEST(OrderNumberBinopEffects2) { | 954 TEST(OrderNumberBinopEffects2) { |
949 JSTypedLoweringTester R; | 955 JSTypedLoweringTester R; |
950 | 956 |
951 const Operator* ops[] = { | 957 const Operator* ops[] = { |
952 R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), | 958 R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), |
953 R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), | 959 R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), |
954 R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), | 960 R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), |
955 R.javascript.Divide(R.binop_hints), R.simplified.NumberDivide(), | 961 R.javascript.Divide(R.binop_hints), R.simplified.NumberDivide(), |
956 }; | 962 }; |
957 | 963 |
958 for (size_t j = 0; j < arraysize(ops); j += 2) { | 964 for (size_t j = 0; j < arraysize(ops); j += 2) { |
959 BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol()); | 965 BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol(), |
| 966 JSTypedLowering::kNoFlags); |
960 | 967 |
961 Node* i0 = B.CheckNoOp(0); | 968 Node* i0 = B.CheckNoOp(0); |
962 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 969 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
963 | 970 |
964 CHECK_EQ(B.p0, i0); | 971 CHECK_EQ(B.p0, i0); |
965 CHECK_EQ(B.p1, i1->InputAt(0)); | 972 CHECK_EQ(B.p1, i1->InputAt(0)); |
966 | 973 |
967 // Effects should be ordered start -> i1 -> effect_use | 974 // Effects should be ordered start -> i1 -> effect_use |
968 B.CheckEffectOrdering(i1); | 975 B.CheckEffectOrdering(i1); |
969 } | 976 } |
970 | 977 |
971 for (size_t j = 0; j < arraysize(ops); j += 2) { | 978 for (size_t j = 0; j < arraysize(ops); j += 2) { |
972 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number()); | 979 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number(), |
| 980 JSTypedLowering::kNoFlags); |
973 | 981 |
974 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 982 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
975 Node* i1 = B.CheckNoOp(1); | 983 Node* i1 = B.CheckNoOp(1); |
976 | 984 |
977 CHECK_EQ(B.p0, i0->InputAt(0)); | 985 CHECK_EQ(B.p0, i0->InputAt(0)); |
978 CHECK_EQ(B.p1, i1); | 986 CHECK_EQ(B.p1, i1); |
979 | 987 |
980 // Effects should be ordered start -> i0 -> effect_use | 988 // Effects should be ordered start -> i0 -> effect_use |
981 B.CheckEffectOrdering(i0); | 989 B.CheckEffectOrdering(i0); |
982 } | 990 } |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 CHECK_EQ(p1, r->InputAt(1)); | 1234 CHECK_EQ(p1, r->InputAt(1)); |
1227 } | 1235 } |
1228 } | 1236 } |
1229 } | 1237 } |
1230 } | 1238 } |
1231 } | 1239 } |
1232 | 1240 |
1233 } // namespace compiler | 1241 } // namespace compiler |
1234 } // namespace internal | 1242 } // namespace internal |
1235 } // namespace v8 | 1243 } // namespace v8 |
OLD | NEW |