| 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 |