| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 63 |
| 64 bool Value::Equals(Value* other) const { | 64 bool Value::Equals(Value* other) const { |
| 65 return definition() == other->definition(); | 65 return definition() == other->definition(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 | 68 |
| 69 CheckClassInstr::CheckClassInstr(Value* value, | 69 CheckClassInstr::CheckClassInstr(Value* value, |
| 70 intptr_t deopt_id, | 70 intptr_t deopt_id, |
| 71 const ICData& unary_checks) | 71 const ICData& unary_checks) |
| 72 : unary_checks_(unary_checks) { | 72 : unary_checks_(unary_checks) { |
| 73 ASSERT(value != NULL); | |
| 74 ASSERT(unary_checks.IsZoneHandle()); | 73 ASSERT(unary_checks.IsZoneHandle()); |
| 75 // Expected useful check data. | 74 // Expected useful check data. |
| 76 ASSERT(!unary_checks_.IsNull() && | 75 ASSERT(!unary_checks_.IsNull()); |
| 77 (unary_checks_.NumberOfChecks() > 0) && | 76 ASSERT(unary_checks_.NumberOfChecks() > 0); |
| 78 (unary_checks_.num_args_tested() == 1)); | 77 ASSERT(unary_checks_.num_args_tested() == 1); |
| 79 inputs_[0] = value; | 78 SetInputAt(0, value); |
| 80 deopt_id_ = deopt_id; | 79 deopt_id_ = deopt_id; |
| 81 // Otherwise use CheckSmiInstr. | 80 // Otherwise use CheckSmiInstr. |
| 82 ASSERT((unary_checks_.NumberOfChecks() != 1) || | 81 ASSERT((unary_checks_.NumberOfChecks() != 1) || |
| 83 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); | 82 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); |
| 84 } | 83 } |
| 85 | 84 |
| 86 | 85 |
| 87 bool CheckClassInstr::AttributesEqual(Instruction* other) const { | 86 bool CheckClassInstr::AttributesEqual(Instruction* other) const { |
| 88 CheckClassInstr* other_check = other->AsCheckClass(); | 87 CheckClassInstr* other_check = other->AsCheckClass(); |
| 89 ASSERT(other_check != NULL); | 88 ASSERT(other_check != NULL); |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 } | 527 } |
| 529 } | 528 } |
| 530 | 529 |
| 531 | 530 |
| 532 void Definition::ReplaceWith(Definition* other, | 531 void Definition::ReplaceWith(Definition* other, |
| 533 ForwardInstructionIterator* iterator) { | 532 ForwardInstructionIterator* iterator) { |
| 534 // Record other's input uses. | 533 // Record other's input uses. |
| 535 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { | 534 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { |
| 536 Value* input = other->InputAt(i); | 535 Value* input = other->InputAt(i); |
| 537 input->definition()->AddInputUse(input); | 536 input->definition()->AddInputUse(input); |
| 538 input->set_instruction(other); | |
| 539 input->set_use_index(i); | |
| 540 } | 537 } |
| 541 // Take other's environment from this definition. | 538 // Take other's environment from this definition. |
| 542 ASSERT(other->env() == NULL); | 539 ASSERT(other->env() == NULL); |
| 543 intptr_t use_index = 0; | 540 intptr_t use_index = 0; |
| 544 for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { | 541 for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { |
| 545 Value* use = it.CurrentValue(); | 542 Value* use = it.CurrentValue(); |
| 546 use->set_instruction(other); | 543 use->set_instruction(other); |
| 547 use->set_use_index(use_index++); | 544 use->set_use_index(use_index++); |
| 548 } | 545 } |
| 549 other->set_env(env()); | 546 other->set_env(env()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 563 other->LinkTo(this); | 560 other->LinkTo(this); |
| 564 iterator->RemoveCurrentFromGraph(); | 561 iterator->RemoveCurrentFromGraph(); |
| 565 } else { | 562 } else { |
| 566 other->LinkTo(next()); | 563 other->LinkTo(next()); |
| 567 } | 564 } |
| 568 set_previous(NULL); | 565 set_previous(NULL); |
| 569 set_next(NULL); | 566 set_next(NULL); |
| 570 } | 567 } |
| 571 | 568 |
| 572 | 569 |
| 570 BranchInstr::BranchInstr(ComparisonInstr* comparison, bool is_checked) |
| 571 : comparison_(comparison), is_checked_(is_checked) { |
| 572 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) { |
| 573 comparison->InputAt(i)->set_instruction(this); |
| 574 } |
| 575 } |
| 576 |
| 577 |
| 578 void BranchInstr::RawSetInputAt(intptr_t i, Value* value) { |
| 579 comparison()->RawSetInputAt(i, value); |
| 580 } |
| 581 |
| 582 |
| 573 // A misleadingly named function for use in template functions that replace | 583 // A misleadingly named function for use in template functions that replace |
| 574 // both definitions with definitions and branch comparisons with | 584 // both definitions with definitions and branch comparisons with |
| 575 // comparisons. In the branch case, leave the branch intact and replace its | 585 // comparisons. In the branch case, leave the branch intact and replace its |
| 576 // comparison with another comparison. | 586 // comparison with another comparison. |
| 577 void BranchInstr::ReplaceWith(ComparisonInstr* other, | 587 void BranchInstr::ReplaceWith(ComparisonInstr* other, |
| 578 ForwardInstructionIterator* ignored) { | 588 ForwardInstructionIterator* ignored) { |
| 579 // Record the new comparison's input uses. | 589 // Record the new comparison's input uses. |
| 580 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { | 590 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { |
| 581 Value* input = other->InputAt(i); | 591 Value* input = other->InputAt(i); |
| 582 input->definition()->AddInputUse(input); | 592 input->definition()->AddInputUse(input); |
| 583 } | 593 } |
| 584 SetComparison(other); | 594 SetComparison(other); |
| 585 } | 595 } |
| 586 | 596 |
| 587 | 597 |
| 588 void BranchInstr::SetComparison(ComparisonInstr* comp) { | 598 void BranchInstr::SetComparison(ComparisonInstr* comp) { |
| 589 // The new comparison's input uses are already recorded in their | 599 // The new comparison's input uses are already recorded in their |
| 590 // definition's use lists. | 600 // definition's use lists. |
| 591 for (intptr_t i = comp->InputCount() - 1; i >= 0; --i) { | 601 for (intptr_t i = comp->InputCount() - 1; i >= 0; --i) { |
| 592 Value* input = comp->InputAt(i); | 602 comp->InputAt(i)->set_instruction(this); |
| 593 input->set_instruction(this); | |
| 594 input->set_use_index(i); | |
| 595 } | 603 } |
| 596 // There should be no need to copy or unuse an environment. | 604 // There should be no need to copy or unuse an environment. |
| 597 ASSERT(comparison()->env() == NULL); | 605 ASSERT(comparison()->env() == NULL); |
| 598 // Remove the current comparison's input uses. | 606 // Remove the current comparison's input uses. |
| 599 comparison()->UnuseAllInputs(); | 607 comparison()->UnuseAllInputs(); |
| 600 ASSERT(!comp->HasUses()); | 608 ASSERT(!comp->HasUses()); |
| 601 comparison_ = comp; | 609 comparison_ = comp; |
| 602 } | 610 } |
| 603 | 611 |
| 604 | 612 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 PhiInstr* phi = (*join->phis())[i]; | 756 PhiInstr* phi = (*join->phis())[i]; |
| 749 if (phi == NULL) continue; | 757 if (phi == NULL) continue; |
| 750 ASSERT(pred_count == phi->InputCount()); | 758 ASSERT(pred_count == phi->InputCount()); |
| 751 // Save the predecessor use. | 759 // Save the predecessor use. |
| 752 Value* pred_use = phi->InputAt(old_index); | 760 Value* pred_use = phi->InputAt(old_index); |
| 753 // Move uses between old and new. | 761 // Move uses between old and new. |
| 754 intptr_t step = (old_index < new_index) ? 1 : -1; | 762 intptr_t step = (old_index < new_index) ? 1 : -1; |
| 755 for (intptr_t use_idx = old_index; | 763 for (intptr_t use_idx = old_index; |
| 756 use_idx != new_index; | 764 use_idx != new_index; |
| 757 use_idx += step) { | 765 use_idx += step) { |
| 758 Value* use = phi->InputAt(use_idx + step); | 766 phi->SetInputAt(use_idx, phi->InputAt(use_idx + step)); |
| 759 phi->SetInputAt(use_idx, use); | |
| 760 use->set_use_index(use_idx); | |
| 761 } | 767 } |
| 762 // Write the predecessor use. | 768 // Write the predecessor use. |
| 763 phi->SetInputAt(new_index, pred_use); | 769 phi->SetInputAt(new_index, pred_use); |
| 764 pred_use->set_use_index(new_index); | |
| 765 } | 770 } |
| 766 } | 771 } |
| 767 } | 772 } |
| 768 | 773 |
| 769 | 774 |
| 770 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { | 775 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { |
| 771 // Lazily initialize the array of phis. | 776 // Lazily initialize the array of phis. |
| 772 // Currently, phis are stored in a sparse array that holds the phi | 777 // Currently, phis are stored in a sparse array that holds the phi |
| 773 // for variable with index i at position i. | 778 // for variable with index i at position i. |
| 774 // TODO(fschneider): Store phis in a more compact way. | 779 // TODO(fschneider): Store phis in a more compact way. |
| (...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2164 case kExternalUint8ArrayCid: | 2169 case kExternalUint8ArrayCid: |
| 2165 case kExternalUint8ClampedArrayCid: | 2170 case kExternalUint8ClampedArrayCid: |
| 2166 return ByteArray::length_offset(); | 2171 return ByteArray::length_offset(); |
| 2167 default: | 2172 default: |
| 2168 UNREACHABLE(); | 2173 UNREACHABLE(); |
| 2169 return -1; | 2174 return -1; |
| 2170 } | 2175 } |
| 2171 } | 2176 } |
| 2172 | 2177 |
| 2173 | 2178 |
| 2179 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( |
| 2180 ZoneGrowableArray<Value*>* inputs, |
| 2181 InstanceCallInstr* instance_call, |
| 2182 MethodRecognizer::Kind recognized_kind) |
| 2183 : inputs_(inputs), |
| 2184 locs_(NULL), |
| 2185 recognized_kind_(recognized_kind) { |
| 2186 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); |
| 2187 for (intptr_t i = 0; i < inputs_->length(); ++i) { |
| 2188 ASSERT((*inputs)[i] != NULL); |
| 2189 (*inputs)[i]->set_instruction(this); |
| 2190 (*inputs)[i]->set_use_index(i); |
| 2191 } |
| 2192 deopt_id_ = instance_call->deopt_id(); |
| 2193 } |
| 2194 |
| 2195 |
| 2174 intptr_t InvokeMathCFunctionInstr::ArgumentCountFor( | 2196 intptr_t InvokeMathCFunctionInstr::ArgumentCountFor( |
| 2175 MethodRecognizer::Kind kind) { | 2197 MethodRecognizer::Kind kind) { |
| 2176 switch (kind) { | 2198 switch (kind) { |
| 2177 case MethodRecognizer::kDoubleTruncate: | 2199 case MethodRecognizer::kDoubleTruncate: |
| 2178 case MethodRecognizer::kDoubleRound: | 2200 case MethodRecognizer::kDoubleRound: |
| 2179 case MethodRecognizer::kDoubleFloor: | 2201 case MethodRecognizer::kDoubleFloor: |
| 2180 case MethodRecognizer::kDoubleCeil: { | 2202 case MethodRecognizer::kDoubleCeil: { |
| 2181 ASSERT(!CPUFeatures::double_truncate_round_supported()); | 2203 ASSERT(!CPUFeatures::double_truncate_round_supported()); |
| 2182 return 1; | 2204 return 1; |
| 2183 } | 2205 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 default: | 2258 default: |
| 2237 UNREACHABLE(); | 2259 UNREACHABLE(); |
| 2238 } | 2260 } |
| 2239 return kPowRuntimeEntry; | 2261 return kPowRuntimeEntry; |
| 2240 } | 2262 } |
| 2241 | 2263 |
| 2242 | 2264 |
| 2243 #undef __ | 2265 #undef __ |
| 2244 | 2266 |
| 2245 } // namespace dart | 2267 } // namespace dart |
| OLD | NEW |