Chromium Code Reviews| 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/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| 11 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
| 12 #include "src/compiler/diamond.h" | 12 #include "src/compiler/diamond.h" |
| 13 #include "src/compiler/linkage.h" | 13 #include "src/compiler/linkage.h" |
| 14 #include "src/compiler/node-matchers.h" | 14 #include "src/compiler/node-matchers.h" |
| 15 #include "src/compiler/node-properties.h" | 15 #include "src/compiler/node-properties.h" |
| 16 #include "src/compiler/operator-properties.h" | 16 #include "src/compiler/operator-properties.h" |
| 17 #include "src/compiler/representation-change.h" | 17 #include "src/compiler/representation-change.h" |
| 18 #include "src/compiler/simplified-lowering.h" | 18 #include "src/compiler/simplified-lowering.h" |
| 19 #include "src/compiler/simplified-operator.h" | 19 #include "src/compiler/simplified-operator.h" |
| 20 #include "src/compiler/source-position.h" | |
| 20 #include "src/objects.h" | 21 #include "src/objects.h" |
| 21 | 22 |
| 22 namespace v8 { | 23 namespace v8 { |
| 23 namespace internal { | 24 namespace internal { |
| 24 namespace compiler { | 25 namespace compiler { |
| 25 | 26 |
| 26 // Macro for outputting trace information from representation inference. | 27 // Macro for outputting trace information from representation inference. |
| 27 #define TRACE(x) \ | 28 #define TRACE(x) \ |
| 28 if (FLAG_trace_representation) PrintF x | 29 if (FLAG_trace_representation) PrintF x |
| 29 | 30 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 58 public: | 59 public: |
| 59 // Information for each node tracked during the fixpoint. | 60 // Information for each node tracked during the fixpoint. |
| 60 struct NodeInfo { | 61 struct NodeInfo { |
| 61 MachineTypeUnion use : 15; // Union of all usages for the node. | 62 MachineTypeUnion use : 15; // Union of all usages for the node. |
| 62 bool queued : 1; // Bookkeeping for the traversal. | 63 bool queued : 1; // Bookkeeping for the traversal. |
| 63 bool visited : 1; // Bookkeeping for the traversal. | 64 bool visited : 1; // Bookkeeping for the traversal. |
| 64 MachineTypeUnion output : 15; // Output type of the node. | 65 MachineTypeUnion output : 15; // Output type of the node. |
| 65 }; | 66 }; |
| 66 | 67 |
| 67 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 68 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
| 68 RepresentationChanger* changer) | 69 RepresentationChanger* changer, |
| 70 SourcePositionTable* source_positions) | |
| 69 : jsgraph_(jsgraph), | 71 : jsgraph_(jsgraph), |
| 70 count_(jsgraph->graph()->NodeCount()), | 72 count_(jsgraph->graph()->NodeCount()), |
| 71 info_(zone->NewArray<NodeInfo>(count_)), | 73 info_(zone->NewArray<NodeInfo>(count_)), |
| 72 nodes_(zone), | 74 nodes_(zone), |
| 73 replacements_(zone), | 75 replacements_(zone), |
| 74 phase_(PROPAGATE), | 76 phase_(PROPAGATE), |
| 75 changer_(changer), | 77 changer_(changer), |
| 76 queue_(zone) { | 78 queue_(zone), |
| 79 source_positions_(source_positions) { | |
| 77 memset(info_, 0, sizeof(NodeInfo) * count_); | 80 memset(info_, 0, sizeof(NodeInfo) * count_); |
| 78 | 81 |
| 79 safe_int_additive_range_ = | 82 safe_int_additive_range_ = |
| 80 Type::Range(-std::pow(2.0, 52.0), std::pow(2.0, 52.0), zone); | 83 Type::Range(-std::pow(2.0, 52.0), std::pow(2.0, 52.0), zone); |
| 81 } | 84 } |
| 82 | 85 |
| 83 void Run(SimplifiedLowering* lowering) { | 86 void Run(SimplifiedLowering* lowering) { |
| 84 // Run propagation phase to a fixpoint. | 87 // Run propagation phase to a fixpoint. |
| 85 TRACE(("--{Propagation phase}--\n")); | 88 TRACE(("--{Propagation phase}--\n")); |
| 86 phase_ = PROPAGATE; | 89 phase_ = PROPAGATE; |
| 87 Enqueue(jsgraph_->graph()->end()); | 90 Enqueue(jsgraph_->graph()->end()); |
| 88 // Process nodes from the queue until it is empty. | 91 // Process nodes from the queue until it is empty. |
| 89 while (!queue_.empty()) { | 92 while (!queue_.empty()) { |
| 90 Node* node = queue_.front(); | 93 Node* node = queue_.front(); |
| 91 NodeInfo* info = GetInfo(node); | 94 NodeInfo* info = GetInfo(node); |
| 92 queue_.pop(); | 95 queue_.pop(); |
| 93 info->queued = false; | 96 info->queued = false; |
| 94 TRACE((" visit #%d: %s\n", node->id(), node->op()->mnemonic())); | 97 TRACE((" visit #%d: %s\n", node->id(), node->op()->mnemonic())); |
| 98 SourcePositionTable::Scope scope( | |
|
titzer
2015/02/04 13:23:44
You shouldn't need the scope during the propagatio
danno
2015/02/04 13:42:17
Done.
| |
| 99 source_positions_, source_positions_->GetSourcePosition(node)); | |
| 95 VisitNode(node, info->use, NULL); | 100 VisitNode(node, info->use, NULL); |
| 96 TRACE((" ==> output ")); | 101 TRACE((" ==> output ")); |
| 97 PrintInfo(info->output); | 102 PrintInfo(info->output); |
| 98 TRACE(("\n")); | 103 TRACE(("\n")); |
| 99 } | 104 } |
| 100 | 105 |
| 101 // Run lowering and change insertion phase. | 106 // Run lowering and change insertion phase. |
| 102 TRACE(("--{Simplified lowering phase}--\n")); | 107 TRACE(("--{Simplified lowering phase}--\n")); |
| 103 phase_ = LOWER; | 108 phase_ = LOWER; |
| 104 // Process nodes from the collected {nodes_} vector. | 109 // Process nodes from the collected {nodes_} vector. |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 } | 452 } |
| 448 | 453 |
| 449 bool CanObserveNaN(MachineTypeUnion use) { | 454 bool CanObserveNaN(MachineTypeUnion use) { |
| 450 return (use & (kTypeNumber | kTypeAny)) != 0; | 455 return (use & (kTypeNumber | kTypeAny)) != 0; |
| 451 } | 456 } |
| 452 | 457 |
| 453 bool CanObserveNonUint32(MachineTypeUnion use) { | 458 bool CanObserveNonUint32(MachineTypeUnion use) { |
| 454 return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0; | 459 return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0; |
| 455 } | 460 } |
| 456 | 461 |
| 462 void VisitNode(Node* node, MachineTypeUnion use, | |
|
titzer
2015/02/04 13:23:44
I'd rather see this inlined into the second loop (
danno
2015/02/04 13:42:17
Done.
| |
| 463 SimplifiedLowering* lowering) { | |
| 464 if (FLAG_turbo_source_positions) { | |
| 465 SourcePositionTable::Scope scope( | |
| 466 source_positions_, source_positions_->GetSourcePosition(node)); | |
| 467 VisitNodeDispatch(node, use, lowering); | |
| 468 } else { | |
| 469 VisitNodeDispatch(node, use, lowering); | |
| 470 } | |
| 471 } | |
| 472 | |
| 457 // Dispatching routine for visiting the node {node} with the usage {use}. | 473 // Dispatching routine for visiting the node {node} with the usage {use}. |
| 458 // Depending on the operator, propagate new usage info to the inputs. | 474 // Depending on the operator, propagate new usage info to the inputs. |
| 459 void VisitNode(Node* node, MachineTypeUnion use, | 475 void VisitNodeDispatch(Node* node, MachineTypeUnion use, |
| 460 SimplifiedLowering* lowering) { | 476 SimplifiedLowering* lowering) { |
| 461 switch (node->opcode()) { | 477 switch (node->opcode()) { |
| 462 //------------------------------------------------------------------ | 478 //------------------------------------------------------------------ |
| 463 // Common operators. | 479 // Common operators. |
| 464 //------------------------------------------------------------------ | 480 //------------------------------------------------------------------ |
| 465 case IrOpcode::kStart: | 481 case IrOpcode::kStart: |
| 466 case IrOpcode::kDead: | 482 case IrOpcode::kDead: |
| 467 return VisitLeaf(node, 0); | 483 return VisitLeaf(node, 0); |
| 468 case IrOpcode::kParameter: { | 484 case IrOpcode::kParameter: { |
| 469 // TODO(titzer): use representation from linkage. | 485 // TODO(titzer): use representation from linkage. |
| 470 Type* upper = NodeProperties::GetBounds(node).upper; | 486 Type* upper = NodeProperties::GetBounds(node).upper; |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1064 | 1080 |
| 1065 private: | 1081 private: |
| 1066 JSGraph* jsgraph_; | 1082 JSGraph* jsgraph_; |
| 1067 int count_; // number of nodes in the graph | 1083 int count_; // number of nodes in the graph |
| 1068 NodeInfo* info_; // node id -> usage information | 1084 NodeInfo* info_; // node id -> usage information |
| 1069 NodeVector nodes_; // collected nodes | 1085 NodeVector nodes_; // collected nodes |
| 1070 NodeVector replacements_; // replacements to be done after lowering | 1086 NodeVector replacements_; // replacements to be done after lowering |
| 1071 Phase phase_; // current phase of algorithm | 1087 Phase phase_; // current phase of algorithm |
| 1072 RepresentationChanger* changer_; // for inserting representation changes | 1088 RepresentationChanger* changer_; // for inserting representation changes |
| 1073 ZoneQueue<Node*> queue_; // queue for traversing the graph | 1089 ZoneQueue<Node*> queue_; // queue for traversing the graph |
| 1090 // TODO(danno): RepresentationSelector shouldn't know anything about the | |
| 1091 // source positions table, but must for now since there currently is no other | |
| 1092 // way to pass down source position information to nodes created during | |
| 1093 // lowering. Once this phase becomes a vanilla reducer, it should get source | |
| 1094 // position information via the SourcePositionWrapper like all other reducers. | |
| 1095 SourcePositionTable* source_positions_; | |
| 1074 Type* safe_int_additive_range_; | 1096 Type* safe_int_additive_range_; |
| 1075 | 1097 |
| 1076 NodeInfo* GetInfo(Node* node) { | 1098 NodeInfo* GetInfo(Node* node) { |
| 1077 DCHECK(node->id() >= 0); | 1099 DCHECK(node->id() >= 0); |
| 1078 DCHECK(node->id() < count_); | 1100 DCHECK(node->id() < count_); |
| 1079 return &info_[node->id()]; | 1101 return &info_[node->id()]; |
| 1080 } | 1102 } |
| 1081 | 1103 |
| 1082 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } | 1104 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } |
| 1083 }; | 1105 }; |
| 1084 | 1106 |
| 1085 | 1107 |
| 1086 Node* SimplifiedLowering::IsTagged(Node* node) { | 1108 Node* SimplifiedLowering::IsTagged(Node* node) { |
| 1087 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 1109 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
| 1088 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. | 1110 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. |
| 1089 return graph()->NewNode(machine()->WordAnd(), node, | 1111 return graph()->NewNode(machine()->WordAnd(), node, |
| 1090 jsgraph()->Int32Constant(kSmiTagMask)); | 1112 jsgraph()->Int32Constant(kSmiTagMask)); |
| 1091 } | 1113 } |
| 1092 | 1114 |
| 1093 | 1115 |
| 1094 void SimplifiedLowering::LowerAllNodes() { | 1116 void SimplifiedLowering::LowerAllNodes() { |
| 1095 SimplifiedOperatorBuilder simplified(graph()->zone()); | 1117 SimplifiedOperatorBuilder simplified(graph()->zone()); |
| 1096 RepresentationChanger changer(jsgraph(), &simplified, jsgraph()->isolate()); | 1118 RepresentationChanger changer(jsgraph(), &simplified, jsgraph()->isolate()); |
| 1097 RepresentationSelector selector(jsgraph(), zone_, &changer); | 1119 RepresentationSelector selector(jsgraph(), zone_, &changer, |
| 1120 source_positions_); | |
| 1098 selector.Run(this); | 1121 selector.Run(this); |
| 1099 } | 1122 } |
| 1100 | 1123 |
| 1101 | 1124 |
| 1102 Node* SimplifiedLowering::Untag(Node* node) { | 1125 Node* SimplifiedLowering::Untag(Node* node) { |
| 1103 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 1126 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
| 1104 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); | 1127 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); |
| 1105 return graph()->NewNode(machine()->WordSar(), node, shift_amount); | 1128 return graph()->NewNode(machine()->WordSar(), node, shift_amount); |
| 1106 } | 1129 } |
| 1107 | 1130 |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1514 | 1537 |
| 1515 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1538 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
| 1516 node->set_op(machine()->IntLessThanOrEqual()); | 1539 node->set_op(machine()->IntLessThanOrEqual()); |
| 1517 node->ReplaceInput(0, StringComparison(node, true)); | 1540 node->ReplaceInput(0, StringComparison(node, true)); |
| 1518 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1541 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1519 } | 1542 } |
| 1520 | 1543 |
| 1521 } // namespace compiler | 1544 } // namespace compiler |
| 1522 } // namespace internal | 1545 } // namespace internal |
| 1523 } // namespace v8 | 1546 } // namespace v8 |
| OLD | NEW |