| 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/compiler/js-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
| 6 | 6 |
| 7 #include "src/ast/modules.h" | 7 #include "src/ast/modules.h" |
| 8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/compilation-dependencies.h" | 10 #include "src/compilation-dependencies.h" |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } else if (r.IsReceiverCompareOperation()) { | 982 } else if (r.IsReceiverCompareOperation()) { |
| 983 r.CheckInputsToReceiver(); | 983 r.CheckInputsToReceiver(); |
| 984 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 984 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
| 985 } else if (r.IsStringCompareOperation()) { | 985 } else if (r.IsStringCompareOperation()) { |
| 986 r.CheckInputsToString(); | 986 r.CheckInputsToString(); |
| 987 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 987 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); |
| 988 } | 988 } |
| 989 return NoChange(); | 989 return NoChange(); |
| 990 } | 990 } |
| 991 | 991 |
| 992 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { | 992 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node) { |
| 993 JSBinopReduction r(this, node); | 993 JSBinopReduction r(this, node); |
| 994 if (r.left() == r.right()) { | 994 if (r.left() == r.right()) { |
| 995 // x === x is always true if x != NaN | 995 // x === x is always true if x != NaN |
| 996 Node* replacement = graph()->NewNode(simplified()->ObjectIsNaN(), r.left()); | 996 Node* replacement = graph()->NewNode( |
| 997 if (!invert) { | 997 simplified()->BooleanNot(), |
| 998 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); | 998 graph()->NewNode(simplified()->ObjectIsNaN(), r.left())); |
| 999 } | |
| 1000 ReplaceWithValue(node, replacement); | 999 ReplaceWithValue(node, replacement); |
| 1001 return Replace(replacement); | 1000 return Replace(replacement); |
| 1002 } | 1001 } |
| 1003 if (r.OneInputCannotBe(Type::NumberOrString())) { | 1002 if (r.OneInputCannotBe(Type::NumberOrString())) { |
| 1004 // For values with canonical representation (i.e. neither String, nor | 1003 // For values with canonical representation (i.e. neither String, nor |
| 1005 // Number) an empty type intersection means the values cannot be strictly | 1004 // Number) an empty type intersection means the values cannot be strictly |
| 1006 // equal. | 1005 // equal. |
| 1007 if (!r.left_type()->Maybe(r.right_type())) { | 1006 if (!r.left_type()->Maybe(r.right_type())) { |
| 1008 Node* replacement = jsgraph()->BooleanConstant(invert); | 1007 Node* replacement = jsgraph()->FalseConstant(); |
| 1009 ReplaceWithValue(node, replacement); | 1008 ReplaceWithValue(node, replacement); |
| 1010 return Replace(replacement); | 1009 return Replace(replacement); |
| 1011 } | 1010 } |
| 1012 } | 1011 } |
| 1013 | 1012 |
| 1014 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); | 1013 Reduction const reduction = ReduceJSEqualTypeOf(node, false); |
| 1015 if (reduction.Changed()) return reduction; | 1014 if (reduction.Changed()) return reduction; |
| 1016 | 1015 |
| 1017 if (r.BothInputsAre(Type::Unique())) { | 1016 if (r.BothInputsAre(Type::Unique())) { |
| 1018 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 1017 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 1019 } | 1018 } |
| 1020 if (r.OneInputIs(pointer_comparable_type_)) { | 1019 if (r.OneInputIs(pointer_comparable_type_)) { |
| 1021 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 1020 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 1022 } | 1021 } |
| 1023 if (r.IsInternalizedStringCompareOperation()) { | 1022 if (r.IsInternalizedStringCompareOperation()) { |
| 1024 r.CheckInputsToInternalizedString(); | 1023 r.CheckInputsToInternalizedString(); |
| 1025 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 1024 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 1026 } | 1025 } |
| 1027 if (r.BothInputsAre(Type::String())) { | 1026 if (r.BothInputsAre(Type::String())) { |
| 1028 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 1027 return r.ChangeToPureOperator(simplified()->StringEqual()); |
| 1029 } | 1028 } |
| 1030 | 1029 |
| 1031 NumberOperationHint hint; | 1030 NumberOperationHint hint; |
| 1032 if (r.BothInputsAre(Type::Signed32()) || | 1031 if (r.BothInputsAre(Type::Signed32()) || |
| 1033 r.BothInputsAre(Type::Unsigned32())) { | 1032 r.BothInputsAre(Type::Unsigned32())) { |
| 1034 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 1033 return r.ChangeToPureOperator(simplified()->NumberEqual()); |
| 1035 } else if (r.GetCompareNumberOperationHint(&hint)) { | 1034 } else if (r.GetCompareNumberOperationHint(&hint)) { |
| 1036 return r.ChangeToSpeculativeOperator( | 1035 return r.ChangeToSpeculativeOperator( |
| 1037 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); | 1036 simplified()->SpeculativeNumberEqual(hint), false, Type::Boolean()); |
| 1038 } else if (r.BothInputsAre(Type::Number())) { | 1037 } else if (r.BothInputsAre(Type::Number())) { |
| 1039 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 1038 return r.ChangeToPureOperator(simplified()->NumberEqual()); |
| 1040 } else if (r.IsReceiverCompareOperation()) { | 1039 } else if (r.IsReceiverCompareOperation()) { |
| 1041 // For strict equality, it's enough to know that one input is a Receiver, | 1040 // For strict equality, it's enough to know that one input is a Receiver, |
| 1042 // as a strict equality comparison with a Receiver can only yield true if | 1041 // as a strict equality comparison with a Receiver can only yield true if |
| 1043 // both sides refer to the same Receiver than. | 1042 // both sides refer to the same Receiver than. |
| 1044 r.CheckLeftInputToReceiver(); | 1043 r.CheckLeftInputToReceiver(); |
| 1045 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); | 1044 return r.ChangeToPureOperator(simplified()->ReferenceEqual()); |
| 1046 } else if (r.IsStringCompareOperation()) { | 1045 } else if (r.IsStringCompareOperation()) { |
| 1047 r.CheckInputsToString(); | 1046 r.CheckInputsToString(); |
| 1048 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 1047 return r.ChangeToPureOperator(simplified()->StringEqual()); |
| 1049 } | 1048 } |
| 1050 return NoChange(); | 1049 return NoChange(); |
| 1051 } | 1050 } |
| 1052 | 1051 |
| 1053 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 1052 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
| 1054 Node* const input = node->InputAt(0); | 1053 Node* const input = node->InputAt(0); |
| 1055 Type* const input_type = NodeProperties::GetType(input); | 1054 Type* const input_type = NodeProperties::GetType(input); |
| 1056 if (input_type->Is(Type::Boolean())) { | 1055 if (input_type->Is(Type::Boolean())) { |
| 1057 // JSToBoolean(x:boolean) => x | 1056 // JSToBoolean(x:boolean) => x |
| 1058 return Replace(input); | 1057 return Replace(input); |
| (...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 return Changed(element); | 2365 return Changed(element); |
| 2367 } | 2366 } |
| 2368 | 2367 |
| 2369 Reduction JSTypedLowering::Reduce(Node* node) { | 2368 Reduction JSTypedLowering::Reduce(Node* node) { |
| 2370 switch (node->opcode()) { | 2369 switch (node->opcode()) { |
| 2371 case IrOpcode::kJSEqual: | 2370 case IrOpcode::kJSEqual: |
| 2372 return ReduceJSEqual(node, false); | 2371 return ReduceJSEqual(node, false); |
| 2373 case IrOpcode::kJSNotEqual: | 2372 case IrOpcode::kJSNotEqual: |
| 2374 return ReduceJSEqual(node, true); | 2373 return ReduceJSEqual(node, true); |
| 2375 case IrOpcode::kJSStrictEqual: | 2374 case IrOpcode::kJSStrictEqual: |
| 2376 return ReduceJSStrictEqual(node, false); | 2375 return ReduceJSStrictEqual(node); |
| 2377 case IrOpcode::kJSStrictNotEqual: | |
| 2378 return ReduceJSStrictEqual(node, true); | |
| 2379 case IrOpcode::kJSLessThan: // fall through | 2376 case IrOpcode::kJSLessThan: // fall through |
| 2380 case IrOpcode::kJSGreaterThan: // fall through | 2377 case IrOpcode::kJSGreaterThan: // fall through |
| 2381 case IrOpcode::kJSLessThanOrEqual: // fall through | 2378 case IrOpcode::kJSLessThanOrEqual: // fall through |
| 2382 case IrOpcode::kJSGreaterThanOrEqual: | 2379 case IrOpcode::kJSGreaterThanOrEqual: |
| 2383 return ReduceJSComparison(node); | 2380 return ReduceJSComparison(node); |
| 2384 case IrOpcode::kJSBitwiseOr: | 2381 case IrOpcode::kJSBitwiseOr: |
| 2385 case IrOpcode::kJSBitwiseXor: | 2382 case IrOpcode::kJSBitwiseXor: |
| 2386 case IrOpcode::kJSBitwiseAnd: | 2383 case IrOpcode::kJSBitwiseAnd: |
| 2387 return ReduceInt32Binop(node); | 2384 return ReduceInt32Binop(node); |
| 2388 case IrOpcode::kJSShiftLeft: | 2385 case IrOpcode::kJSShiftLeft: |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2491 } | 2488 } |
| 2492 | 2489 |
| 2493 | 2490 |
| 2494 CompilationDependencies* JSTypedLowering::dependencies() const { | 2491 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2495 return dependencies_; | 2492 return dependencies_; |
| 2496 } | 2493 } |
| 2497 | 2494 |
| 2498 } // namespace compiler | 2495 } // namespace compiler |
| 2499 } // namespace internal | 2496 } // namespace internal |
| 2500 } // namespace v8 | 2497 } // namespace v8 |
| OLD | NEW |