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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 683873002: [turbofan] Avoid unnecessary (u)int32<->float64 changes in simplified lowering. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Test Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | test/cctest/compiler/test-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 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/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 void VisitInt64Binop(Node* node) { VisitBinop(node, kMachInt64, kMachInt64); } 289 void VisitInt64Binop(Node* node) { VisitBinop(node, kMachInt64, kMachInt64); }
290 void VisitUint64Binop(Node* node) { 290 void VisitUint64Binop(Node* node) {
291 VisitBinop(node, kMachUint64, kMachUint64); 291 VisitBinop(node, kMachUint64, kMachUint64);
292 } 292 }
293 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); } 293 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); }
294 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); } 294 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); }
295 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); } 295 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); }
296 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); } 296 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); }
297 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); } 297 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); }
298 298
299 // Infer representation for phi-like nodes.
300 MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) {
301 // Phis adapt to the output representation their uses demand.
302 Type* upper = NodeProperties::GetBounds(node).upper;
303 if ((use & kRepMask) == kRepTagged) {
304 // only tagged uses.
305 return kRepTagged;
306 } else if (IsSafeIntAdditiveOperand(node)) {
307 // Integer within [-2^52, 2^52] range.
308 if ((use & kRepMask) == kRepFloat64) {
309 // only float64 uses.
310 return kRepFloat64;
311 } else if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
312 // multiple uses, but we are within 32 bits range => pick kRepWord32.
313 return kRepWord32;
314 } else if ((use & kRepMask) == kRepWord32 ||
315 (use & kTypeMask) == kTypeInt32 ||
316 (use & kTypeMask) == kTypeUint32) {
317 // The type is a safe integer, but we only use 32 bits.
318 return kRepWord32;
319 } else {
320 return kRepFloat64;
321 }
322 } else if (upper->Is(Type::Boolean())) {
323 // multiple uses => pick kRepBit.
324 return kRepBit;
325 } else if (upper->Is(Type::Number())) {
326 // multiple uses => pick kRepFloat64.
327 return kRepFloat64;
328 }
329 return kRepTagged;
330 }
331
299 // Helper for handling selects. 332 // Helper for handling selects.
300 // TODO(turbofan): Share some code with VisitPhi() below?
301 void VisitSelect(Node* node, MachineTypeUnion use, 333 void VisitSelect(Node* node, MachineTypeUnion use,
302 SimplifiedLowering* lowering) { 334 SimplifiedLowering* lowering) {
303 ProcessInput(node, 0, kRepBit); 335 ProcessInput(node, 0, kRepBit);
336 MachineType output = GetRepresentationForPhi(node, use);
304 337
305 // Selects adapt to the output representation their uses demand, pushing
306 // representation changes to their inputs.
307 Type* upper = NodeProperties::GetBounds(node).upper; 338 Type* upper = NodeProperties::GetBounds(node).upper;
308 MachineType output = kMachNone;
309 MachineType propagate = kMachNone;
310
311 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
312 // legal = kRepTagged | kRepFloat64 | kRepWord32;
313 if ((use & kRepMask) == kRepTagged) {
314 // only tagged uses.
315 output = kRepTagged;
316 propagate = kRepTagged;
317 } else if ((use & kRepMask) == kRepFloat64) {
318 // only float64 uses.
319 output = kRepFloat64;
320 propagate = kRepFloat64;
321 } else {
322 // multiple uses.
323 output = kRepWord32;
324 propagate = kRepWord32;
325 }
326 } else if (upper->Is(Type::Boolean())) {
327 // legal = kRepTagged | kRepBit;
328 if ((use & kRepMask) == kRepTagged) {
329 // only tagged uses.
330 output = kRepTagged;
331 propagate = kRepTagged;
332 } else {
333 // multiple uses.
334 output = kRepBit;
335 propagate = kRepBit;
336 }
337 } else if (upper->Is(Type::Number())) {
338 // legal = kRepTagged | kRepFloat64;
339 if ((use & kRepMask) == kRepTagged) {
340 // only tagged uses.
341 output = kRepTagged;
342 propagate = kRepTagged;
343 } else {
344 // multiple uses.
345 output = kRepFloat64;
346 propagate = kRepFloat64;
347 }
348 } else {
349 // legal = kRepTagged;
350 output = kRepTagged;
351 propagate = kRepTagged;
352 }
353
354 MachineType output_type = 339 MachineType output_type =
355 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); 340 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
356 SetOutput(node, output_type); 341 SetOutput(node, output_type);
357 342
358 if (lower()) { 343 if (lower()) {
359 // Update the select operator. 344 // Update the select operator.
360 SelectParameters p = SelectParametersOf(node->op()); 345 SelectParameters p = SelectParametersOf(node->op());
361 MachineType type = static_cast<MachineType>(output_type); 346 MachineType type = static_cast<MachineType>(output_type);
362 if (type != p.type()) { 347 if (type != p.type()) {
363 node->set_op(lowering->common()->Select(type, p.hint())); 348 node->set_op(lowering->common()->Select(type, p.hint()));
364 } 349 }
365 350
366 // Convert inputs to the output representation of this select. 351 // Convert inputs to the output representation of this select.
367 ProcessInput(node, 1, output_type); 352 ProcessInput(node, 1, output_type);
368 ProcessInput(node, 2, output_type); 353 ProcessInput(node, 2, output_type);
369 } else { 354 } else {
370 // Propagate {use} of the select to value inputs. 355 // Propagate {use} of the select to value inputs.
371 MachineType use_type = 356 MachineType use_type =
372 static_cast<MachineType>((use & kTypeMask) | propagate); 357 static_cast<MachineType>((use & kTypeMask) | output);
373 ProcessInput(node, 1, use_type); 358 ProcessInput(node, 1, use_type);
374 ProcessInput(node, 2, use_type); 359 ProcessInput(node, 2, use_type);
375 } 360 }
376 } 361 }
377 362
378 // Helper for handling phis. 363 // Helper for handling phis.
379 void VisitPhi(Node* node, MachineTypeUnion use, 364 void VisitPhi(Node* node, MachineTypeUnion use,
380 SimplifiedLowering* lowering) { 365 SimplifiedLowering* lowering) {
381 // Phis adapt to the output representation their uses demand, pushing 366 MachineType output = GetRepresentationForPhi(node, use);
382 // representation changes to their inputs. 367
383 Type* upper = NodeProperties::GetBounds(node).upper; 368 Type* upper = NodeProperties::GetBounds(node).upper;
384 MachineType output = kMachNone;
385 MachineType propagate = kMachNone;
386
387 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
388 // legal = kRepTagged | kRepFloat64 | kRepWord32;
389 if ((use & kRepMask) == kRepTagged) {
390 // only tagged uses.
391 output = kRepTagged;
392 propagate = kRepTagged;
393 } else if ((use & kRepMask) == kRepFloat64) {
394 // only float64 uses.
395 output = kRepFloat64;
396 propagate = kRepFloat64;
397 } else {
398 // multiple uses.
399 output = kRepWord32;
400 propagate = kRepWord32;
401 }
402 } else if (upper->Is(Type::Boolean())) {
403 // legal = kRepTagged | kRepBit;
404 if ((use & kRepMask) == kRepTagged) {
405 // only tagged uses.
406 output = kRepTagged;
407 propagate = kRepTagged;
408 } else {
409 // multiple uses.
410 output = kRepBit;
411 propagate = kRepBit;
412 }
413 } else if (upper->Is(Type::Number())) {
414 // legal = kRepTagged | kRepFloat64;
415 if ((use & kRepMask) == kRepTagged) {
416 // only tagged uses.
417 output = kRepTagged;
418 propagate = kRepTagged;
419 } else {
420 // multiple uses.
421 output = kRepFloat64;
422 propagate = kRepFloat64;
423 }
424 } else {
425 // legal = kRepTagged;
426 output = kRepTagged;
427 propagate = kRepTagged;
428 }
429
430 MachineType output_type = 369 MachineType output_type =
431 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); 370 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
432 SetOutput(node, output_type); 371 SetOutput(node, output_type);
433 372
434 int values = node->op()->ValueInputCount(); 373 int values = node->op()->ValueInputCount();
435 374
436 if (lower()) { 375 if (lower()) {
437 // Update the phi operator. 376 // Update the phi operator.
438 MachineType type = static_cast<MachineType>(output_type); 377 MachineType type = static_cast<MachineType>(output_type);
439 if (type != OpParameter<MachineType>(node)) { 378 if (type != OpParameter<MachineType>(node)) {
440 node->set_op(lowering->common()->Phi(type, values)); 379 node->set_op(lowering->common()->Phi(type, values));
441 } 380 }
442 381
443 // Convert inputs to the output representation of this phi. 382 // Convert inputs to the output representation of this phi.
444 Node::Inputs inputs = node->inputs(); 383 Node::Inputs inputs = node->inputs();
445 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); 384 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
446 ++iter, --values) { 385 ++iter, --values) {
447 // TODO(titzer): it'd be nice to have distinguished edge kinds here. 386 // TODO(titzer): it'd be nice to have distinguished edge kinds here.
448 ProcessInput(node, iter.index(), values > 0 ? output_type : 0); 387 ProcessInput(node, iter.index(), values > 0 ? output_type : 0);
449 } 388 }
450 } else { 389 } else {
451 // Propagate {use} of the phi to value inputs, and 0 to control. 390 // Propagate {use} of the phi to value inputs, and 0 to control.
452 Node::Inputs inputs = node->inputs(); 391 Node::Inputs inputs = node->inputs();
453 MachineType use_type = 392 MachineType use_type =
454 static_cast<MachineType>((use & kTypeMask) | propagate); 393 static_cast<MachineType>((use & kTypeMask) | output);
455 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); 394 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
456 ++iter, --values) { 395 ++iter, --values) {
457 // TODO(titzer): it'd be nice to have distinguished edge kinds here. 396 // TODO(titzer): it'd be nice to have distinguished edge kinds here.
458 ProcessInput(node, iter.index(), values > 0 ? use_type : 0); 397 ProcessInput(node, iter.index(), values > 0 ? use_type : 0);
459 } 398 }
460 } 399 }
461 } 400 }
462 401
463 const Operator* Int32Op(Node* node) { 402 const Operator* Int32Op(Node* node) {
464 return changer_->Int32OperatorFor(node->opcode()); 403 return changer_->Int32OperatorFor(node->opcode());
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 break; 657 break;
719 } 658 }
720 // => Float64Mod 659 // => Float64Mod
721 VisitFloat64Binop(node); 660 VisitFloat64Binop(node);
722 if (lower()) node->set_op(Float64Op(node)); 661 if (lower()) node->set_op(Float64Op(node));
723 break; 662 break;
724 } 663 }
725 case IrOpcode::kNumberToInt32: { 664 case IrOpcode::kNumberToInt32: {
726 MachineTypeUnion use_rep = use & kRepMask; 665 MachineTypeUnion use_rep = use & kRepMask;
727 Node* input = node->InputAt(0); 666 Node* input = node->InputAt(0);
667 Type* in_upper = NodeProperties::GetBounds(input).upper;
728 MachineTypeUnion in = GetInfo(input)->output; 668 MachineTypeUnion in = GetInfo(input)->output;
729 if (NodeProperties::GetBounds(input).upper->Is(Type::Signed32())) { 669 if (in_upper->Is(Type::Signed32())) {
730 // If the input has type int32, pass through representation. 670 // If the input has type int32, pass through representation.
731 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); 671 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
732 if (lower()) DeferReplacement(node, node->InputAt(0)); 672 if (lower()) DeferReplacement(node, node->InputAt(0));
733 } else if ((in & kTypeMask) == kTypeUint32 || 673 } else if ((in & kTypeMask) == kTypeUint32 ||
734 (in & kTypeMask) == kTypeInt32 || 674 (in & kTypeMask) == kTypeInt32 ||
675 in_upper->Is(Type::Unsigned32()) ||
735 (in & kRepMask) == kRepWord32) { 676 (in & kRepMask) == kRepWord32) {
736 // Just change representation if necessary. 677 // Just change representation if necessary.
737 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); 678 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32);
738 if (lower()) DeferReplacement(node, node->InputAt(0)); 679 if (lower()) DeferReplacement(node, node->InputAt(0));
739 } else { 680 } else {
740 // Require the input in float64 format and perform truncation. 681 // Require the input in float64 format and perform truncation.
741 // TODO(turbofan): avoid a truncation with a smi check. 682 // TODO(turbofan): avoid a truncation with a smi check.
742 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); 683 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
743 if (lower()) 684 if (lower())
744 node->set_op(lowering->machine()->TruncateFloat64ToInt32()); 685 node->set_op(lowering->machine()->TruncateFloat64ToInt32());
745 } 686 }
746 break; 687 break;
747 } 688 }
748 case IrOpcode::kNumberToUint32: { 689 case IrOpcode::kNumberToUint32: {
749 MachineTypeUnion use_rep = use & kRepMask; 690 MachineTypeUnion use_rep = use & kRepMask;
750 Node* input = node->InputAt(0); 691 Node* input = node->InputAt(0);
692 Type* in_upper = NodeProperties::GetBounds(input).upper;
751 MachineTypeUnion in = GetInfo(input)->output; 693 MachineTypeUnion in = GetInfo(input)->output;
752 if (NodeProperties::GetBounds(input).upper->Is(Type::Unsigned32())) { 694 if (in_upper->Is(Type::Unsigned32())) {
753 // If the input has type uint32, pass through representation. 695 // If the input has type uint32, pass through representation.
754 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); 696 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
755 if (lower()) DeferReplacement(node, node->InputAt(0)); 697 if (lower()) DeferReplacement(node, node->InputAt(0));
756 } else if ((in & kTypeMask) == kTypeUint32 || 698 } else if ((in & kTypeMask) == kTypeUint32 ||
757 (in & kTypeMask) == kTypeInt32 || 699 (in & kTypeMask) == kTypeInt32 ||
700 in_upper->Is(Type::Signed32()) ||
758 (in & kRepMask) == kRepWord32) { 701 (in & kRepMask) == kRepWord32) {
759 // Just change representation if necessary. 702 // Just change representation if necessary.
760 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); 703 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32);
761 if (lower()) DeferReplacement(node, node->InputAt(0)); 704 if (lower()) DeferReplacement(node, node->InputAt(0));
762 } else { 705 } else {
763 // Require the input in float64 format and perform truncation. 706 // Require the input in float64 format and perform truncation.
764 // TODO(turbofan): avoid a truncation with a smi check. 707 // TODO(turbofan): avoid a truncation with a smi check.
765 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); 708 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32);
766 if (lower()) 709 if (lower())
767 node->set_op(lowering->machine()->TruncateFloat64ToInt32()); 710 node->set_op(lowering->machine()->TruncateFloat64ToInt32());
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 1467
1525 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { 1468 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
1526 node->set_op(machine()->IntLessThanOrEqual()); 1469 node->set_op(machine()->IntLessThanOrEqual());
1527 node->ReplaceInput(0, StringComparison(node, true)); 1470 node->ReplaceInput(0, StringComparison(node, true));
1528 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1471 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1529 } 1472 }
1530 1473
1531 } // namespace compiler 1474 } // namespace compiler
1532 } // namespace internal 1475 } // namespace internal
1533 } // namespace v8 1476 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698