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-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
6 | 6 |
7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 if (HasInstanceTypeWitness(receiver, effect, JS_DATE_TYPE)) { | 368 if (HasInstanceTypeWitness(receiver, effect, JS_DATE_TYPE)) { |
369 Node* value = effect = graph()->NewNode( | 369 Node* value = effect = graph()->NewNode( |
370 simplified()->LoadField(AccessBuilder::ForJSDateValue()), receiver, | 370 simplified()->LoadField(AccessBuilder::ForJSDateValue()), receiver, |
371 effect, control); | 371 effect, control); |
372 ReplaceWithValue(node, value, effect, control); | 372 ReplaceWithValue(node, value, effect, control); |
373 return Replace(value); | 373 return Replace(value); |
374 } | 374 } |
375 return NoChange(); | 375 return NoChange(); |
376 } | 376 } |
377 | 377 |
| 378 // ES6 section 18.2.2 isFinite ( number ) |
| 379 Reduction JSBuiltinReducer::ReduceGlobalIsFinite(Node* node) { |
| 380 JSCallReduction r(node); |
| 381 if (r.InputsMatchOne(Type::PlainPrimitive())) { |
| 382 // isFinite(a:plain-primitive) -> NumberEqual(a', a') |
| 383 // where a' = NumberSubtract(ToNumber(a), ToNumber(a)) |
| 384 Node* input = ToNumber(r.GetJSCallInput(0)); |
| 385 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, input); |
| 386 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, diff); |
| 387 return Replace(value); |
| 388 } |
| 389 return NoChange(); |
| 390 } |
| 391 |
| 392 // ES6 section 18.2.3 isNaN ( number ) |
| 393 Reduction JSBuiltinReducer::ReduceGlobalIsNaN(Node* node) { |
| 394 JSCallReduction r(node); |
| 395 if (r.InputsMatchOne(Type::PlainPrimitive())) { |
| 396 // isNaN(a:plain-primitive) -> BooleanNot(NumberEqual(a', a')) |
| 397 // where a' = ToNumber(a) |
| 398 Node* input = ToNumber(r.GetJSCallInput(0)); |
| 399 Node* check = graph()->NewNode(simplified()->NumberEqual(), input, input); |
| 400 Node* value = graph()->NewNode(simplified()->BooleanNot(), check); |
| 401 return Replace(value); |
| 402 } |
| 403 return NoChange(); |
| 404 } |
| 405 |
378 // ES6 section 20.2.2.1 Math.abs ( x ) | 406 // ES6 section 20.2.2.1 Math.abs ( x ) |
379 Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) { | 407 Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) { |
380 JSCallReduction r(node); | 408 JSCallReduction r(node); |
381 if (r.InputsMatchOne(Type::PlainPrimitive())) { | 409 if (r.InputsMatchOne(Type::PlainPrimitive())) { |
382 // Math.abs(a:plain-primitive) -> NumberAbs(ToNumber(a)) | 410 // Math.abs(a:plain-primitive) -> NumberAbs(ToNumber(a)) |
383 Node* input = ToNumber(r.GetJSCallInput(0)); | 411 Node* input = ToNumber(r.GetJSCallInput(0)); |
384 Node* value = graph()->NewNode(simplified()->NumberAbs(), input); | 412 Node* value = graph()->NewNode(simplified()->NumberAbs(), input); |
385 return Replace(value); | 413 return Replace(value); |
386 } | 414 } |
387 return NoChange(); | 415 return NoChange(); |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 JSCallReduction r(node); | 810 JSCallReduction r(node); |
783 if (r.InputsMatchOne(Type::PlainPrimitive())) { | 811 if (r.InputsMatchOne(Type::PlainPrimitive())) { |
784 // Math.trunc(a:plain-primitive) -> NumberTrunc(ToNumber(a)) | 812 // Math.trunc(a:plain-primitive) -> NumberTrunc(ToNumber(a)) |
785 Node* input = ToNumber(r.GetJSCallInput(0)); | 813 Node* input = ToNumber(r.GetJSCallInput(0)); |
786 Node* value = graph()->NewNode(simplified()->NumberTrunc(), input); | 814 Node* value = graph()->NewNode(simplified()->NumberTrunc(), input); |
787 return Replace(value); | 815 return Replace(value); |
788 } | 816 } |
789 return NoChange(); | 817 return NoChange(); |
790 } | 818 } |
791 | 819 |
| 820 // ES6 section 20.1.2.2 Number.isFinite ( number ) |
| 821 Reduction JSBuiltinReducer::ReduceNumberIsFinite(Node* node) { |
| 822 JSCallReduction r(node); |
| 823 if (r.InputsMatchOne(Type::Number())) { |
| 824 // Number.isFinite(a:number) -> NumberEqual(a', a') |
| 825 // where a' = NumberSubtract(a, a) |
| 826 Node* input = r.GetJSCallInput(0); |
| 827 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, input); |
| 828 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, diff); |
| 829 return Replace(value); |
| 830 } |
| 831 return NoChange(); |
| 832 } |
| 833 |
| 834 // ES6 section 20.1.2.3 Number.isInteger ( number ) |
| 835 Reduction JSBuiltinReducer::ReduceNumberIsInteger(Node* node) { |
| 836 JSCallReduction r(node); |
| 837 if (r.InputsMatchOne(Type::Number())) { |
| 838 // Number.isInteger(x:number) -> NumberEqual(NumberSubtract(x, x'), #0) |
| 839 // where x' = NumberTrunc(x) |
| 840 Node* input = r.GetJSCallInput(0); |
| 841 Node* trunc = graph()->NewNode(simplified()->NumberTrunc(), input); |
| 842 Node* diff = graph()->NewNode(simplified()->NumberSubtract(), input, trunc); |
| 843 Node* value = graph()->NewNode(simplified()->NumberEqual(), diff, |
| 844 jsgraph()->ZeroConstant()); |
| 845 return Replace(value); |
| 846 } |
| 847 return NoChange(); |
| 848 } |
| 849 |
| 850 // ES6 section 20.1.2.4 Number.isNaN ( number ) |
| 851 Reduction JSBuiltinReducer::ReduceNumberIsNaN(Node* node) { |
| 852 JSCallReduction r(node); |
| 853 if (r.InputsMatchOne(Type::Number())) { |
| 854 // Number.isNaN(a:number) -> BooleanNot(NumberEqual(a, a)) |
| 855 Node* input = r.GetJSCallInput(0); |
| 856 Node* check = graph()->NewNode(simplified()->NumberEqual(), input, input); |
| 857 Node* value = graph()->NewNode(simplified()->BooleanNot(), check); |
| 858 return Replace(value); |
| 859 } |
| 860 return NoChange(); |
| 861 } |
| 862 |
| 863 // ES6 section 20.1.2.5 Number.isSafeInteger ( number ) |
| 864 Reduction JSBuiltinReducer::ReduceNumberIsSafeInteger(Node* node) { |
| 865 JSCallReduction r(node); |
| 866 if (r.InputsMatchOne(type_cache_.kSafeInteger)) { |
| 867 // Number.isInteger(x:safe-integer) -> #true |
| 868 Node* value = jsgraph()->TrueConstant(); |
| 869 return Replace(value); |
| 870 } |
| 871 return NoChange(); |
| 872 } |
| 873 |
792 // ES6 section 20.1.2.13 Number.parseInt ( string, radix ) | 874 // ES6 section 20.1.2.13 Number.parseInt ( string, radix ) |
793 Reduction JSBuiltinReducer::ReduceNumberParseInt(Node* node) { | 875 Reduction JSBuiltinReducer::ReduceNumberParseInt(Node* node) { |
794 JSCallReduction r(node); | 876 JSCallReduction r(node); |
795 if (r.InputsMatchOne(type_cache_.kSafeInteger) || | 877 if (r.InputsMatchOne(type_cache_.kSafeInteger) || |
796 r.InputsMatchTwo(type_cache_.kSafeInteger, | 878 r.InputsMatchTwo(type_cache_.kSafeInteger, |
797 type_cache_.kZeroOrUndefined) || | 879 type_cache_.kZeroOrUndefined) || |
798 r.InputsMatchTwo(type_cache_.kSafeInteger, type_cache_.kTenOrUndefined)) { | 880 r.InputsMatchTwo(type_cache_.kSafeInteger, type_cache_.kTenOrUndefined)) { |
799 // Number.parseInt(a:safe-integer) -> NumberToInt32(a) | 881 // Number.parseInt(a:safe-integer) -> NumberToInt32(a) |
800 // Number.parseInt(a:safe-integer,b:#0\/undefined) -> NumberToInt32(a) | 882 // Number.parseInt(a:safe-integer,b:#0\/undefined) -> NumberToInt32(a) |
801 // Number.parseInt(a:safe-integer,b:#10\/undefined) -> NumberToInt32(a) | 883 // Number.parseInt(a:safe-integer,b:#10\/undefined) -> NumberToInt32(a) |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 | 1056 |
975 // Dispatch according to the BuiltinFunctionId if present. | 1057 // Dispatch according to the BuiltinFunctionId if present. |
976 if (!r.HasBuiltinFunctionId()) return NoChange(); | 1058 if (!r.HasBuiltinFunctionId()) return NoChange(); |
977 switch (r.GetBuiltinFunctionId()) { | 1059 switch (r.GetBuiltinFunctionId()) { |
978 case kArrayPop: | 1060 case kArrayPop: |
979 return ReduceArrayPop(node); | 1061 return ReduceArrayPop(node); |
980 case kArrayPush: | 1062 case kArrayPush: |
981 return ReduceArrayPush(node); | 1063 return ReduceArrayPush(node); |
982 case kDateGetTime: | 1064 case kDateGetTime: |
983 return ReduceDateGetTime(node); | 1065 return ReduceDateGetTime(node); |
| 1066 case kGlobalIsFinite: |
| 1067 reduction = ReduceGlobalIsFinite(node); |
| 1068 break; |
| 1069 case kGlobalIsNaN: |
| 1070 reduction = ReduceGlobalIsNaN(node); |
| 1071 break; |
984 case kMathAbs: | 1072 case kMathAbs: |
985 reduction = ReduceMathAbs(node); | 1073 reduction = ReduceMathAbs(node); |
986 break; | 1074 break; |
987 case kMathAcos: | 1075 case kMathAcos: |
988 reduction = ReduceMathAcos(node); | 1076 reduction = ReduceMathAcos(node); |
989 break; | 1077 break; |
990 case kMathAcosh: | 1078 case kMathAcosh: |
991 reduction = ReduceMathAcosh(node); | 1079 reduction = ReduceMathAcosh(node); |
992 break; | 1080 break; |
993 case kMathAsin: | 1081 case kMathAsin: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 break; | 1161 break; |
1074 case kMathTan: | 1162 case kMathTan: |
1075 reduction = ReduceMathTan(node); | 1163 reduction = ReduceMathTan(node); |
1076 break; | 1164 break; |
1077 case kMathTanh: | 1165 case kMathTanh: |
1078 reduction = ReduceMathTanh(node); | 1166 reduction = ReduceMathTanh(node); |
1079 break; | 1167 break; |
1080 case kMathTrunc: | 1168 case kMathTrunc: |
1081 reduction = ReduceMathTrunc(node); | 1169 reduction = ReduceMathTrunc(node); |
1082 break; | 1170 break; |
| 1171 case kNumberIsFinite: |
| 1172 reduction = ReduceNumberIsFinite(node); |
| 1173 break; |
| 1174 case kNumberIsInteger: |
| 1175 reduction = ReduceNumberIsInteger(node); |
| 1176 break; |
| 1177 case kNumberIsNaN: |
| 1178 reduction = ReduceNumberIsNaN(node); |
| 1179 break; |
| 1180 case kNumberIsSafeInteger: |
| 1181 reduction = ReduceNumberIsSafeInteger(node); |
| 1182 break; |
1083 case kNumberParseInt: | 1183 case kNumberParseInt: |
1084 reduction = ReduceNumberParseInt(node); | 1184 reduction = ReduceNumberParseInt(node); |
1085 break; | 1185 break; |
1086 case kStringFromCharCode: | 1186 case kStringFromCharCode: |
1087 reduction = ReduceStringFromCharCode(node); | 1187 reduction = ReduceStringFromCharCode(node); |
1088 break; | 1188 break; |
1089 case kStringCharAt: | 1189 case kStringCharAt: |
1090 return ReduceStringCharAt(node); | 1190 return ReduceStringCharAt(node); |
1091 case kStringCharCodeAt: | 1191 case kStringCharCodeAt: |
1092 return ReduceStringCharCodeAt(node); | 1192 return ReduceStringCharCodeAt(node); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 } | 1245 } |
1146 | 1246 |
1147 | 1247 |
1148 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { | 1248 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { |
1149 return jsgraph()->simplified(); | 1249 return jsgraph()->simplified(); |
1150 } | 1250 } |
1151 | 1251 |
1152 } // namespace compiler | 1252 } // namespace compiler |
1153 } // namespace internal | 1253 } // namespace internal |
1154 } // namespace v8 | 1254 } // namespace v8 |
OLD | NEW |