| 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" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 147 |
| 148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { | 148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { |
| 149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { | 153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { |
| 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
| 155 } | 155 } |
| 156 | 156 |
| 157 |
| 158 #ifdef DEBUG |
| 159 // Helpers for monotonicity checking. |
| 160 |
| 161 bool MachineTypeIsSubtype(MachineType t1, MachineType t2) { |
| 162 switch (t1) { |
| 163 case kMachNone: |
| 164 return true; |
| 165 case kTypeBool: |
| 166 return t2 == kTypeBool || t2 == kTypeNumber || t2 == kTypeAny; |
| 167 case kTypeInt32: |
| 168 return t2 == kTypeInt32 || t2 == kTypeNumber || t2 == kTypeAny; |
| 169 case kTypeUint32: |
| 170 return t2 == kTypeUint32 || t2 == kTypeNumber || t2 == kTypeAny; |
| 171 case kTypeInt64: |
| 172 return t2 == kTypeInt64; |
| 173 case kTypeUint64: |
| 174 return t2 == kTypeUint64; |
| 175 case kTypeNumber: |
| 176 return t2 == kTypeNumber || t2 == kTypeAny; |
| 177 case kTypeAny: |
| 178 return t2 == kTypeAny; |
| 179 default: |
| 180 break; |
| 181 } |
| 182 UNREACHABLE(); |
| 183 return false; |
| 184 } |
| 185 |
| 186 |
| 187 bool MachineRepresentationIsSubtype(MachineType r1, MachineType r2) { |
| 188 switch (r1) { |
| 189 case kMachNone: |
| 190 return true; |
| 191 case kRepBit: |
| 192 return r2 == kRepBit || r2 == kRepTagged; |
| 193 case kRepWord8: |
| 194 return r2 == kRepWord8 || r2 == kRepWord16 || r2 == kRepWord32 || |
| 195 r2 == kRepWord64 || r2 == kRepFloat32 || r2 == kRepFloat64 || |
| 196 r2 == kRepTagged; |
| 197 case kRepWord16: |
| 198 return r2 == kRepWord16 || r2 == kRepWord32 || r2 == kRepWord64 || |
| 199 r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; |
| 200 case kRepWord32: |
| 201 return r2 == kRepWord32 || r2 == kRepWord64 || r2 == kRepFloat64 || |
| 202 r2 == kRepTagged; |
| 203 case kRepWord64: |
| 204 return r2 == kRepWord64; |
| 205 case kRepFloat32: |
| 206 return r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; |
| 207 case kRepFloat64: |
| 208 return r2 == kRepFloat64 || r2 == kRepTagged; |
| 209 case kRepTagged: |
| 210 return r2 == kRepTagged; |
| 211 default: |
| 212 break; |
| 213 } |
| 214 UNREACHABLE(); |
| 215 return false; |
| 216 } |
| 217 |
| 218 |
| 219 bool MachineTypeRepIsSubtype(MachineTypeUnion m1, MachineTypeUnion m2) { |
| 220 return MachineTypeIsSubtype(static_cast<MachineType>(m1 & kTypeMask), |
| 221 static_cast<MachineType>(m2 & kTypeMask)) && |
| 222 MachineRepresentationIsSubtype( |
| 223 static_cast<MachineType>(m1 & kRepMask), |
| 224 static_cast<MachineType>(m2 & kRepMask)); |
| 225 } |
| 226 |
| 227 |
| 228 class InputUseInfos { |
| 229 public: |
| 230 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} |
| 231 |
| 232 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { |
| 233 if (input_use_infos_.empty()) { |
| 234 input_use_infos_.resize(node->InputCount(), UseInfo::None()); |
| 235 } |
| 236 // Check that the new use informatin is a super-type of the old |
| 237 // one. |
| 238 CHECK(IsUseLessGeneral(input_use_infos_[index], use_info)); |
| 239 input_use_infos_[index] = use_info; |
| 240 } |
| 241 |
| 242 private: |
| 243 ZoneVector<UseInfo> input_use_infos_; |
| 244 |
| 245 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) { |
| 246 return MachineRepresentationIsSubtype(use1.preferred(), use2.preferred()) && |
| 247 use1.truncation().IsLessGeneralThan(use2.truncation()); |
| 248 } |
| 249 }; |
| 250 |
| 251 #endif // DEBUG |
| 252 |
| 157 } // namespace | 253 } // namespace |
| 158 | 254 |
| 159 | 255 |
| 160 class RepresentationSelector { | 256 class RepresentationSelector { |
| 161 public: | 257 public: |
| 162 // Information for each node tracked during the fixpoint. | 258 // Information for each node tracked during the fixpoint. |
| 163 class NodeInfo { | 259 class NodeInfo { |
| 164 public: | 260 public: |
| 165 // Adds new use to the node. Returns true if something has changed | 261 // Adds new use to the node. Returns true if something has changed |
| 166 // and the node has to be requeued. | 262 // and the node has to be requeued. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 184 MachineTypeUnion output_ = kMachNone; // Output type of the node. | 280 MachineTypeUnion output_ = kMachNone; // Output type of the node. |
| 185 Truncation truncation_ = Truncation::None(); // Information about uses. | 281 Truncation truncation_ = Truncation::None(); // Information about uses. |
| 186 }; | 282 }; |
| 187 | 283 |
| 188 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 284 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
| 189 RepresentationChanger* changer, | 285 RepresentationChanger* changer, |
| 190 SourcePositionTable* source_positions) | 286 SourcePositionTable* source_positions) |
| 191 : jsgraph_(jsgraph), | 287 : jsgraph_(jsgraph), |
| 192 count_(jsgraph->graph()->NodeCount()), | 288 count_(jsgraph->graph()->NodeCount()), |
| 193 info_(count_, zone), | 289 info_(count_, zone), |
| 290 #ifdef DEBUG |
| 291 node_input_use_infos_(count_, InputUseInfos(zone), zone), |
| 292 #endif |
| 194 nodes_(zone), | 293 nodes_(zone), |
| 195 replacements_(zone), | 294 replacements_(zone), |
| 196 phase_(PROPAGATE), | 295 phase_(PROPAGATE), |
| 197 changer_(changer), | 296 changer_(changer), |
| 198 queue_(zone), | 297 queue_(zone), |
| 199 source_positions_(source_positions), | 298 source_positions_(source_positions), |
| 200 type_cache_(TypeCache::Get()) {} | 299 type_cache_(TypeCache::Get()) { |
| 300 } |
| 201 | 301 |
| 202 void Run(SimplifiedLowering* lowering) { | 302 void Run(SimplifiedLowering* lowering) { |
| 203 // Run propagation phase to a fixpoint. | 303 // Run propagation phase to a fixpoint. |
| 204 TRACE("--{Propagation phase}--\n"); | 304 TRACE("--{Propagation phase}--\n"); |
| 205 phase_ = PROPAGATE; | 305 phase_ = PROPAGATE; |
| 206 Enqueue(jsgraph_->graph()->end()); | 306 EnqueueInitial(jsgraph_->graph()->end()); |
| 207 // Process nodes from the queue until it is empty. | 307 // Process nodes from the queue until it is empty. |
| 208 while (!queue_.empty()) { | 308 while (!queue_.empty()) { |
| 209 Node* node = queue_.front(); | 309 Node* node = queue_.front(); |
| 210 NodeInfo* info = GetInfo(node); | 310 NodeInfo* info = GetInfo(node); |
| 211 queue_.pop(); | 311 queue_.pop(); |
| 212 info->set_queued(false); | 312 info->set_queued(false); |
| 213 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); | 313 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); |
| 214 VisitNode(node, info->truncation(), NULL); | 314 VisitNode(node, info->truncation(), NULL); |
| 215 TRACE(" ==> output "); | 315 TRACE(" ==> output "); |
| 216 PrintInfo(info->output_type()); | 316 PrintInfo(info->output_type()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 238 Node* replacement = *(++i); | 338 Node* replacement = *(++i); |
| 239 node->ReplaceUses(replacement); | 339 node->ReplaceUses(replacement); |
| 240 // We also need to replace the node in the rest of the vector. | 340 // We also need to replace the node in the rest of the vector. |
| 241 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { | 341 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { |
| 242 ++j; | 342 ++j; |
| 243 if (*j == node) *j = replacement; | 343 if (*j == node) *j = replacement; |
| 244 } | 344 } |
| 245 } | 345 } |
| 246 } | 346 } |
| 247 | 347 |
| 248 // Enqueue {node} if the {use} contains new information for that node. | 348 void EnqueueInitial(Node* node) { |
| 249 // Add {node} to {nodes_} if this is the first time it's been visited. | 349 NodeInfo* info = GetInfo(node); |
| 250 void Enqueue(Node* node, UseInfo use_info = UseInfo::None()) { | 350 info->set_visited(); |
| 351 info->set_queued(true); |
| 352 nodes_.push_back(node); |
| 353 queue_.push(node); |
| 354 } |
| 355 |
| 356 // Enqueue {use_node}'s {index} input if the {use} contains new information |
| 357 // for that input node. Add the input to {nodes_} if this is the first time |
| 358 // it's been visited. |
| 359 void EnqueueInput(Node* use_node, int index, |
| 360 UseInfo use_info = UseInfo::None()) { |
| 361 Node* node = use_node->InputAt(index); |
| 251 if (phase_ != PROPAGATE) return; | 362 if (phase_ != PROPAGATE) return; |
| 252 NodeInfo* info = GetInfo(node); | 363 NodeInfo* info = GetInfo(node); |
| 364 #ifdef DEBUG |
| 365 // Check monotonicity of input requirements. |
| 366 node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index, |
| 367 use_info); |
| 368 #endif // DEBUG |
| 253 if (!info->visited()) { | 369 if (!info->visited()) { |
| 254 // First visit of this node. | 370 // First visit of this node. |
| 255 info->set_visited(); | 371 info->set_visited(); |
| 256 info->set_queued(true); | 372 info->set_queued(true); |
| 257 nodes_.push_back(node); | 373 nodes_.push_back(node); |
| 258 queue_.push(node); | 374 queue_.push(node); |
| 259 TRACE(" initial: "); | 375 TRACE(" initial: "); |
| 260 info->AddUse(use_info); | 376 info->AddUse(use_info); |
| 261 PrintTruncation(info->truncation()); | 377 PrintTruncation(info->truncation()); |
| 262 return; | 378 return; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 277 } | 393 } |
| 278 | 394 |
| 279 bool lower() { return phase_ == LOWER; } | 395 bool lower() { return phase_ == LOWER; } |
| 280 | 396 |
| 281 void SetOutput(Node* node, MachineTypeUnion output) { | 397 void SetOutput(Node* node, MachineTypeUnion output) { |
| 282 // Every node should have at most one output representation. Note that | 398 // Every node should have at most one output representation. Note that |
| 283 // phis can have 0, if they have not been used in a representation-inducing | 399 // phis can have 0, if they have not been used in a representation-inducing |
| 284 // instruction. | 400 // instruction. |
| 285 DCHECK((output & kRepMask) == 0 || | 401 DCHECK((output & kRepMask) == 0 || |
| 286 base::bits::IsPowerOfTwo32(output & kRepMask)); | 402 base::bits::IsPowerOfTwo32(output & kRepMask)); |
| 287 GetInfo(node)->set_output_type(output); | 403 NodeInfo* info = GetInfo(node); |
| 404 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); |
| 405 info->set_output_type(output); |
| 288 } | 406 } |
| 289 | 407 |
| 290 bool BothInputsAre(Node* node, Type* type) { | 408 bool BothInputsAre(Node* node, Type* type) { |
| 291 DCHECK_EQ(2, node->InputCount()); | 409 DCHECK_EQ(2, node->InputCount()); |
| 292 return NodeProperties::GetType(node->InputAt(0))->Is(type) && | 410 return NodeProperties::GetType(node->InputAt(0))->Is(type) && |
| 293 NodeProperties::GetType(node->InputAt(1))->Is(type); | 411 NodeProperties::GetType(node->InputAt(1))->Is(type); |
| 294 } | 412 } |
| 295 | 413 |
| 296 void EnqueueInputUse(Node* node, int index, UseInfo use) { | |
| 297 Enqueue(node->InputAt(index), use); | |
| 298 } | |
| 299 | |
| 300 void ConvertInput(Node* node, int index, UseInfo use) { | 414 void ConvertInput(Node* node, int index, UseInfo use) { |
| 301 Node* input = node->InputAt(index); | 415 Node* input = node->InputAt(index); |
| 302 // In the change phase, insert a change before the use if necessary. | 416 // In the change phase, insert a change before the use if necessary. |
| 303 if (use.preferred() == kMachNone) | 417 if (use.preferred() == kMachNone) |
| 304 return; // No input requirement on the use. | 418 return; // No input requirement on the use. |
| 305 MachineTypeUnion output = GetInfo(input)->output_type(); | 419 MachineTypeUnion output = GetInfo(input)->output_type(); |
| 306 if ((output & kRepMask) != use.preferred()) { | 420 if ((output & kRepMask) != use.preferred()) { |
| 307 // Output representation doesn't match usage. | 421 // Output representation doesn't match usage. |
| 308 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), | 422 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), |
| 309 index, input->id(), input->op()->mnemonic()); | 423 index, input->id(), input->op()->mnemonic()); |
| 310 TRACE(" from "); | 424 TRACE(" from "); |
| 311 PrintInfo(output); | 425 PrintInfo(output); |
| 312 TRACE(" to "); | 426 TRACE(" to "); |
| 313 PrintUseInfo(use); | 427 PrintUseInfo(use); |
| 314 TRACE("\n"); | 428 TRACE("\n"); |
| 315 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), | 429 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), |
| 316 use.truncation()); | 430 use.truncation()); |
| 317 node->ReplaceInput(index, n); | 431 node->ReplaceInput(index, n); |
| 318 } | 432 } |
| 319 } | 433 } |
| 320 | 434 |
| 321 void ProcessInput(Node* node, int index, UseInfo use) { | 435 void ProcessInput(Node* node, int index, UseInfo use) { |
| 322 if (phase_ == PROPAGATE) { | 436 if (phase_ == PROPAGATE) { |
| 323 EnqueueInputUse(node, index, use); | 437 EnqueueInput(node, index, use); |
| 324 } else { | 438 } else { |
| 325 ConvertInput(node, index, use); | 439 ConvertInput(node, index, use); |
| 326 } | 440 } |
| 327 } | 441 } |
| 328 | 442 |
| 329 void ProcessRemainingInputs(Node* node, int index) { | 443 void ProcessRemainingInputs(Node* node, int index) { |
| 330 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); | 444 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); |
| 331 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); | 445 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); |
| 332 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); | 446 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); |
| 333 i < NodeProperties::PastEffectIndex(node); ++i) { | 447 i < NodeProperties::PastEffectIndex(node); ++i) { |
| 334 Enqueue(node->InputAt(i)); // Effect inputs: just visit | 448 EnqueueInput(node, i); // Effect inputs: just visit |
| 335 } | 449 } |
| 336 for (int i = std::max(index, NodeProperties::FirstControlIndex(node)); | 450 for (int i = std::max(index, NodeProperties::FirstControlIndex(node)); |
| 337 i < NodeProperties::PastControlIndex(node); ++i) { | 451 i < NodeProperties::PastControlIndex(node); ++i) { |
| 338 Enqueue(node->InputAt(i)); // Control inputs: just visit | 452 EnqueueInput(node, i); // Control inputs: just visit |
| 339 } | 453 } |
| 340 } | 454 } |
| 341 | 455 |
| 342 // The default, most general visitation case. For {node}, process all value, | 456 // The default, most general visitation case. For {node}, process all value, |
| 343 // context, frame state, effect, and control inputs, assuming that value | 457 // context, frame state, effect, and control inputs, assuming that value |
| 344 // inputs should have {kRepTagged} representation and can observe all output | 458 // inputs should have {kRepTagged} representation and can observe all output |
| 345 // values {kTypeAny}. | 459 // values {kTypeAny}. |
| 346 void VisitInputs(Node* node) { | 460 void VisitInputs(Node* node) { |
| 347 int tagged_count = node->op()->ValueInputCount() + | 461 int tagged_count = node->op()->ValueInputCount() + |
| 348 OperatorProperties::GetContextInputCount(node->op()); | 462 OperatorProperties::GetContextInputCount(node->op()); |
| 349 // Visit value and context inputs as tagged. | 463 // Visit value and context inputs as tagged. |
| 350 for (int i = 0; i < tagged_count; i++) { | 464 for (int i = 0; i < tagged_count; i++) { |
| 351 ProcessInput(node, i, UseInfo::AnyTagged()); | 465 ProcessInput(node, i, UseInfo::AnyTagged()); |
| 352 } | 466 } |
| 353 // Only enqueue other inputs (framestates, effects, control). | 467 // Only enqueue other inputs (framestates, effects, control). |
| 354 for (int i = tagged_count; i < node->InputCount(); i++) { | 468 for (int i = tagged_count; i < node->InputCount(); i++) { |
| 355 Enqueue(node->InputAt(i)); | 469 EnqueueInput(node, i); |
| 356 } | 470 } |
| 357 // Assume the output is tagged. | |
| 358 SetOutput(node, kMachAnyTagged); | |
| 359 } | 471 } |
| 360 | 472 |
| 361 // Helper for binops of the R x L -> O variety. | 473 // Helper for binops of the R x L -> O variety. |
| 362 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 474 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
| 363 MachineTypeUnion output) { | 475 MachineTypeUnion output) { |
| 364 DCHECK_EQ(2, node->op()->ValueInputCount()); | 476 DCHECK_EQ(2, node->op()->ValueInputCount()); |
| 365 ProcessInput(node, 0, left_use); | 477 ProcessInput(node, 0, left_use); |
| 366 ProcessInput(node, 1, right_use); | 478 ProcessInput(node, 1, right_use); |
| 367 for (int i = 2; i < node->InputCount(); i++) { | 479 for (int i = 2; i < node->InputCount(); i++) { |
| 368 Enqueue(node->InputAt(i)); | 480 EnqueueInput(node, i); |
| 369 } | 481 } |
| 370 SetOutput(node, output); | 482 SetOutput(node, output); |
| 371 } | 483 } |
| 372 | 484 |
| 373 // Helper for binops of the I x I -> O variety. | 485 // Helper for binops of the I x I -> O variety. |
| 374 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { | 486 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { |
| 375 VisitBinop(node, input_use, input_use, output); | 487 VisitBinop(node, input_use, input_use, output); |
| 376 } | 488 } |
| 377 | 489 |
| 378 // Helper for unops of the I -> O variety. | 490 // Helper for unops of the I -> O variety. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 if (sig->return_count() > 0) { | 628 if (sig->return_count() > 0) { |
| 517 SetOutput(node, desc->GetMachineSignature()->GetReturn()); | 629 SetOutput(node, desc->GetMachineSignature()->GetReturn()); |
| 518 } else { | 630 } else { |
| 519 SetOutput(node, kMachAnyTagged); | 631 SetOutput(node, kMachAnyTagged); |
| 520 } | 632 } |
| 521 } | 633 } |
| 522 | 634 |
| 523 void VisitStateValues(Node* node) { | 635 void VisitStateValues(Node* node) { |
| 524 if (phase_ == PROPAGATE) { | 636 if (phase_ == PROPAGATE) { |
| 525 for (int i = 0; i < node->InputCount(); i++) { | 637 for (int i = 0; i < node->InputCount(); i++) { |
| 526 Enqueue(node->InputAt(i), UseInfo::Any()); | 638 EnqueueInput(node, i, UseInfo::Any()); |
| 527 } | 639 } |
| 528 } else { | 640 } else { |
| 529 Zone* zone = jsgraph_->zone(); | 641 Zone* zone = jsgraph_->zone(); |
| 530 ZoneVector<MachineType>* types = | 642 ZoneVector<MachineType>* types = |
| 531 new (zone->New(sizeof(ZoneVector<MachineType>))) | 643 new (zone->New(sizeof(ZoneVector<MachineType>))) |
| 532 ZoneVector<MachineType>(node->InputCount(), zone); | 644 ZoneVector<MachineType>(node->InputCount(), zone); |
| 533 for (int i = 0; i < node->InputCount(); i++) { | 645 for (int i = 0; i < node->InputCount(); i++) { |
| 534 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); | 646 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); |
| 535 (*types)[i] = static_cast<MachineType>(input_type); | 647 (*types)[i] = static_cast<MachineType>(input_type); |
| 536 } | 648 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 return VisitLeaf(node, kRepFloat64); | 718 return VisitLeaf(node, kRepFloat64); |
| 607 case IrOpcode::kExternalConstant: | 719 case IrOpcode::kExternalConstant: |
| 608 return VisitLeaf(node, kMachPtr); | 720 return VisitLeaf(node, kMachPtr); |
| 609 case IrOpcode::kNumberConstant: | 721 case IrOpcode::kNumberConstant: |
| 610 return VisitLeaf(node, kRepTagged); | 722 return VisitLeaf(node, kRepTagged); |
| 611 case IrOpcode::kHeapConstant: | 723 case IrOpcode::kHeapConstant: |
| 612 return VisitLeaf(node, kRepTagged); | 724 return VisitLeaf(node, kRepTagged); |
| 613 | 725 |
| 614 case IrOpcode::kBranch: | 726 case IrOpcode::kBranch: |
| 615 ProcessInput(node, 0, UseInfo::Bool()); | 727 ProcessInput(node, 0, UseInfo::Bool()); |
| 616 Enqueue(NodeProperties::GetControlInput(node, 0)); | 728 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
| 617 break; | 729 break; |
| 618 case IrOpcode::kSwitch: | 730 case IrOpcode::kSwitch: |
| 619 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 731 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
| 620 Enqueue(NodeProperties::GetControlInput(node, 0)); | 732 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
| 621 break; | 733 break; |
| 622 case IrOpcode::kSelect: | 734 case IrOpcode::kSelect: |
| 623 return VisitSelect(node, truncation, lowering); | 735 return VisitSelect(node, truncation, lowering); |
| 624 case IrOpcode::kPhi: | 736 case IrOpcode::kPhi: |
| 625 return VisitPhi(node, truncation, lowering); | 737 return VisitPhi(node, truncation, lowering); |
| 626 case IrOpcode::kCall: | 738 case IrOpcode::kCall: |
| 627 return VisitCall(node, lowering); | 739 return VisitCall(node, lowering); |
| 628 | 740 |
| 629 //------------------------------------------------------------------ | 741 //------------------------------------------------------------------ |
| 630 // JavaScript operators. | 742 // JavaScript operators. |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), | 1209 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), |
| 1098 kMachFloat64); | 1210 kMachFloat64); |
| 1099 case IrOpcode::kLoadStackPointer: | 1211 case IrOpcode::kLoadStackPointer: |
| 1100 case IrOpcode::kLoadFramePointer: | 1212 case IrOpcode::kLoadFramePointer: |
| 1101 return VisitLeaf(node, kMachPtr); | 1213 return VisitLeaf(node, kMachPtr); |
| 1102 case IrOpcode::kStateValues: | 1214 case IrOpcode::kStateValues: |
| 1103 VisitStateValues(node); | 1215 VisitStateValues(node); |
| 1104 break; | 1216 break; |
| 1105 default: | 1217 default: |
| 1106 VisitInputs(node); | 1218 VisitInputs(node); |
| 1219 // Assume the output is tagged. |
| 1220 SetOutput(node, kMachAnyTagged); |
| 1107 break; | 1221 break; |
| 1108 } | 1222 } |
| 1109 } | 1223 } |
| 1110 | 1224 |
| 1111 void DeferReplacement(Node* node, Node* replacement) { | 1225 void DeferReplacement(Node* node, Node* replacement) { |
| 1112 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), | 1226 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), |
| 1113 node->op()->mnemonic(), replacement->id(), | 1227 node->op()->mnemonic(), replacement->id(), |
| 1114 replacement->op()->mnemonic()); | 1228 replacement->op()->mnemonic()); |
| 1115 | 1229 |
| 1116 if (replacement->id() < count_ && | 1230 if (replacement->id() < count_ && |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1147 if (FLAG_trace_representation) { | 1261 if (FLAG_trace_representation) { |
| 1148 OFStream os(stdout); | 1262 OFStream os(stdout); |
| 1149 os << info.preferred() << ":" << info.truncation().description(); | 1263 os << info.preferred() << ":" << info.truncation().description(); |
| 1150 } | 1264 } |
| 1151 } | 1265 } |
| 1152 | 1266 |
| 1153 private: | 1267 private: |
| 1154 JSGraph* jsgraph_; | 1268 JSGraph* jsgraph_; |
| 1155 size_t const count_; // number of nodes in the graph | 1269 size_t const count_; // number of nodes in the graph |
| 1156 ZoneVector<NodeInfo> info_; // node id -> usage information | 1270 ZoneVector<NodeInfo> info_; // node id -> usage information |
| 1271 #ifdef DEBUG |
| 1272 ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about |
| 1273 // requirements on inputs. |
| 1274 #endif // DEBUG |
| 1157 NodeVector nodes_; // collected nodes | 1275 NodeVector nodes_; // collected nodes |
| 1158 NodeVector replacements_; // replacements to be done after lowering | 1276 NodeVector replacements_; // replacements to be done after lowering |
| 1159 Phase phase_; // current phase of algorithm | 1277 Phase phase_; // current phase of algorithm |
| 1160 RepresentationChanger* changer_; // for inserting representation changes | 1278 RepresentationChanger* changer_; // for inserting representation changes |
| 1161 ZoneQueue<Node*> queue_; // queue for traversing the graph | 1279 ZoneQueue<Node*> queue_; // queue for traversing the graph |
| 1162 // TODO(danno): RepresentationSelector shouldn't know anything about the | 1280 // TODO(danno): RepresentationSelector shouldn't know anything about the |
| 1163 // source positions table, but must for now since there currently is no other | 1281 // source positions table, but must for now since there currently is no other |
| 1164 // way to pass down source position information to nodes created during | 1282 // way to pass down source position information to nodes created during |
| 1165 // lowering. Once this phase becomes a vanilla reducer, it should get source | 1283 // lowering. Once this phase becomes a vanilla reducer, it should get source |
| 1166 // position information via the SourcePositionWrapper like all other reducers. | 1284 // position information via the SourcePositionWrapper like all other reducers. |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 ReplaceEffectUses(node, comparison); | 1728 ReplaceEffectUses(node, comparison); |
| 1611 node->ReplaceInput(0, comparison); | 1729 node->ReplaceInput(0, comparison); |
| 1612 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1730 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1613 node->TrimInputCount(2); | 1731 node->TrimInputCount(2); |
| 1614 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1732 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
| 1615 } | 1733 } |
| 1616 | 1734 |
| 1617 } // namespace compiler | 1735 } // namespace compiler |
| 1618 } // namespace internal | 1736 } // namespace internal |
| 1619 } // namespace v8 | 1737 } // namespace v8 |
| OLD | NEW |