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

Side by Side Diff: src/compiler/simplified-lowering.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/representation-change.h ('k') | src/compiler/typer.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/address-map.h" 9 #include "src/address-map.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // 1.) PROPAGATE: Traverse the graph from the end, pushing usage information 44 // 1.) PROPAGATE: Traverse the graph from the end, pushing usage information
45 // backwards from uses to definitions, around cycles in phis, according 45 // backwards from uses to definitions, around cycles in phis, according
46 // to local rules for each operator. 46 // to local rules for each operator.
47 // During this phase, the usage information for a node determines the best 47 // During this phase, the usage information for a node determines the best
48 // possible lowering for each operator so far, and that in turn determines 48 // possible lowering for each operator so far, and that in turn determines
49 // the output representation. 49 // the output representation.
50 // Therefore, to be correct, this phase must iterate to a fixpoint before 50 // Therefore, to be correct, this phase must iterate to a fixpoint before
51 // the next phase can begin. 51 // the next phase can begin.
52 PROPAGATE, 52 PROPAGATE,
53 53
54 // 2.) LOWER: perform lowering for all {Simplified} nodes by replacing some 54 // 2.) RETYPE: Propagate types from type feedback forwards.
55 RETYPE,
56
57 // 3.) LOWER: perform lowering for all {Simplified} nodes by replacing some
55 // operators for some nodes, expanding some nodes to multiple nodes, or 58 // operators for some nodes, expanding some nodes to multiple nodes, or
56 // removing some (redundant) nodes. 59 // removing some (redundant) nodes.
57 // During this phase, use the {RepresentationChanger} to insert 60 // During this phase, use the {RepresentationChanger} to insert
58 // representation changes between uses that demand a particular 61 // representation changes between uses that demand a particular
59 // representation and nodes that produce a different representation. 62 // representation and nodes that produce a different representation.
60 LOWER 63 LOWER
61 }; 64 };
62 65
63
64 namespace { 66 namespace {
65 67
66 68
67 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) { 69 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
68 switch (rep) { 70 switch (rep) {
69 case MachineRepresentation::kTagged: 71 case MachineRepresentation::kTagged:
70 return UseInfo::AnyTagged(); 72 return UseInfo::AnyTagged();
71 case MachineRepresentation::kFloat64: 73 case MachineRepresentation::kFloat64:
72 return UseInfo::TruncatingFloat64(); 74 return UseInfo::TruncatingFloat64();
73 case MachineRepresentation::kFloat32: 75 case MachineRepresentation::kFloat32:
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 changer_(changer), 241 changer_(changer),
240 queue_(zone), 242 queue_(zone),
241 typing_stack_(zone), 243 typing_stack_(zone),
242 source_positions_(source_positions), 244 source_positions_(source_positions),
243 type_cache_(TypeCache::Get()), 245 type_cache_(TypeCache::Get()),
244 op_typer_(jsgraph->isolate(), graph_zone()) { 246 op_typer_(jsgraph->isolate(), graph_zone()) {
245 } 247 }
246 248
247 // Forward propagation of types from type feedback. 249 // Forward propagation of types from type feedback.
248 void RunTypePropagationPhase() { 250 void RunTypePropagationPhase() {
251 // Run type propagation.
252 TRACE("--{Type propagation phase}--\n");
253 phase_ = RETYPE;
254 ResetNodeInfoState();
255
249 DCHECK(typing_stack_.empty()); 256 DCHECK(typing_stack_.empty());
250
251 typing_stack_.push({graph()->end(), 0}); 257 typing_stack_.push({graph()->end(), 0});
252 GetInfo(graph()->end())->set_pushed(); 258 GetInfo(graph()->end())->set_pushed();
253 while (!typing_stack_.empty()) { 259 while (!typing_stack_.empty()) {
254 NodeState& current = typing_stack_.top(); 260 NodeState& current = typing_stack_.top();
255 261
256 // If there is an unvisited input, push it and continue. 262 // If there is an unvisited input, push it and continue.
257 bool pushed_unvisited = false; 263 bool pushed_unvisited = false;
258 while (current.input_index < current.node->InputCount()) { 264 while (current.input_index < current.node->InputCount()) {
259 Node* input = current.node->InputAt(current.input_index); 265 Node* input = current.node->InputAt(current.input_index);
260 NodeInfo* input_info = GetInfo(input); 266 NodeInfo* input_info = GetInfo(input);
261 current.input_index++; 267 current.input_index++;
262 if (input_info->unvisited()) { 268 if (input_info->unvisited()) {
263 input_info->set_pushed(); 269 input_info->set_pushed();
264 typing_stack_.push({input, 0}); 270 typing_stack_.push({input, 0});
265 pushed_unvisited = true; 271 pushed_unvisited = true;
266 break; 272 break;
267 } 273 }
268 } 274 }
269 if (pushed_unvisited) continue; 275 if (pushed_unvisited) continue;
270 276
271 // Process the top of the stack. 277 // Process the top of the stack.
272 Node* node = current.node; 278 Node* node = current.node;
273 typing_stack_.pop(); 279 typing_stack_.pop();
274 NodeInfo* info = GetInfo(node); 280 NodeInfo* info = GetInfo(node);
275 info->set_visited(); 281 info->set_visited();
276 bool updated = UpdateFeedbackType(node); 282 bool updated = UpdateFeedbackType(node);
283 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
284 VisitNode(node, info->truncation(), nullptr);
277 if (updated) { 285 if (updated) {
278 for (Node* const user : node->uses()) { 286 for (Node* const user : node->uses()) {
279 if (GetInfo(user)->visited()) { 287 if (GetInfo(user)->visited()) {
280 GetInfo(user)->set_queued(); 288 GetInfo(user)->set_queued();
281 queue_.push(user); 289 queue_.push(user);
282 } 290 }
283 } 291 }
284 } 292 }
285 } 293 }
286 294
287 // Process the revisit queue. 295 // Process the revisit queue.
288 while (!queue_.empty()) { 296 while (!queue_.empty()) {
289 Node* node = queue_.front(); 297 Node* node = queue_.front();
290 queue_.pop(); 298 queue_.pop();
291 NodeInfo* info = GetInfo(node); 299 NodeInfo* info = GetInfo(node);
292 info->set_visited(); 300 info->set_visited();
293 bool updated = UpdateFeedbackType(node); 301 bool updated = UpdateFeedbackType(node);
302 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
303 VisitNode(node, info->truncation(), nullptr);
294 if (updated) { 304 if (updated) {
295 for (Node* const user : node->uses()) { 305 for (Node* const user : node->uses()) {
296 if (GetInfo(user)->visited()) { 306 if (GetInfo(user)->visited()) {
297 GetInfo(user)->set_queued(); 307 GetInfo(user)->set_queued();
298 queue_.push(user); 308 queue_.push(user);
299 } 309 }
300 } 310 }
301 } 311 }
302 } 312 }
303 } 313 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 } 379 }
370 380
371 switch (node->opcode()) { 381 switch (node->opcode()) {
372 case IrOpcode::kSpeculativeNumberAdd: { 382 case IrOpcode::kSpeculativeNumberAdd: {
373 // TODO(jarin) The ToNumber conversion is too conservative here, 383 // TODO(jarin) The ToNumber conversion is too conservative here,
374 // e.g. it will treat true as 1 even though the number check will 384 // e.g. it will treat true as 1 even though the number check will
375 // fail on a boolean. OperationTyper should have a function that 385 // fail on a boolean. OperationTyper should have a function that
376 // computes a more precise type. 386 // computes a more precise type.
377 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); 387 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
378 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); 388 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
379 Type* static_type = op_typer_.NumericAdd(lhs, rhs); 389 Type* static_type = op_typer_.NumberAdd(lhs, rhs);
380 if (info->type_check() == TypeCheckKind::kNone) { 390 if (info->type_check() == TypeCheckKind::kNone) {
381 new_type = static_type; 391 new_type = static_type;
382 } else { 392 } else {
383 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); 393 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
384 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); 394 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
385 } 395 }
386 break; 396 break;
387 } 397 }
388 398
389 case IrOpcode::kSpeculativeNumberSubtract: { 399 case IrOpcode::kSpeculativeNumberSubtract: {
390 // TODO(jarin) The ToNumber conversion is too conservative here, 400 // TODO(jarin) The ToNumber conversion is too conservative here,
391 // e.g. it will treat true as 1 even though the number check will 401 // e.g. it will treat true as 1 even though the number check will
392 // fail on a boolean. OperationTyper should have a function that 402 // fail on a boolean. OperationTyper should have a function that
393 // computes a more precise type. 403 // computes a more precise type.
394 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); 404 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
395 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); 405 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
396 Type* static_type = op_typer_.NumericSubtract(lhs, rhs); 406 Type* static_type = op_typer_.NumberSubtract(lhs, rhs);
397 if (info->type_check() == TypeCheckKind::kNone) { 407 if (info->type_check() == TypeCheckKind::kNone) {
398 new_type = static_type; 408 new_type = static_type;
399 } else { 409 } else {
400 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); 410 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
401 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); 411 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
402 } 412 }
403 break; 413 break;
404 } 414 }
405 415
406 case IrOpcode::kSpeculativeNumberMultiply: { 416 case IrOpcode::kSpeculativeNumberMultiply: {
407 // TODO(jarin) The ToNumber conversion is too conservative here, 417 // TODO(jarin) The ToNumber conversion is too conservative here,
408 // e.g. it will treat true as 1 even though the number check will 418 // e.g. it will treat true as 1 even though the number check will
409 // fail on a boolean. OperationTyper should have a function that 419 // fail on a boolean. OperationTyper should have a function that
410 // computes a more precise type. 420 // computes a more precise type.
411 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); 421 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
412 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); 422 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
413 Type* static_type = op_typer_.NumericMultiply(lhs, rhs); 423 Type* static_type = op_typer_.NumberMultiply(lhs, rhs);
414 if (info->type_check() == TypeCheckKind::kNone) { 424 if (info->type_check() == TypeCheckKind::kNone) {
415 new_type = static_type; 425 new_type = static_type;
416 } else { 426 } else {
417 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); 427 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
418 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); 428 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
419 } 429 }
420 break; 430 break;
421 } 431 }
422 432
423 case IrOpcode::kSpeculativeNumberDivide: { 433 case IrOpcode::kSpeculativeNumberDivide: {
424 // TODO(jarin) The ToNumber conversion is too conservative here, 434 // TODO(jarin) The ToNumber conversion is too conservative here,
425 // e.g. it will treat true as 1 even though the number check will 435 // e.g. it will treat true as 1 even though the number check will
426 // fail on a boolean. OperationTyper should have a function that 436 // fail on a boolean. OperationTyper should have a function that
427 // computes a more precise type. 437 // computes a more precise type.
428 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); 438 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
429 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); 439 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
430 Type* static_type = op_typer_.NumericDivide(lhs, rhs); 440 Type* static_type = op_typer_.NumberDivide(lhs, rhs);
431 if (info->type_check() == TypeCheckKind::kNone) { 441 if (info->type_check() == TypeCheckKind::kNone) {
432 new_type = static_type; 442 new_type = static_type;
433 } else { 443 } else {
434 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); 444 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
435 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); 445 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
436 } 446 }
437 break; 447 break;
438 } 448 }
439 449
440 case IrOpcode::kSpeculativeNumberModulus: { 450 case IrOpcode::kSpeculativeNumberModulus: {
441 // TODO(jarin) The ToNumber conversion is too conservative here, 451 // TODO(jarin) The ToNumber conversion is too conservative here,
442 // e.g. it will treat true as 1 even though the number check will 452 // e.g. it will treat true as 1 even though the number check will
443 // fail on a boolean. OperationTyper should have a function that 453 // fail on a boolean. OperationTyper should have a function that
444 // computes a more precise type. 454 // computes a more precise type.
445 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); 455 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
446 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); 456 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
447 Type* static_type = op_typer_.NumericModulus(lhs, rhs); 457 Type* static_type = op_typer_.NumberModulus(lhs, rhs);
448 if (info->type_check() == TypeCheckKind::kNone) { 458 if (info->type_check() == TypeCheckKind::kNone) {
449 new_type = static_type; 459 new_type = static_type;
450 } else { 460 } else {
451 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); 461 Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
452 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); 462 new_type = Type::Intersect(static_type, feedback_type, graph_zone());
453 } 463 }
454 break; 464 break;
455 } 465 }
456 466
467 case IrOpcode::kNumberAbs: {
468 new_type = op_typer_.NumberAbs(FeedbackTypeOf(node->InputAt(0)));
469 break;
470 }
471
457 case IrOpcode::kPhi: { 472 case IrOpcode::kPhi: {
458 new_type = TypePhi(node); 473 new_type = TypePhi(node);
459 if (type != nullptr) { 474 if (type != nullptr) {
460 new_type = Weaken(node, type, new_type); 475 new_type = Weaken(node, type, new_type);
461 } 476 }
462 // Recompute the phi representation based on the new type.
463 MachineRepresentation output =
464 GetOutputInfoForPhi(node, GetInfo(node)->truncation(), new_type);
465 ResetOutput(node, output);
466 break; 477 break;
467 } 478 }
468 479
469 case IrOpcode::kSelect: { 480 case IrOpcode::kSelect: {
470 new_type = TypeSelect(node); 481 new_type = TypeSelect(node);
471 // Recompute representation based on the new type.
472 MachineRepresentation output =
473 GetOutputInfoForPhi(node, GetInfo(node)->truncation(), new_type);
474 ResetOutput(node, output);
475 break; 482 break;
476 } 483 }
477 484
478 default: 485 default:
479 // Shortcut for operations that we do not handle. 486 // Shortcut for operations that we do not handle.
480 if (type == nullptr) { 487 if (type == nullptr) {
481 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node)); 488 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
482 return true; 489 return true;
483 } 490 }
484 return false; 491 return false;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 VisitNode(node, info->truncation(), nullptr); 569 VisitNode(node, info->truncation(), nullptr);
563 TRACE(" ==> output "); 570 TRACE(" ==> output ");
564 PrintOutputInfo(info); 571 PrintOutputInfo(info);
565 TRACE("\n"); 572 TRACE("\n");
566 } 573 }
567 } 574 }
568 575
569 void Run(SimplifiedLowering* lowering) { 576 void Run(SimplifiedLowering* lowering) {
570 RunTruncationPropagationPhase(); 577 RunTruncationPropagationPhase();
571 578
572 // Run type propagation.
573 ResetNodeInfoState();
574 RunTypePropagationPhase(); 579 RunTypePropagationPhase();
575 580
576 // Run lowering and change insertion phase. 581 // Run lowering and change insertion phase.
577 TRACE("--{Simplified lowering phase}--\n"); 582 TRACE("--{Simplified lowering phase}--\n");
578 phase_ = LOWER; 583 phase_ = LOWER;
579 // Process nodes from the collected {nodes_} vector. 584 // Process nodes from the collected {nodes_} vector.
580 for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) { 585 for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
581 Node* node = *i; 586 Node* node = *i;
582 NodeInfo* info = GetInfo(node); 587 NodeInfo* info = GetInfo(node);
583 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); 588 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 queue_.push(node); 645 queue_.push(node);
641 info->set_queued(); 646 info->set_queued();
642 TRACE(" added: "); 647 TRACE(" added: ");
643 } else { 648 } else {
644 TRACE(" inqueue: "); 649 TRACE(" inqueue: ");
645 } 650 }
646 PrintTruncation(info->truncation()); 651 PrintTruncation(info->truncation());
647 } 652 }
648 } 653 }
649 654
650 bool lower() { return phase_ == LOWER; } 655 bool lower() const { return phase_ == LOWER; }
651 bool propagate() { return phase_ == PROPAGATE; } 656 bool retype() const { return phase_ == RETYPE; }
657 bool propagate() const { return phase_ == PROPAGATE; }
652 658
653 void SetOutput(Node* node, MachineRepresentation representation, 659 void SetOutput(Node* node, MachineRepresentation representation,
654 TypeCheckKind type_check = TypeCheckKind::kNone) { 660 TypeCheckKind type_check = TypeCheckKind::kNone) {
655 DCHECK(MachineRepresentationIsSubtype(GetInfo(node)->representation(), 661 NodeInfo* const info = GetInfo(node);
656 representation)); 662 switch (phase_) {
657 ResetOutput(node, representation, type_check); 663 case PROPAGATE:
664 info->set_type_check(type_check);
665 break;
666 case RETYPE:
667 DCHECK_EQ(info->type_check(), type_check);
668 info->set_output(representation);
669 break;
670 case LOWER:
671 DCHECK_EQ(info->type_check(), type_check);
672 DCHECK_EQ(info->representation(), representation);
673 break;
674 }
658 } 675 }
659 676
660 void ResetOutput(Node* node, MachineRepresentation representation, 677 void ResetOutput(Node* node, MachineRepresentation representation,
661 TypeCheckKind type_check = TypeCheckKind::kNone) { 678 TypeCheckKind type_check = TypeCheckKind::kNone) {
662 NodeInfo* info = GetInfo(node); 679 NodeInfo* info = GetInfo(node);
663 info->set_output(representation); 680 info->set_output(representation);
664 info->set_type_check(type_check); 681 info->set_type_check(type_check);
665 } 682 }
666 683
667 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); } 684 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 TRACE(" to "); 725 TRACE(" to ");
709 PrintUseInfo(use); 726 PrintUseInfo(use);
710 TRACE("\n"); 727 TRACE("\n");
711 Node* n = changer_->GetRepresentationFor( 728 Node* n = changer_->GetRepresentationFor(
712 input, input_info->representation(), TypeOf(input), node, use); 729 input, input_info->representation(), TypeOf(input), node, use);
713 node->ReplaceInput(index, n); 730 node->ReplaceInput(index, n);
714 } 731 }
715 } 732 }
716 733
717 void ProcessInput(Node* node, int index, UseInfo use) { 734 void ProcessInput(Node* node, int index, UseInfo use) {
718 if (phase_ == PROPAGATE) { 735 switch (phase_) {
719 EnqueueInput(node, index, use); 736 case PROPAGATE:
720 } else { 737 EnqueueInput(node, index, use);
721 ConvertInput(node, index, use); 738 break;
739 case RETYPE:
740 break;
741 case LOWER:
742 ConvertInput(node, index, use);
743 break;
722 } 744 }
723 } 745 }
724 746
725 void ProcessRemainingInputs(Node* node, int index) { 747 void ProcessRemainingInputs(Node* node, int index) {
726 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); 748 DCHECK_GE(index, NodeProperties::PastValueIndex(node));
727 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); 749 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
728 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); 750 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
729 i < NodeProperties::PastEffectIndex(node); ++i) { 751 i < NodeProperties::PastEffectIndex(node); ++i) {
730 EnqueueInput(node, i); // Effect inputs: just visit 752 EnqueueInput(node, i); // Effect inputs: just visit
731 } 753 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); 842 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit);
821 } 843 }
822 void VisitInt64Cmp(Node* node) { 844 void VisitInt64Cmp(Node* node) {
823 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); 845 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit);
824 } 846 }
825 void VisitUint64Cmp(Node* node) { 847 void VisitUint64Cmp(Node* node) {
826 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); 848 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit);
827 } 849 }
828 850
829 // Infer representation for phi-like nodes. 851 // Infer representation for phi-like nodes.
830 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use, 852 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use) {
831 Type* type = nullptr) {
832 // Compute the representation. 853 // Compute the representation.
833 if (type == nullptr) { 854 Type* type = TypeOf(node);
834 type = TypeOf(node);
835 }
836 if (type->Is(Type::None())) { 855 if (type->Is(Type::None())) {
837 return MachineRepresentation::kNone; 856 return MachineRepresentation::kNone;
838 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { 857 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
839 return MachineRepresentation::kWord32; 858 return MachineRepresentation::kWord32;
840 } else if (use.TruncatesToWord32()) { 859 } else if (use.TruncatesToWord32()) {
841 return MachineRepresentation::kWord32; 860 return MachineRepresentation::kWord32;
842 } else if (type->Is(Type::Boolean())) { 861 } else if (type->Is(Type::Boolean())) {
843 return MachineRepresentation::kBit; 862 return MachineRepresentation::kBit;
844 } else if (type->Is(Type::Number())) { 863 } else if (type->Is(Type::Number())) {
845 return MachineRepresentation::kFloat64; 864 return MachineRepresentation::kFloat64;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 if (type->Is(Type::Signed32())) { 961 if (type->Is(Type::Signed32())) {
943 return MachineSemantic::kInt32; 962 return MachineSemantic::kInt32;
944 } else if (type->Is(Type::Unsigned32())) { 963 } else if (type->Is(Type::Unsigned32())) {
945 return MachineSemantic::kUint32; 964 return MachineSemantic::kUint32;
946 } else { 965 } else {
947 return MachineSemantic::kAny; 966 return MachineSemantic::kAny;
948 } 967 }
949 } 968 }
950 969
951 void VisitStateValues(Node* node) { 970 void VisitStateValues(Node* node) {
952 if (phase_ == PROPAGATE) { 971 if (propagate()) {
953 for (int i = 0; i < node->InputCount(); i++) { 972 for (int i = 0; i < node->InputCount(); i++) {
954 EnqueueInput(node, i, UseInfo::Any()); 973 EnqueueInput(node, i, UseInfo::Any());
955 } 974 }
956 } else { 975 } else if (lower()) {
957 Zone* zone = jsgraph_->zone(); 976 Zone* zone = jsgraph_->zone();
958 ZoneVector<MachineType>* types = 977 ZoneVector<MachineType>* types =
959 new (zone->New(sizeof(ZoneVector<MachineType>))) 978 new (zone->New(sizeof(ZoneVector<MachineType>)))
960 ZoneVector<MachineType>(node->InputCount(), zone); 979 ZoneVector<MachineType>(node->InputCount(), zone);
961 for (int i = 0; i < node->InputCount(); i++) { 980 for (int i = 0; i < node->InputCount(); i++) {
962 Node* input = node->InputAt(i); 981 Node* input = node->InputAt(i);
963 NodeInfo* input_info = GetInfo(input); 982 NodeInfo* input_info = GetInfo(input);
964 MachineType machine_type(input_info->representation(), 983 MachineType machine_type(input_info->representation(),
965 DeoptValueSemanticOf(TypeOf(input))); 984 DeoptValueSemanticOf(TypeOf(input)));
966 DCHECK(machine_type.representation() != 985 DCHECK(machine_type.representation() !=
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 case IrOpcode::kNumberShiftRightLogical: { 1608 case IrOpcode::kNumberShiftRightLogical: {
1590 Type* rhs_type = GetUpperBound(node->InputAt(1)); 1609 Type* rhs_type = GetUpperBound(node->InputAt(1));
1591 VisitBinop(node, UseInfo::TruncatingWord32(), 1610 VisitBinop(node, UseInfo::TruncatingWord32(),
1592 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 1611 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1593 if (lower()) { 1612 if (lower()) {
1594 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); 1613 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
1595 } 1614 }
1596 return; 1615 return;
1597 } 1616 }
1598 case IrOpcode::kNumberAbs: { 1617 case IrOpcode::kNumberAbs: {
1599 if (InputIs(node, Type::Unsigned32())) { 1618 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32())) {
1600 VisitUnop(node, UseInfo::TruncatingWord32(), 1619 VisitUnop(node, UseInfo::TruncatingWord32(),
1601 MachineRepresentation::kWord32); 1620 MachineRepresentation::kWord32);
1602 if (lower()) DeferReplacement(node, node->InputAt(0)); 1621 if (lower()) DeferReplacement(node, node->InputAt(0));
1603 } else if (InputIs(node, Type::Signed32())) { 1622 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32())) {
1604 VisitUnop(node, UseInfo::TruncatingWord32(), 1623 VisitUnop(node, UseInfo::TruncatingWord32(),
1605 MachineRepresentation::kWord32); 1624 MachineRepresentation::kWord32);
1606 if (lower()) DeferReplacement(node, lowering->Int32Abs(node)); 1625 if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
1607 } else if (InputIs(node, 1626 } else if (TypeOf(node->InputAt(0))
1608 type_cache_.kPositiveIntegerOrMinusZeroOrNaN)) { 1627 ->Is(type_cache_.kPositiveIntegerOrMinusZeroOrNaN)) {
1609 VisitUnop(node, UseInfo::TruncatingFloat64(), 1628 VisitUnop(node, UseInfo::TruncatingFloat64(),
1610 MachineRepresentation::kFloat64); 1629 MachineRepresentation::kFloat64);
1611 if (lower()) DeferReplacement(node, node->InputAt(0)); 1630 if (lower()) DeferReplacement(node, node->InputAt(0));
1612 } else { 1631 } else {
1613 VisitUnop(node, UseInfo::TruncatingFloat64(), 1632 VisitUnop(node, UseInfo::TruncatingFloat64(),
1614 MachineRepresentation::kFloat64); 1633 MachineRepresentation::kFloat64);
1615 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1634 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1616 } 1635 }
1617 return; 1636 return;
1618 } 1637 }
(...skipping 1667 matching lines...) Expand 10 before | Expand all | Expand 10 after
3286 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3305 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3287 Operator::kNoProperties); 3306 Operator::kNoProperties);
3288 to_number_operator_.set(common()->Call(desc)); 3307 to_number_operator_.set(common()->Call(desc));
3289 } 3308 }
3290 return to_number_operator_.get(); 3309 return to_number_operator_.get();
3291 } 3310 }
3292 3311
3293 } // namespace compiler 3312 } // namespace compiler
3294 } // namespace internal 3313 } // namespace internal
3295 } // namespace v8 3314 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698