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 |