OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |