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

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

Issue 2074903002: [turbofan] Numeric type feedback for mul, div and mod. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase 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 | « src/compiler/operation-typer.h ('k') | src/compiler/representation-change.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/operation-typer.h" 5 #include "src/compiler/operation-typer.h"
6 6
7 #include "src/factory.h" 7 #include "src/factory.h"
8 #include "src/isolate.h" 8 #include "src/isolate.h"
9 #include "src/type-cache.h" 9 #include "src/type-cache.h"
10 #include "src/types.h" 10 #include "src/types.h"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 omin = 0 - abs; 226 omin = 0 - abs;
227 omax = abs; 227 omax = abs;
228 maybe_minus_zero = true; 228 maybe_minus_zero = true;
229 } 229 }
230 230
231 Type* result = Type::Range(omin, omax, zone()); 231 Type* result = Type::Range(omin, omax, zone());
232 if (maybe_minus_zero) result = Type::Union(result, Type::MinusZero(), zone()); 232 if (maybe_minus_zero) result = Type::Union(result, Type::MinusZero(), zone());
233 return result; 233 return result;
234 } 234 }
235 235
236 Type* OperationTyper::MultiplyRanger(Type* lhs, Type* rhs) {
237 double results[4];
238 double lmin = lhs->AsRange()->Min();
239 double lmax = lhs->AsRange()->Max();
240 double rmin = rhs->AsRange()->Min();
241 double rmax = rhs->AsRange()->Max();
242 results[0] = lmin * rmin;
243 results[1] = lmin * rmax;
244 results[2] = lmax * rmin;
245 results[3] = lmax * rmax;
246 // If the result may be nan, we give up on calculating a precise type,
247 // because
248 // the discontinuity makes it too complicated. Note that even if none of
249 // the
250 // "results" above is nan, the actual result may still be, so we have to do
251 // a
252 // different check:
253 bool maybe_nan = (lhs->Maybe(cache_.kSingletonZero) &&
254 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
255 (rhs->Maybe(cache_.kSingletonZero) &&
256 (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
257 if (maybe_nan) return cache_.kIntegerOrMinusZeroOrNaN; // Giving up.
258 bool maybe_minuszero = (lhs->Maybe(cache_.kSingletonZero) && rmin < 0) ||
259 (rhs->Maybe(cache_.kSingletonZero) && lmin < 0);
260 Type* range =
261 Type::Range(array_min(results, 4), array_max(results, 4), zone());
262 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), zone())
263 : range;
264 }
265
236 Type* OperationTyper::ToNumber(Type* type) { 266 Type* OperationTyper::ToNumber(Type* type) {
237 if (type->Is(Type::Number())) return type; 267 if (type->Is(Type::Number())) return type;
238 if (type->Is(Type::NullOrUndefined())) { 268 if (type->Is(Type::NullOrUndefined())) {
239 if (type->Is(Type::Null())) return cache_.kSingletonZero; 269 if (type->Is(Type::Null())) return cache_.kSingletonZero;
240 if (type->Is(Type::Undefined())) return Type::NaN(); 270 if (type->Is(Type::Undefined())) return Type::NaN();
241 return Type::Union(Type::NaN(), cache_.kSingletonZero, zone()); 271 return Type::Union(Type::NaN(), cache_.kSingletonZero, zone());
242 } 272 }
243 if (type->Is(Type::NumberOrUndefined())) { 273 if (type->Is(Type::NumberOrUndefined())) {
244 return Type::Union(Type::Intersect(type, Type::Number(), zone()), 274 return Type::Union(Type::Intersect(type, Type::Number(), zone()),
245 Type::NaN(), zone()); 275 Type::NaN(), zone());
(...skipping 29 matching lines...) Expand all
275 lhs = Rangify(lhs); 305 lhs = Rangify(lhs);
276 rhs = Rangify(rhs); 306 rhs = Rangify(rhs);
277 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 307 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
278 if (lhs->IsRange() && rhs->IsRange()) { 308 if (lhs->IsRange() && rhs->IsRange()) {
279 return SubtractRanger(lhs->AsRange(), rhs->AsRange()); 309 return SubtractRanger(lhs->AsRange(), rhs->AsRange());
280 } 310 }
281 // TODO(neis): Deal with numeric bitsets here and elsewhere. 311 // TODO(neis): Deal with numeric bitsets here and elsewhere.
282 return Type::Number(); 312 return Type::Number();
283 } 313 }
284 314
315 Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) {
316 DCHECK(lhs->Is(Type::Number()));
317 DCHECK(rhs->Is(Type::Number()));
318 lhs = Rangify(lhs);
319 rhs = Rangify(rhs);
320 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
321 if (lhs->IsRange() && rhs->IsRange()) {
322 return MultiplyRanger(lhs, rhs);
323 }
324 return Type::Number();
325 }
326
327 Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) {
328 DCHECK(lhs->Is(Type::Number()));
329 DCHECK(rhs->Is(Type::Number()));
330
331 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
332 // Division is tricky, so all we do is try ruling out nan.
333 bool maybe_nan =
334 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
335 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
336 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
337 return maybe_nan ? Type::Number() : Type::OrderedNumber();
338 }
339
340 Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) {
341 DCHECK(lhs->Is(Type::Number()));
342 DCHECK(rhs->Is(Type::Number()));
343 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
344
345 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
346 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
347 // Result maybe NaN.
348 return Type::Number();
349 }
350
351 lhs = Rangify(lhs);
352 rhs = Rangify(rhs);
353 if (lhs->IsRange() && rhs->IsRange()) {
354 return ModulusRanger(lhs->AsRange(), rhs->AsRange());
355 }
356 return Type::OrderedNumber();
357 }
358
285 Type* OperationTyper::ToPrimitive(Type* type) { 359 Type* OperationTyper::ToPrimitive(Type* type) {
286 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 360 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
287 return type; 361 return type;
288 } 362 }
289 return Type::Primitive(); 363 return Type::Primitive();
290 } 364 }
291 365
292 Type* OperationTyper::Invert(Type* type) { 366 Type* OperationTyper::Invert(Type* type) {
293 DCHECK(type->Is(Type::Boolean())); 367 DCHECK(type->Is(Type::Boolean()));
294 DCHECK(type->IsInhabited()); 368 DCHECK(type->IsInhabited());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 return NumericAdd(lhs, rhs); 406 return NumericAdd(lhs, rhs);
333 } 407 }
334 408
335 Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) { 409 Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) {
336 return NumericSubtract(ToNumber(lhs), ToNumber(rhs)); 410 return NumericSubtract(ToNumber(lhs), ToNumber(rhs));
337 } 411 }
338 412
339 } // namespace compiler 413 } // namespace compiler
340 } // namespace internal 414 } // namespace internal
341 } // namespace v8 415 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/operation-typer.h ('k') | src/compiler/representation-change.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698