| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/hydrogen-instructions.h" | 5 #include "src/hydrogen-instructions.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/double.h" | 8 #include "src/double.h" |
| 9 #include "src/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 UpdateRepresentation(new_rep, h_infer, "uses"); | 67 UpdateRepresentation(new_rep, h_infer, "uses"); |
| 68 if (representation().IsSmi() && HasNonSmiUse()) { | 68 if (representation().IsSmi() && HasNonSmiUse()) { |
| 69 UpdateRepresentation( | 69 UpdateRepresentation( |
| 70 Representation::Integer32(), h_infer, "use requirements"); | 70 Representation::Integer32(), h_infer, "use requirements"); |
| 71 } | 71 } |
| 72 } | 72 } |
| 73 | 73 |
| 74 | 74 |
| 75 Representation HValue::RepresentationFromUses() { | 75 Representation HValue::RepresentationFromUses() { |
| 76 if (HasNoUses()) return Representation::None(); | 76 if (HasNoUses()) return Representation::None(); |
| 77 | 77 Representation result = Representation::None(); |
| 78 // Array of use counts for each representation. | |
| 79 int use_count[Representation::kNumRepresentations] = { 0 }; | |
| 80 | 78 |
| 81 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 79 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
| 82 HValue* use = it.value(); | 80 HValue* use = it.value(); |
| 83 Representation rep = use->observed_input_representation(it.index()); | 81 Representation rep = use->observed_input_representation(it.index()); |
| 84 if (rep.IsNone()) continue; | 82 result = result.generalize(rep); |
| 83 |
| 85 if (FLAG_trace_representation) { | 84 if (FLAG_trace_representation) { |
| 86 PrintF("#%d %s is used by #%d %s as %s%s\n", | 85 PrintF("#%d %s is used by #%d %s as %s%s\n", |
| 87 id(), Mnemonic(), use->id(), use->Mnemonic(), rep.Mnemonic(), | 86 id(), Mnemonic(), use->id(), use->Mnemonic(), rep.Mnemonic(), |
| 88 (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : "")); | 87 (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : "")); |
| 89 } | 88 } |
| 90 use_count[rep.kind()] += 1; | |
| 91 } | 89 } |
| 92 if (IsPhi()) HPhi::cast(this)->AddIndirectUsesTo(&use_count[0]); | 90 if (IsPhi()) { |
| 93 int tagged_count = use_count[Representation::kTagged]; | 91 result = result.generalize( |
| 94 int double_count = use_count[Representation::kDouble]; | 92 HPhi::cast(this)->representation_from_indirect_uses()); |
| 95 int int32_count = use_count[Representation::kInteger32]; | 93 } |
| 96 int smi_count = use_count[Representation::kSmi]; | |
| 97 | 94 |
| 98 if (tagged_count > 0) return Representation::Tagged(); | 95 // External representations are dealt with separately. |
| 99 if (double_count > 0) return Representation::Double(); | 96 return result.IsExternal() ? Representation::None() : result; |
| 100 if (int32_count > 0) return Representation::Integer32(); | |
| 101 if (smi_count > 0) return Representation::Smi(); | |
| 102 | |
| 103 return Representation::None(); | |
| 104 } | 97 } |
| 105 | 98 |
| 106 | 99 |
| 107 void HValue::UpdateRepresentation(Representation new_rep, | 100 void HValue::UpdateRepresentation(Representation new_rep, |
| 108 HInferRepresentationPhase* h_infer, | 101 HInferRepresentationPhase* h_infer, |
| 109 const char* reason) { | 102 const char* reason) { |
| 110 Representation r = representation(); | 103 Representation r = representation(); |
| 111 if (new_rep.is_more_general_than(r)) { | 104 if (new_rep.is_more_general_than(r)) { |
| 112 if (CheckFlag(kCannotBeTagged) && new_rep.IsTagged()) return; | 105 if (CheckFlag(kCannotBeTagged) && new_rep.IsTagged()) return; |
| 113 if (FLAG_trace_representation) { | 106 if (FLAG_trace_representation) { |
| (...skipping 2363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2477 inputs_.Add(NULL, value->block()->zone()); | 2470 inputs_.Add(NULL, value->block()->zone()); |
| 2478 SetOperandAt(OperandCount() - 1, value); | 2471 SetOperandAt(OperandCount() - 1, value); |
| 2479 } | 2472 } |
| 2480 | 2473 |
| 2481 | 2474 |
| 2482 std::ostream& HPhi::PrintTo(std::ostream& os) const { // NOLINT | 2475 std::ostream& HPhi::PrintTo(std::ostream& os) const { // NOLINT |
| 2483 os << "["; | 2476 os << "["; |
| 2484 for (int i = 0; i < OperandCount(); ++i) { | 2477 for (int i = 0; i < OperandCount(); ++i) { |
| 2485 os << " " << NameOf(OperandAt(i)) << " "; | 2478 os << " " << NameOf(OperandAt(i)) << " "; |
| 2486 } | 2479 } |
| 2487 return os << " uses:" << UseCount() << "_" | 2480 return os << " uses" << UseCount() |
| 2488 << smi_non_phi_uses() + smi_indirect_uses() << "s_" | 2481 << representation_from_indirect_uses().Mnemonic() << " " |
| 2489 << int32_non_phi_uses() + int32_indirect_uses() << "i_" | |
| 2490 << double_non_phi_uses() + double_indirect_uses() << "d_" | |
| 2491 << tagged_non_phi_uses() + tagged_indirect_uses() << "t" | |
| 2492 << TypeOf(this) << "]"; | 2482 << TypeOf(this) << "]"; |
| 2493 } | 2483 } |
| 2494 | 2484 |
| 2495 | 2485 |
| 2496 void HPhi::AddInput(HValue* value) { | 2486 void HPhi::AddInput(HValue* value) { |
| 2497 inputs_.Add(NULL, value->block()->zone()); | 2487 inputs_.Add(NULL, value->block()->zone()); |
| 2498 SetOperandAt(OperandCount() - 1, value); | 2488 SetOperandAt(OperandCount() - 1, value); |
| 2499 // Mark phis that may have 'arguments' directly or indirectly as an operand. | 2489 // Mark phis that may have 'arguments' directly or indirectly as an operand. |
| 2500 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { | 2490 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { |
| 2501 SetFlag(kIsArguments); | 2491 SetFlag(kIsArguments); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2540 phi_id_ = phi_id; | 2530 phi_id_ = phi_id; |
| 2541 // Compute a conservative approximation of truncating uses before inferring | 2531 // Compute a conservative approximation of truncating uses before inferring |
| 2542 // representations. The proper, exact computation will be done later, when | 2532 // representations. The proper, exact computation will be done later, when |
| 2543 // inserting representation changes. | 2533 // inserting representation changes. |
| 2544 SetFlag(kTruncatingToSmi); | 2534 SetFlag(kTruncatingToSmi); |
| 2545 SetFlag(kTruncatingToInt32); | 2535 SetFlag(kTruncatingToInt32); |
| 2546 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 2536 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
| 2547 HValue* value = it.value(); | 2537 HValue* value = it.value(); |
| 2548 if (!value->IsPhi()) { | 2538 if (!value->IsPhi()) { |
| 2549 Representation rep = value->observed_input_representation(it.index()); | 2539 Representation rep = value->observed_input_representation(it.index()); |
| 2550 non_phi_uses_[rep.kind()] += 1; | 2540 representation_from_non_phi_uses_ = |
| 2541 representation_from_non_phi_uses().generalize(rep); |
| 2542 if (rep.IsSmi() || rep.IsInteger32() || rep.IsDouble()) { |
| 2543 has_type_feedback_from_uses_ = true; |
| 2544 } |
| 2545 |
| 2551 if (FLAG_trace_representation) { | 2546 if (FLAG_trace_representation) { |
| 2552 PrintF("#%d Phi is used by real #%d %s as %s\n", | 2547 PrintF("#%d Phi is used by real #%d %s as %s\n", |
| 2553 id(), value->id(), value->Mnemonic(), rep.Mnemonic()); | 2548 id(), value->id(), value->Mnemonic(), rep.Mnemonic()); |
| 2554 } | 2549 } |
| 2555 if (!value->IsSimulate()) { | 2550 if (!value->IsSimulate()) { |
| 2556 if (!value->CheckFlag(kTruncatingToSmi)) { | 2551 if (!value->CheckFlag(kTruncatingToSmi)) { |
| 2557 ClearFlag(kTruncatingToSmi); | 2552 ClearFlag(kTruncatingToSmi); |
| 2558 } | 2553 } |
| 2559 if (!value->CheckFlag(kTruncatingToInt32)) { | 2554 if (!value->CheckFlag(kTruncatingToInt32)) { |
| 2560 ClearFlag(kTruncatingToInt32); | 2555 ClearFlag(kTruncatingToInt32); |
| 2561 } | 2556 } |
| 2562 } | 2557 } |
| 2563 } | 2558 } |
| 2564 } | 2559 } |
| 2565 } | 2560 } |
| 2566 | 2561 |
| 2567 | 2562 |
| 2568 void HPhi::AddNonPhiUsesFrom(HPhi* other) { | 2563 void HPhi::AddNonPhiUsesFrom(HPhi* other) { |
| 2569 if (FLAG_trace_representation) { | 2564 if (FLAG_trace_representation) { |
| 2570 PrintF("adding to #%d Phi uses of #%d Phi: s%d i%d d%d t%d\n", | 2565 PrintF( |
| 2571 id(), other->id(), | 2566 "generalizing use representation '%s' of #%d Phi " |
| 2572 other->non_phi_uses_[Representation::kSmi], | 2567 "with uses of #%d Phi '%s'\n", |
| 2573 other->non_phi_uses_[Representation::kInteger32], | 2568 representation_from_indirect_uses().Mnemonic(), id(), other->id(), |
| 2574 other->non_phi_uses_[Representation::kDouble], | 2569 other->representation_from_non_phi_uses().Mnemonic()); |
| 2575 other->non_phi_uses_[Representation::kTagged]); | |
| 2576 } | 2570 } |
| 2577 | 2571 |
| 2578 for (int i = 0; i < Representation::kNumRepresentations; i++) { | 2572 representation_from_indirect_uses_ = |
| 2579 indirect_uses_[i] += other->non_phi_uses_[i]; | 2573 representation_from_indirect_uses().generalize( |
| 2580 } | 2574 other->representation_from_non_phi_uses()); |
| 2581 } | 2575 } |
| 2582 | 2576 |
| 2583 | 2577 |
| 2584 void HPhi::AddIndirectUsesTo(int* dest) { | |
| 2585 for (int i = 0; i < Representation::kNumRepresentations; i++) { | |
| 2586 dest[i] += indirect_uses_[i]; | |
| 2587 } | |
| 2588 } | |
| 2589 | |
| 2590 | |
| 2591 void HSimulate::MergeWith(ZoneList<HSimulate*>* list) { | 2578 void HSimulate::MergeWith(ZoneList<HSimulate*>* list) { |
| 2592 while (!list->is_empty()) { | 2579 while (!list->is_empty()) { |
| 2593 HSimulate* from = list->RemoveLast(); | 2580 HSimulate* from = list->RemoveLast(); |
| 2594 ZoneList<HValue*>* from_values = &from->values_; | 2581 ZoneList<HValue*>* from_values = &from->values_; |
| 2595 for (int i = 0; i < from_values->length(); ++i) { | 2582 for (int i = 0; i < from_values->length(); ++i) { |
| 2596 if (from->HasAssignedIndexAt(i)) { | 2583 if (from->HasAssignedIndexAt(i)) { |
| 2597 int index = from->GetAssignedIndexAt(i); | 2584 int index = from->GetAssignedIndexAt(i); |
| 2598 if (HasValueForIndex(index)) continue; | 2585 if (HasValueForIndex(index)) continue; |
| 2599 AddAssignedValue(index, from_values->at(i)); | 2586 AddAssignedValue(index, from_values->at(i)); |
| 2600 } else { | 2587 } else { |
| (...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4415 Representation new_rep = RepresentationFromUses(); | 4402 Representation new_rep = RepresentationFromUses(); |
| 4416 UpdateRepresentation(new_rep, h_infer, "uses"); | 4403 UpdateRepresentation(new_rep, h_infer, "uses"); |
| 4417 new_rep = RepresentationFromInputs(); | 4404 new_rep = RepresentationFromInputs(); |
| 4418 UpdateRepresentation(new_rep, h_infer, "inputs"); | 4405 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 4419 new_rep = RepresentationFromUseRequirements(); | 4406 new_rep = RepresentationFromUseRequirements(); |
| 4420 UpdateRepresentation(new_rep, h_infer, "use requirements"); | 4407 UpdateRepresentation(new_rep, h_infer, "use requirements"); |
| 4421 } | 4408 } |
| 4422 | 4409 |
| 4423 | 4410 |
| 4424 Representation HPhi::RepresentationFromInputs() { | 4411 Representation HPhi::RepresentationFromInputs() { |
| 4425 bool has_type_feedback = | |
| 4426 smi_non_phi_uses() + int32_non_phi_uses() + double_non_phi_uses() > 0; | |
| 4427 Representation r = representation(); | 4412 Representation r = representation(); |
| 4428 for (int i = 0; i < OperandCount(); ++i) { | 4413 for (int i = 0; i < OperandCount(); ++i) { |
| 4429 // Ignore conservative Tagged assumption of parameters if we have | 4414 // Ignore conservative Tagged assumption of parameters if we have |
| 4430 // reason to believe that it's too conservative. | 4415 // reason to believe that it's too conservative. |
| 4431 if (has_type_feedback && OperandAt(i)->IsParameter()) continue; | 4416 if (has_type_feedback_from_uses() && OperandAt(i)->IsParameter()) { |
| 4417 continue; |
| 4418 } |
| 4432 | 4419 |
| 4433 r = r.generalize(OperandAt(i)->KnownOptimalRepresentation()); | 4420 r = r.generalize(OperandAt(i)->KnownOptimalRepresentation()); |
| 4434 } | 4421 } |
| 4435 return r; | 4422 return r; |
| 4436 } | 4423 } |
| 4437 | 4424 |
| 4438 | 4425 |
| 4439 // Returns a representation if all uses agree on the same representation. | 4426 // Returns a representation if all uses agree on the same representation. |
| 4440 // Integer32 is also returned when some uses are Smi but others are Integer32. | 4427 // Integer32 is also returned when some uses are Smi but others are Integer32. |
| 4441 Representation HValue::RepresentationFromUseRequirements() { | 4428 Representation HValue::RepresentationFromUseRequirements() { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4721 case HObjectAccess::kExternalMemory: | 4708 case HObjectAccess::kExternalMemory: |
| 4722 os << "[external-memory]"; | 4709 os << "[external-memory]"; |
| 4723 break; | 4710 break; |
| 4724 } | 4711 } |
| 4725 | 4712 |
| 4726 return os << "@" << access.offset(); | 4713 return os << "@" << access.offset(); |
| 4727 } | 4714 } |
| 4728 | 4715 |
| 4729 } // namespace internal | 4716 } // namespace internal |
| 4730 } // namespace v8 | 4717 } // namespace v8 |
| OLD | NEW |