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

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

Powered by Google App Engine
This is Rietveld 408576698