Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(548)

Side by Side Diff: src/compiler/typer.cc

Issue 2081553002: [turbofan] Compute better types for additions with minus zero. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/typer.h" 5 #include "src/compiler/typer.h"
6 6
7 #include "src/base/flags.h" 7 #include "src/base/flags.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
10 #include "src/compiler/common-operator.h" 10 #include "src/compiler/common-operator.h"
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 static Type* NumberToInt32(Type*, Typer*); 249 static Type* NumberToInt32(Type*, Typer*);
250 static Type* NumberToUint32(Type*, Typer*); 250 static Type* NumberToUint32(Type*, Typer*);
251 251
252 static Type* ObjectIsCallable(Type*, Typer*); 252 static Type* ObjectIsCallable(Type*, Typer*);
253 static Type* ObjectIsNumber(Type*, Typer*); 253 static Type* ObjectIsNumber(Type*, Typer*);
254 static Type* ObjectIsReceiver(Type*, Typer*); 254 static Type* ObjectIsReceiver(Type*, Typer*);
255 static Type* ObjectIsSmi(Type*, Typer*); 255 static Type* ObjectIsSmi(Type*, Typer*);
256 static Type* ObjectIsString(Type*, Typer*); 256 static Type* ObjectIsString(Type*, Typer*);
257 static Type* ObjectIsUndetectable(Type*, Typer*); 257 static Type* ObjectIsUndetectable(Type*, Typer*);
258 258
259 static Type* JSAddRanger(RangeType*, RangeType*, Typer*); 259 static Type* JSAddRanger(double lhs_min, double lhs_max, double rhs_min,
260 double rhs_max, Typer* t);
260 static Type* JSSubtractRanger(RangeType*, RangeType*, Typer*); 261 static Type* JSSubtractRanger(RangeType*, RangeType*, Typer*);
261 static Type* JSDivideRanger(RangeType*, RangeType*, Typer*); 262 static Type* JSDivideRanger(RangeType*, RangeType*, Typer*);
262 static Type* JSModulusRanger(RangeType*, RangeType*, Typer*); 263 static Type* JSModulusRanger(RangeType*, RangeType*, Typer*);
263 264
264 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); 265 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
265 266
266 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); 267 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
267 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) 268 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
268 #undef DECLARE_METHOD 269 #undef DECLARE_METHOD
269 270
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 double x = -V8_INFINITY; 1031 double x = -V8_INFINITY;
1031 for (size_t i = 0; i < n; ++i) { 1032 for (size_t i = 0; i < n; ++i) {
1032 if (!std::isnan(a[i])) { 1033 if (!std::isnan(a[i])) {
1033 x = std::max(a[i], x); 1034 x = std::max(a[i], x);
1034 } 1035 }
1035 } 1036 }
1036 DCHECK(!std::isnan(x)); 1037 DCHECK(!std::isnan(x));
1037 return x == 0 ? 0 : x; // -0 -> 0 1038 return x == 0 ? 0 : x; // -0 -> 0
1038 } 1039 }
1039 1040
1040 Type* Typer::Visitor::JSAddRanger(RangeType* lhs, RangeType* rhs, Typer* t) { 1041 Type* Typer::Visitor::JSAddRanger(double lhs_min, double lhs_max,
1042 double rhs_min, double rhs_max, Typer* t) {
1041 double results[4]; 1043 double results[4];
1042 results[0] = lhs->Min() + rhs->Min(); 1044 results[0] = lhs_min + rhs_min;
1043 results[1] = lhs->Min() + rhs->Max(); 1045 results[1] = lhs_min + rhs_max;
1044 results[2] = lhs->Max() + rhs->Min(); 1046 results[2] = lhs_max + rhs_min;
1045 results[3] = lhs->Max() + rhs->Max(); 1047 results[3] = lhs_max + rhs_max;
1046 // Since none of the inputs can be -0, the result cannot be -0 either. 1048 // The results can be nan (the sum of two infinities of opposite sign).
1047 // However, it can be nan (the sum of two infinities of opposite sign).
1048 // On the other hand, if none of the "results" above is nan, then the actual 1049 // On the other hand, if none of the "results" above is nan, then the actual
1049 // result cannot be nan either. 1050 // result cannot be nan either.
1050 int nans = 0; 1051 int nans = 0;
1051 for (int i = 0; i < 4; ++i) { 1052 for (int i = 0; i < 4; ++i) {
1052 if (std::isnan(results[i])) ++nans; 1053 if (std::isnan(results[i])) ++nans;
1053 } 1054 }
1054 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa 1055 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa
1055 Type* range = 1056 Type* range =
1056 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); 1057 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1057 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); 1058 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
1058 // Examples: 1059 // Examples:
1059 // [-inf, -inf] + [+inf, +inf] = NaN 1060 // [-inf, -inf] + [+inf, +inf] = NaN
1060 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN 1061 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
1061 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN 1062 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
1062 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN 1063 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
1063 } 1064 }
1064 1065
1065 1066
1066 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 1067 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
1067 lhs = ToPrimitive(lhs, t); 1068 lhs = ToPrimitive(lhs, t);
1068 rhs = ToPrimitive(rhs, t); 1069 rhs = ToPrimitive(rhs, t);
1069 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 1070 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
1070 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 1071 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
1071 return Type::String(); 1072 return Type::String();
1072 } else { 1073 } else {
1073 return Type::NumberOrString(); 1074 return Type::NumberOrString();
1074 } 1075 }
1075 } 1076 }
1076 lhs = Rangify(ToNumber(lhs, t), t); 1077 // The addition must be numeric.
1077 rhs = Rangify(ToNumber(rhs, t), t); 1078 lhs = ToNumber(lhs, t);
1078 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1079 rhs = ToNumber(rhs, t);
1079 if (lhs->IsRange() && rhs->IsRange()) { 1080 // We can give more precise types for integers.
1080 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); 1081 if (!lhs->Is(t->cache_.kIntegerOrMinusZeroOrNaN) ||
1082 !rhs->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) {
1083 return Type::Number();
1081 } 1084 }
1082 return Type::Number(); 1085 Type* int_lhs = Type::Intersect(lhs, t->cache_.kInteger, t->zone());
1086 Type* int_rhs = Type::Intersect(rhs, t->cache_.kInteger, t->zone());
1087 Type* result = JSAddRanger(int_lhs->Min(), int_lhs->Max(), int_rhs->Min(),
1088 int_rhs->Max(), t);
1089 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
1090 result = Type::Union(result, Type::NaN(), t->zone());
1091 }
1092 if (lhs->Maybe(Type::MinusZero()) && rhs->Maybe(Type::MinusZero())) {
1093 result = Type::Union(result, Type::MinusZero(), t->zone());
1094 }
1095 return result;
1083 } 1096 }
1084 1097
1085 Type* Typer::Visitor::JSSubtractRanger(RangeType* lhs, RangeType* rhs, 1098 Type* Typer::Visitor::JSSubtractRanger(RangeType* lhs, RangeType* rhs,
1086 Typer* t) { 1099 Typer* t) {
1087 double results[4]; 1100 double results[4];
1088 results[0] = lhs->Min() - rhs->Min(); 1101 results[0] = lhs->Min() - rhs->Min();
1089 results[1] = lhs->Min() - rhs->Max(); 1102 results[1] = lhs->Min() - rhs->Max();
1090 results[2] = lhs->Max() - rhs->Min(); 1103 results[2] = lhs->Max() - rhs->Min();
1091 results[3] = lhs->Max() - rhs->Max(); 1104 results[3] = lhs->Max() - rhs->Max();
1092 // Since none of the inputs can be -0, the result cannot be -0. 1105 // Since none of the inputs can be -0, the result cannot be -0.
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after
2756 } 2769 }
2757 if (Type::IsInteger(*value)) { 2770 if (Type::IsInteger(*value)) {
2758 return Type::Range(value->Number(), value->Number(), zone()); 2771 return Type::Range(value->Number(), value->Number(), zone());
2759 } 2772 }
2760 return Type::Constant(value, zone()); 2773 return Type::Constant(value, zone());
2761 } 2774 }
2762 2775
2763 } // namespace compiler 2776 } // namespace compiler
2764 } // namespace internal 2777 } // namespace internal
2765 } // namespace v8 2778 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698