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

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

Issue 2120243002: [turbofan] Better handling of empty type in simplified lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Disable slow test Created 4 years, 5 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 | src/compiler/simplified-lowering.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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 return Type::Union(Type::Intersect(type, Type::Number(), zone()), 282 return Type::Union(Type::Intersect(type, Type::Number(), zone()),
283 cache_.kZeroOrOne, zone()); 283 cache_.kZeroOrOne, zone());
284 } 284 }
285 return Type::Number(); 285 return Type::Number();
286 } 286 }
287 287
288 Type* OperationTyper::NumericAdd(Type* lhs, Type* rhs) { 288 Type* OperationTyper::NumericAdd(Type* lhs, Type* rhs) {
289 DCHECK(lhs->Is(Type::Number())); 289 DCHECK(lhs->Is(Type::Number()));
290 DCHECK(rhs->Is(Type::Number())); 290 DCHECK(rhs->Is(Type::Number()));
291 291
292 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
293 return Type::None();
294 }
295
292 // We can give more precise types for integers. 296 // We can give more precise types for integers.
293 if (!lhs->Is(cache_.kIntegerOrMinusZeroOrNaN) || 297 if (!lhs->Is(cache_.kIntegerOrMinusZeroOrNaN) ||
294 !rhs->Is(cache_.kIntegerOrMinusZeroOrNaN)) { 298 !rhs->Is(cache_.kIntegerOrMinusZeroOrNaN)) {
295 return Type::Number(); 299 return Type::Number();
296 } 300 }
297 Type* int_lhs = Type::Intersect(lhs, cache_.kInteger, zone()); 301 Type* int_lhs = Type::Intersect(lhs, cache_.kInteger, zone());
298 Type* int_rhs = Type::Intersect(rhs, cache_.kInteger, zone()); 302 Type* int_rhs = Type::Intersect(rhs, cache_.kInteger, zone());
299 Type* result = 303 Type* result =
300 AddRanger(int_lhs->Min(), int_lhs->Max(), int_rhs->Min(), int_rhs->Max()); 304 AddRanger(int_lhs->Min(), int_lhs->Max(), int_rhs->Min(), int_rhs->Max());
301 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { 305 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
302 result = Type::Union(result, Type::NaN(), zone()); 306 result = Type::Union(result, Type::NaN(), zone());
303 } 307 }
304 if (lhs->Maybe(Type::MinusZero()) && rhs->Maybe(Type::MinusZero())) { 308 if (lhs->Maybe(Type::MinusZero()) && rhs->Maybe(Type::MinusZero())) {
305 result = Type::Union(result, Type::MinusZero(), zone()); 309 result = Type::Union(result, Type::MinusZero(), zone());
306 } 310 }
307 return result; 311 return result;
308 } 312 }
309 313
310 Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) { 314 Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) {
311 DCHECK(lhs->Is(Type::Number())); 315 DCHECK(lhs->Is(Type::Number()));
312 DCHECK(rhs->Is(Type::Number())); 316 DCHECK(rhs->Is(Type::Number()));
313 317
318 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
319 return Type::None();
320 }
321
314 lhs = Rangify(lhs); 322 lhs = Rangify(lhs);
315 rhs = Rangify(rhs); 323 rhs = Rangify(rhs);
316 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 324 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
317 if (lhs->IsRange() && rhs->IsRange()) { 325 if (lhs->IsRange() && rhs->IsRange()) {
318 return SubtractRanger(lhs->AsRange(), rhs->AsRange()); 326 return SubtractRanger(lhs->AsRange(), rhs->AsRange());
319 } 327 }
320 // TODO(neis): Deal with numeric bitsets here and elsewhere. 328 // TODO(neis): Deal with numeric bitsets here and elsewhere.
321 return Type::Number(); 329 return Type::Number();
322 } 330 }
323 331
324 Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) { 332 Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) {
325 DCHECK(lhs->Is(Type::Number())); 333 DCHECK(lhs->Is(Type::Number()));
326 DCHECK(rhs->Is(Type::Number())); 334 DCHECK(rhs->Is(Type::Number()));
335
336 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
337 return Type::None();
338 }
339
327 lhs = Rangify(lhs); 340 lhs = Rangify(lhs);
328 rhs = Rangify(rhs); 341 rhs = Rangify(rhs);
329 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 342 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
330 if (lhs->IsRange() && rhs->IsRange()) { 343 if (lhs->IsRange() && rhs->IsRange()) {
331 return MultiplyRanger(lhs, rhs); 344 return MultiplyRanger(lhs, rhs);
332 } 345 }
333 return Type::Number(); 346 return Type::Number();
334 } 347 }
335 348
336 Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) { 349 Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) {
337 DCHECK(lhs->Is(Type::Number())); 350 DCHECK(lhs->Is(Type::Number()));
338 DCHECK(rhs->Is(Type::Number())); 351 DCHECK(rhs->Is(Type::Number()));
339 352
353 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
354 return Type::None();
355 }
356
340 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 357 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
341 // Division is tricky, so all we do is try ruling out nan. 358 // Division is tricky, so all we do is try ruling out nan.
342 bool maybe_nan = 359 bool maybe_nan =
343 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || 360 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
344 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 361 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
345 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 362 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
346 return maybe_nan ? Type::Number() : Type::OrderedNumber(); 363 return maybe_nan ? Type::Number() : Type::OrderedNumber();
347 } 364 }
348 365
349 Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) { 366 Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) {
350 DCHECK(lhs->Is(Type::Number())); 367 DCHECK(lhs->Is(Type::Number()));
351 DCHECK(rhs->Is(Type::Number())); 368 DCHECK(rhs->Is(Type::Number()));
369
370 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
371 return Type::None();
372 }
373
352 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 374 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
353 375
354 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || 376 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
355 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { 377 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
356 // Result maybe NaN. 378 // Result maybe NaN.
357 return Type::Number(); 379 return Type::Number();
358 } 380 }
359 381
360 lhs = Rangify(lhs); 382 lhs = Rangify(lhs);
361 rhs = Rangify(rhs); 383 rhs = Rangify(rhs);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 : singleton_false(); 418 : singleton_false();
397 } 419 }
398 // Type should be non empty, so we know it should be true. 420 // Type should be non empty, so we know it should be true.
399 DCHECK((outcome & kComparisonTrue) != 0); 421 DCHECK((outcome & kComparisonTrue) != 0);
400 return singleton_true(); 422 return singleton_true();
401 } 423 }
402 424
403 Type* OperationTyper::TypeJSAdd(Type* lhs, Type* rhs) { 425 Type* OperationTyper::TypeJSAdd(Type* lhs, Type* rhs) {
404 lhs = ToPrimitive(lhs); 426 lhs = ToPrimitive(lhs);
405 rhs = ToPrimitive(rhs); 427 rhs = ToPrimitive(rhs);
428
429 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
430 return Type::None();
431 }
432
406 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 433 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
407 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 434 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
408 return Type::String(); 435 return Type::String();
409 } else { 436 } else {
410 return Type::NumberOrString(); 437 return Type::NumberOrString();
411 } 438 }
412 } 439 }
413 lhs = ToNumber(lhs); 440 lhs = ToNumber(lhs);
414 rhs = ToNumber(rhs); 441 rhs = ToNumber(rhs);
415 return NumericAdd(lhs, rhs); 442 return NumericAdd(lhs, rhs);
416 } 443 }
417 444
418 Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) { 445 Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) {
419 return NumericSubtract(ToNumber(lhs), ToNumber(rhs)); 446 return NumericSubtract(ToNumber(lhs), ToNumber(rhs));
420 } 447 }
421 448
422 } // namespace compiler 449 } // namespace compiler
423 } // namespace internal 450 } // namespace internal
424 } // namespace v8 451 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698