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 // TODO(jochen): Remove this after the setting is turned on globally. | 5 // TODO(jochen): Remove this after the setting is turned on globally. |
6 #define V8_IMMINENT_DEPRECATION_WARNINGS | 6 #define V8_IMMINENT_DEPRECATION_WARNINGS |
7 | 7 |
8 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/js-typed-lowering.h" | 10 #include "src/compiler/js-typed-lowering.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 const Operator* binop; | 56 const Operator* binop; |
57 const Operator* unop; | 57 const Operator* unop; |
58 JSOperatorBuilder javascript; | 58 JSOperatorBuilder javascript; |
59 MachineOperatorBuilder machine; | 59 MachineOperatorBuilder machine; |
60 SimplifiedOperatorBuilder simplified; | 60 SimplifiedOperatorBuilder simplified; |
61 CommonOperatorBuilder common; | 61 CommonOperatorBuilder common; |
62 CompilationDependencies deps; | 62 CompilationDependencies deps; |
63 Graph graph; | 63 Graph graph; |
64 Typer typer; | 64 Typer typer; |
65 Node* context_node; | 65 Node* context_node; |
| 66 BinaryOperationHints const hints = BinaryOperationHints::Any(); |
66 | 67 |
67 Node* Parameter(Type* t, int32_t index = 0) { | 68 Node* Parameter(Type* t, int32_t index = 0) { |
68 Node* n = graph.NewNode(common.Parameter(index), graph.start()); | 69 Node* n = graph.NewNode(common.Parameter(index), graph.start()); |
69 NodeProperties::SetType(n, t); | 70 NodeProperties::SetType(n, t); |
70 return n; | 71 return n; |
71 } | 72 } |
72 | 73 |
73 Node* UndefinedConstant() { | 74 Node* UndefinedConstant() { |
74 Handle<HeapObject> value = isolate->factory()->undefined_value(); | 75 Handle<HeapObject> value = isolate->factory()->undefined_value(); |
75 return graph.NewNode(common.HeapConstant(value)); | 76 return graph.NewNode(common.HeapConstant(value)); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 } | 262 } |
262 } | 263 } |
263 #endif | 264 #endif |
264 | 265 |
265 | 266 |
266 TEST_WITH_STRONG(AddNumber1) { | 267 TEST_WITH_STRONG(AddNumber1) { |
267 JSTypedLoweringTester R; | 268 JSTypedLoweringTester R; |
268 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { | 269 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { |
269 Node* p0 = R.Parameter(kNumberTypes[i], 0); | 270 Node* p0 = R.Parameter(kNumberTypes[i], 0); |
270 Node* p1 = R.Parameter(kNumberTypes[i], 1); | 271 Node* p1 = R.Parameter(kNumberTypes[i], 1); |
271 Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1); | 272 Node* add = R.Binop( |
| 273 R.javascript.Add(language_mode, BinaryOperationHints::Any()), p0, p1); |
272 Node* r = R.reduce(add); | 274 Node* r = R.reduce(add); |
273 | 275 |
274 R.CheckBinop(IrOpcode::kNumberAdd, r); | 276 R.CheckBinop(IrOpcode::kNumberAdd, r); |
275 CHECK_EQ(p0, r->InputAt(0)); | 277 CHECK_EQ(p0, r->InputAt(0)); |
276 CHECK_EQ(p1, r->InputAt(1)); | 278 CHECK_EQ(p1, r->InputAt(1)); |
277 } | 279 } |
278 } | 280 } |
279 | 281 |
280 | 282 |
281 TEST_WITH_STRONG(NumberBinops) { | 283 TEST_WITH_STRONG(NumberBinops) { |
282 JSTypedLoweringTester R; | 284 JSTypedLoweringTester R; |
283 const Operator* ops[] = { | 285 const Operator* ops[] = { |
284 R.javascript.Add(language_mode), R.simplified.NumberAdd(), | 286 R.javascript.Add(language_mode, R.hints), |
285 R.javascript.Subtract(language_mode), R.simplified.NumberSubtract(), | 287 R.simplified.NumberAdd(), |
286 R.javascript.Multiply(language_mode), R.simplified.NumberMultiply(), | 288 R.javascript.Subtract(language_mode, R.hints), |
287 R.javascript.Divide(language_mode), R.simplified.NumberDivide(), | 289 R.simplified.NumberSubtract(), |
288 R.javascript.Modulus(language_mode), R.simplified.NumberModulus(), | 290 R.javascript.Multiply(language_mode, R.hints), |
| 291 R.simplified.NumberMultiply(), |
| 292 R.javascript.Divide(language_mode, R.hints), |
| 293 R.simplified.NumberDivide(), |
| 294 R.javascript.Modulus(language_mode, R.hints), |
| 295 R.simplified.NumberModulus(), |
289 }; | 296 }; |
290 | 297 |
291 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { | 298 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { |
292 Node* p0 = R.Parameter(kNumberTypes[i], 0); | 299 Node* p0 = R.Parameter(kNumberTypes[i], 0); |
293 | 300 |
294 for (size_t j = 0; j < arraysize(kNumberTypes); ++j) { | 301 for (size_t j = 0; j < arraysize(kNumberTypes); ++j) { |
295 Node* p1 = R.Parameter(kNumberTypes[j], 1); | 302 Node* p1 = R.Parameter(kNumberTypes[j], 1); |
296 | 303 |
297 for (size_t k = 0; k < arraysize(ops); k += 2) { | 304 for (size_t k = 0; k < arraysize(ops); k += 2) { |
298 Node* add = R.Binop(ops[k], p0, p1); | 305 Node* add = R.Binop(ops[k], p0, p1); |
(...skipping 22 matching lines...) Expand all Loading... |
321 } | 328 } |
322 } | 329 } |
323 | 330 |
324 | 331 |
325 // A helper class for testing lowering of bitwise shift operators. | 332 // A helper class for testing lowering of bitwise shift operators. |
326 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester { | 333 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester { |
327 public: | 334 public: |
328 explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode) | 335 explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode) |
329 : JSTypedLoweringTester(), language_mode_(language_mode) { | 336 : JSTypedLoweringTester(), language_mode_(language_mode) { |
330 int i = 0; | 337 int i = 0; |
331 set(i++, javascript.ShiftLeft(language_mode_), true); | 338 set(i++, javascript.ShiftLeft(language_mode_, hints), true); |
332 set(i++, simplified.NumberShiftLeft(), false); | 339 set(i++, simplified.NumberShiftLeft(), false); |
333 set(i++, javascript.ShiftRight(language_mode_), true); | 340 set(i++, javascript.ShiftRight(language_mode_, hints), true); |
334 set(i++, simplified.NumberShiftRight(), false); | 341 set(i++, simplified.NumberShiftRight(), false); |
335 set(i++, javascript.ShiftRightLogical(language_mode_), false); | 342 set(i++, javascript.ShiftRightLogical(language_mode_, hints), false); |
336 set(i++, simplified.NumberShiftRightLogical(), false); | 343 set(i++, simplified.NumberShiftRightLogical(), false); |
337 } | 344 } |
338 static const int kNumberOps = 6; | 345 static const int kNumberOps = 6; |
339 const Operator* ops[kNumberOps]; | 346 const Operator* ops[kNumberOps]; |
340 bool signedness[kNumberOps]; | 347 bool signedness[kNumberOps]; |
341 | 348 |
342 private: | 349 private: |
343 LanguageMode language_mode_; | 350 LanguageMode language_mode_; |
344 void set(int idx, const Operator* op, bool s) { | 351 void set(int idx, const Operator* op, bool s) { |
345 ops[idx] = op; | 352 ops[idx] = op; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 } | 386 } |
380 } | 387 } |
381 | 388 |
382 | 389 |
383 // A helper class for testing lowering of bitwise operators. | 390 // A helper class for testing lowering of bitwise operators. |
384 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester { | 391 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester { |
385 public: | 392 public: |
386 explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode) | 393 explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode) |
387 : JSTypedLoweringTester(), language_mode_(language_mode) { | 394 : JSTypedLoweringTester(), language_mode_(language_mode) { |
388 int i = 0; | 395 int i = 0; |
389 set(i++, javascript.BitwiseOr(language_mode_), true); | 396 set(i++, javascript.BitwiseOr(language_mode_, hints), true); |
390 set(i++, simplified.NumberBitwiseOr(), true); | 397 set(i++, simplified.NumberBitwiseOr(), true); |
391 set(i++, javascript.BitwiseXor(language_mode_), true); | 398 set(i++, javascript.BitwiseXor(language_mode_, hints), true); |
392 set(i++, simplified.NumberBitwiseXor(), true); | 399 set(i++, simplified.NumberBitwiseXor(), true); |
393 set(i++, javascript.BitwiseAnd(language_mode_), true); | 400 set(i++, javascript.BitwiseAnd(language_mode_, hints), true); |
394 set(i++, simplified.NumberBitwiseAnd(), true); | 401 set(i++, simplified.NumberBitwiseAnd(), true); |
395 } | 402 } |
396 static const int kNumberOps = 6; | 403 static const int kNumberOps = 6; |
397 const Operator* ops[kNumberOps]; | 404 const Operator* ops[kNumberOps]; |
398 bool signedness[kNumberOps]; | 405 bool signedness[kNumberOps]; |
399 | 406 |
400 private: | 407 private: |
401 LanguageMode language_mode_; | 408 LanguageMode language_mode_; |
402 void set(int idx, const Operator* op, bool s) { | 409 void set(int idx, const Operator* op, bool s) { |
403 ops[idx] = op; | 410 ops[idx] = op; |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 break; | 740 break; |
734 case 1: | 741 case 1: |
735 DCHECK(OperatorProperties::GetFrameStateInputCount( | 742 DCHECK(OperatorProperties::GetFrameStateInputCount( |
736 R.javascript.ToNumber()) == 1); | 743 R.javascript.ToNumber()) == 1); |
737 effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(), | 744 effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(), |
738 frame_state, ton, R.start()); | 745 frame_state, ton, R.start()); |
739 break; | 746 break; |
740 case 2: | 747 case 2: |
741 effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start()); | 748 effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start()); |
742 case 3: | 749 case 3: |
743 effect_use = R.graph.NewNode(R.javascript.Add(language_mode), ton, ton, | 750 effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints), |
744 R.context(), frame_state, frame_state, ton, | 751 ton, ton, R.context(), frame_state, |
745 R.start()); | 752 frame_state, ton, R.start()); |
746 break; | 753 break; |
747 case 4: | 754 case 4: |
748 effect_use = R.graph.NewNode(R.javascript.Add(language_mode), p0, p0, | 755 effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints), |
749 R.context(), frame_state, frame_state, ton, | 756 p0, p0, R.context(), frame_state, |
750 R.start()); | 757 frame_state, ton, R.start()); |
751 break; | 758 break; |
752 case 5: | 759 case 5: |
753 effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start()); | 760 effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start()); |
754 break; | 761 break; |
755 case 6: | 762 case 6: |
756 effect_use = R.graph.NewNode(R.common.Return(), ton, ton, R.start()); | 763 effect_use = R.graph.NewNode(R.common.Return(), ton, ton, R.start()); |
757 } | 764 } |
758 | 765 |
759 R.CheckEffectInput(R.start(), ton); | 766 R.CheckEffectInput(R.start(), ton); |
760 if (effect_use != NULL) R.CheckEffectInput(ton, effect_use); | 767 if (effect_use != NULL) R.CheckEffectInput(ton, effect_use); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 | 910 |
904 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kStringEqual); | 911 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kStringEqual); |
905 CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual); | 912 CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual); |
906 } | 913 } |
907 | 914 |
908 | 915 |
909 TEST_WITH_STRONG(RemovePureNumberBinopEffects) { | 916 TEST_WITH_STRONG(RemovePureNumberBinopEffects) { |
910 JSTypedLoweringTester R; | 917 JSTypedLoweringTester R; |
911 | 918 |
912 const Operator* ops[] = { | 919 const Operator* ops[] = { |
913 R.javascript.Equal(), R.simplified.NumberEqual(), | 920 R.javascript.Equal(), |
914 R.javascript.Add(language_mode), R.simplified.NumberAdd(), | 921 R.simplified.NumberEqual(), |
915 R.javascript.Subtract(language_mode), R.simplified.NumberSubtract(), | 922 R.javascript.Add(language_mode, R.hints), |
916 R.javascript.Multiply(language_mode), R.simplified.NumberMultiply(), | 923 R.simplified.NumberAdd(), |
917 R.javascript.Divide(language_mode), R.simplified.NumberDivide(), | 924 R.javascript.Subtract(language_mode, R.hints), |
918 R.javascript.Modulus(language_mode), R.simplified.NumberModulus(), | 925 R.simplified.NumberSubtract(), |
919 R.javascript.LessThan(language_mode), R.simplified.NumberLessThan(), | 926 R.javascript.Multiply(language_mode, R.hints), |
| 927 R.simplified.NumberMultiply(), |
| 928 R.javascript.Divide(language_mode, R.hints), |
| 929 R.simplified.NumberDivide(), |
| 930 R.javascript.Modulus(language_mode, R.hints), |
| 931 R.simplified.NumberModulus(), |
| 932 R.javascript.LessThan(language_mode), |
| 933 R.simplified.NumberLessThan(), |
920 R.javascript.LessThanOrEqual(language_mode), | 934 R.javascript.LessThanOrEqual(language_mode), |
921 R.simplified.NumberLessThanOrEqual(), | 935 R.simplified.NumberLessThanOrEqual(), |
922 }; | 936 }; |
923 | 937 |
924 for (size_t j = 0; j < arraysize(ops); j += 2) { | 938 for (size_t j = 0; j < arraysize(ops); j += 2) { |
925 BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); | 939 BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); |
926 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 940 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
927 | 941 |
928 B.R.CheckBinop(B.result->opcode(), B.result); | 942 B.R.CheckBinop(B.result->opcode(), B.result); |
929 | 943 |
930 B.CheckNoOp(0); | 944 B.CheckNoOp(0); |
931 B.CheckNoOp(1); | 945 B.CheckNoOp(1); |
932 | 946 |
933 B.CheckEffectsRemoved(); | 947 B.CheckEffectsRemoved(); |
934 } | 948 } |
935 } | 949 } |
936 | 950 |
937 | 951 |
938 TEST(OrderNumberBinopEffects1) { | 952 TEST(OrderNumberBinopEffects1) { |
939 JSTypedLoweringTester R; | 953 JSTypedLoweringTester R; |
940 | 954 |
941 const Operator* ops[] = { | 955 const Operator* ops[] = { |
942 R.javascript.Subtract(LanguageMode::SLOPPY), | 956 R.javascript.Subtract(LanguageMode::SLOPPY, R.hints), |
943 R.simplified.NumberSubtract(), | 957 R.simplified.NumberSubtract(), |
944 R.javascript.Multiply(LanguageMode::SLOPPY), | 958 R.javascript.Multiply(LanguageMode::SLOPPY, R.hints), |
945 R.simplified.NumberMultiply(), | 959 R.simplified.NumberMultiply(), |
946 R.javascript.Divide(LanguageMode::SLOPPY), | 960 R.javascript.Divide(LanguageMode::SLOPPY, R.hints), |
947 R.simplified.NumberDivide(), | 961 R.simplified.NumberDivide(), |
948 }; | 962 }; |
949 | 963 |
950 for (size_t j = 0; j < arraysize(ops); j += 2) { | 964 for (size_t j = 0; j < arraysize(ops); j += 2) { |
951 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol()); | 965 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol()); |
952 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 966 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
953 | 967 |
954 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 968 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
955 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 969 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
956 | 970 |
957 CHECK_EQ(B.p0, i0->InputAt(0)); | 971 CHECK_EQ(B.p0, i0->InputAt(0)); |
958 CHECK_EQ(B.p1, i1->InputAt(0)); | 972 CHECK_EQ(B.p1, i1->InputAt(0)); |
959 | 973 |
960 // Effects should be ordered start -> i0 -> i1 -> effect_use | 974 // Effects should be ordered start -> i0 -> i1 -> effect_use |
961 B.CheckEffectOrdering(i0, i1); | 975 B.CheckEffectOrdering(i0, i1); |
962 } | 976 } |
963 } | 977 } |
964 | 978 |
965 | 979 |
966 TEST(OrderNumberBinopEffects2) { | 980 TEST(OrderNumberBinopEffects2) { |
967 JSTypedLoweringTester R; | 981 JSTypedLoweringTester R; |
968 | 982 |
969 const Operator* ops[] = { | 983 const Operator* ops[] = { |
970 R.javascript.Add(LanguageMode::SLOPPY), | 984 R.javascript.Add(LanguageMode::SLOPPY, R.hints), |
971 R.simplified.NumberAdd(), | 985 R.simplified.NumberAdd(), |
972 R.javascript.Subtract(LanguageMode::SLOPPY), | 986 R.javascript.Subtract(LanguageMode::SLOPPY, R.hints), |
973 R.simplified.NumberSubtract(), | 987 R.simplified.NumberSubtract(), |
974 R.javascript.Multiply(LanguageMode::SLOPPY), | 988 R.javascript.Multiply(LanguageMode::SLOPPY, R.hints), |
975 R.simplified.NumberMultiply(), | 989 R.simplified.NumberMultiply(), |
976 R.javascript.Divide(LanguageMode::SLOPPY), | 990 R.javascript.Divide(LanguageMode::SLOPPY, R.hints), |
977 R.simplified.NumberDivide(), | 991 R.simplified.NumberDivide(), |
978 }; | 992 }; |
979 | 993 |
980 for (size_t j = 0; j < arraysize(ops); j += 2) { | 994 for (size_t j = 0; j < arraysize(ops); j += 2) { |
981 BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol()); | 995 BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol()); |
982 | 996 |
983 Node* i0 = B.CheckNoOp(0); | 997 Node* i0 = B.CheckNoOp(0); |
984 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 998 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
985 | 999 |
986 CHECK_EQ(B.p0, i0); | 1000 CHECK_EQ(B.p0, i0); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 CHECK_EQ(p1, r->InputAt(1)); | 1279 CHECK_EQ(p1, r->InputAt(1)); |
1266 } | 1280 } |
1267 } | 1281 } |
1268 } | 1282 } |
1269 } | 1283 } |
1270 } | 1284 } |
1271 | 1285 |
1272 } // namespace compiler | 1286 } // namespace compiler |
1273 } // namespace internal | 1287 } // namespace internal |
1274 } // namespace v8 | 1288 } // namespace v8 |
OLD | NEW |