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