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

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

Issue 2139203002: [turbofan] Allow non-speculative operators to consume feedback types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments. 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 | « src/compiler/operation-typer.h ('k') | src/compiler/representation-change.h » ('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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 if (type->Is(singleton_false_)) return cache_.kSingletonZero; 278 if (type->Is(singleton_false_)) return cache_.kSingletonZero;
279 if (type->Is(singleton_true_)) return cache_.kSingletonOne; 279 if (type->Is(singleton_true_)) return cache_.kSingletonOne;
280 if (type->Is(Type::Boolean())) return cache_.kZeroOrOne; 280 if (type->Is(Type::Boolean())) return cache_.kZeroOrOne;
281 if (type->Is(Type::BooleanOrNumber())) { 281 if (type->Is(Type::BooleanOrNumber())) {
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::NumberAdd(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()) { 292 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
293 return Type::None(); 293 return Type::None();
294 } 294 }
295 295
296 // We can give more precise types for integers. 296 // We can give more precise types for integers.
297 if (!lhs->Is(cache_.kIntegerOrMinusZeroOrNaN) || 297 if (!lhs->Is(cache_.kIntegerOrMinusZeroOrNaN) ||
298 !rhs->Is(cache_.kIntegerOrMinusZeroOrNaN)) { 298 !rhs->Is(cache_.kIntegerOrMinusZeroOrNaN)) {
299 return Type::Number(); 299 return Type::Number();
300 } 300 }
301 Type* int_lhs = Type::Intersect(lhs, cache_.kInteger, zone()); 301 Type* int_lhs = Type::Intersect(lhs, cache_.kInteger, zone());
302 Type* int_rhs = Type::Intersect(rhs, cache_.kInteger, zone()); 302 Type* int_rhs = Type::Intersect(rhs, cache_.kInteger, zone());
303 Type* result = 303 Type* result =
304 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());
305 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { 305 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
306 result = Type::Union(result, Type::NaN(), zone()); 306 result = Type::Union(result, Type::NaN(), zone());
307 } 307 }
308 if (lhs->Maybe(Type::MinusZero()) && rhs->Maybe(Type::MinusZero())) { 308 if (lhs->Maybe(Type::MinusZero()) && rhs->Maybe(Type::MinusZero())) {
309 result = Type::Union(result, Type::MinusZero(), zone()); 309 result = Type::Union(result, Type::MinusZero(), zone());
310 } 310 }
311 return result; 311 return result;
312 } 312 }
313 313
314 Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) { 314 Type* OperationTyper::NumberSubtract(Type* lhs, Type* rhs) {
315 DCHECK(lhs->Is(Type::Number())); 315 DCHECK(lhs->Is(Type::Number()));
316 DCHECK(rhs->Is(Type::Number())); 316 DCHECK(rhs->Is(Type::Number()));
317 317
318 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { 318 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
319 return Type::None(); 319 return Type::None();
320 } 320 }
321 321
322 lhs = Rangify(lhs); 322 lhs = Rangify(lhs);
323 rhs = Rangify(rhs); 323 rhs = Rangify(rhs);
324 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();
325 if (lhs->IsRange() && rhs->IsRange()) { 325 if (lhs->IsRange() && rhs->IsRange()) {
326 return SubtractRanger(lhs->AsRange(), rhs->AsRange()); 326 return SubtractRanger(lhs->AsRange(), rhs->AsRange());
327 } 327 }
328 // TODO(neis): Deal with numeric bitsets here and elsewhere. 328 // TODO(neis): Deal with numeric bitsets here and elsewhere.
329 return Type::Number(); 329 return Type::Number();
330 } 330 }
331 331
332 Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) { 332 Type* OperationTyper::NumberMultiply(Type* lhs, Type* rhs) {
333 DCHECK(lhs->Is(Type::Number())); 333 DCHECK(lhs->Is(Type::Number()));
334 DCHECK(rhs->Is(Type::Number())); 334 DCHECK(rhs->Is(Type::Number()));
335 335
336 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { 336 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
337 return Type::None(); 337 return Type::None();
338 } 338 }
339 339
340 lhs = Rangify(lhs); 340 lhs = Rangify(lhs);
341 rhs = Rangify(rhs); 341 rhs = Rangify(rhs);
342 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();
343 if (lhs->IsRange() && rhs->IsRange()) { 343 if (lhs->IsRange() && rhs->IsRange()) {
344 return MultiplyRanger(lhs, rhs); 344 return MultiplyRanger(lhs, rhs);
345 } 345 }
346 return Type::Number(); 346 return Type::Number();
347 } 347 }
348 348
349 Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) { 349 Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) {
350 DCHECK(lhs->Is(Type::Number())); 350 DCHECK(lhs->Is(Type::Number()));
351 DCHECK(rhs->Is(Type::Number())); 351 DCHECK(rhs->Is(Type::Number()));
352 352
353 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { 353 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
354 return Type::None(); 354 return Type::None();
355 } 355 }
356 356
357 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();
358 // 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.
359 bool maybe_nan = 359 bool maybe_nan =
360 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || 360 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
361 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 361 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
362 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 362 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
363 return maybe_nan ? Type::Number() : Type::OrderedNumber(); 363 return maybe_nan ? Type::Number() : Type::OrderedNumber();
364 } 364 }
365 365
366 Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) { 366 Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) {
367 DCHECK(lhs->Is(Type::Number())); 367 DCHECK(lhs->Is(Type::Number()));
368 DCHECK(rhs->Is(Type::Number())); 368 DCHECK(rhs->Is(Type::Number()));
369 369
370 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { 370 if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
371 return Type::None(); 371 return Type::None();
372 } 372 }
373 373
374 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();
375 375
376 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || 376 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
377 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { 377 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
378 // Result maybe NaN. 378 // Result maybe NaN.
379 return Type::Number(); 379 return Type::Number();
380 } 380 }
381 381
382 lhs = Rangify(lhs); 382 lhs = Rangify(lhs);
383 rhs = Rangify(rhs); 383 rhs = Rangify(rhs);
384 if (lhs->IsRange() && rhs->IsRange()) { 384 if (lhs->IsRange() && rhs->IsRange()) {
385 return ModulusRanger(lhs->AsRange(), rhs->AsRange()); 385 return ModulusRanger(lhs->AsRange(), rhs->AsRange());
386 } 386 }
387 return Type::OrderedNumber(); 387 return Type::OrderedNumber();
388 } 388 }
389 389
390 Type* OperationTyper::NumberAbs(Type* type) {
391 DCHECK(type->Is(Type::Number()));
392
393 if (!type->IsInhabited()) {
394 return Type::None();
395 }
396
397 bool const maybe_nan = type->Maybe(Type::NaN());
398 bool const maybe_minuszero = type->Maybe(Type::MinusZero());
399 type = Type::Intersect(type, Type::PlainNumber(), zone());
400 double const max = type->Max();
401 double const min = type->Min();
402 if (min < 0) {
403 if (type->Is(cache_.kInteger)) {
404 type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone());
405 } else {
406 type = Type::PlainNumber();
407 }
408 }
409 if (maybe_minuszero) {
410 type = Type::Union(type, cache_.kSingletonZero, zone());
411 }
412 if (maybe_nan) {
413 type = Type::Union(type, Type::NaN(), zone());
414 }
415 return type;
416 }
417
390 Type* OperationTyper::ToPrimitive(Type* type) { 418 Type* OperationTyper::ToPrimitive(Type* type) {
391 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 419 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
392 return type; 420 return type;
393 } 421 }
394 return Type::Primitive(); 422 return Type::Primitive();
395 } 423 }
396 424
397 Type* OperationTyper::Invert(Type* type) { 425 Type* OperationTyper::Invert(Type* type) {
398 DCHECK(type->Is(Type::Boolean())); 426 DCHECK(type->Is(Type::Boolean()));
399 DCHECK(type->IsInhabited()); 427 DCHECK(type->IsInhabited());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 460
433 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 461 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
434 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 462 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
435 return Type::String(); 463 return Type::String();
436 } else { 464 } else {
437 return Type::NumberOrString(); 465 return Type::NumberOrString();
438 } 466 }
439 } 467 }
440 lhs = ToNumber(lhs); 468 lhs = ToNumber(lhs);
441 rhs = ToNumber(rhs); 469 rhs = ToNumber(rhs);
442 return NumericAdd(lhs, rhs); 470 return NumberAdd(lhs, rhs);
443 } 471 }
444 472
445 Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) { 473 Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) {
446 return NumericSubtract(ToNumber(lhs), ToNumber(rhs)); 474 return NumberSubtract(ToNumber(lhs), ToNumber(rhs));
447 } 475 }
448 476
449 } // namespace compiler 477 } // namespace compiler
450 } // namespace internal 478 } // namespace internal
451 } // namespace v8 479 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/operation-typer.h ('k') | src/compiler/representation-change.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698