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 |