Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10917085: Revert "Remove classes Computation and BindInstr." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/os.h" 15 #include "vm/os.h"
16 #include "vm/scopes.h" 16 #include "vm/scopes.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/symbols.h" 18 #include "vm/symbols.h"
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DECLARE_FLAG(bool, enable_type_checks); 22 DECLARE_FLAG(bool, enable_type_checks);
23 23
24 24
25 intptr_t Definition::Hashcode() const { 25 intptr_t Computation::Hashcode() const {
26 intptr_t result = tag(); 26 intptr_t result = computation_kind();
27 for (intptr_t i = 0; i < InputCount(); ++i) { 27 for (intptr_t i = 0; i < InputCount(); ++i) {
28 Value* value = InputAt(i); 28 Value* value = InputAt(i);
29 intptr_t j = value->definition()->ssa_temp_index(); 29 intptr_t j = value->definition()->ssa_temp_index();
30 result = result * 31 + j; 30 result = result * 31 + j;
31 } 31 }
32 return result; 32 return result;
33 } 33 }
34 34
35 35
36 bool Definition::Equals(Definition* other) const { 36 bool Computation::Equals(Computation* other) const {
37 if (tag() != other->tag()) return false; 37 if (computation_kind() != other->computation_kind()) return false;
38 for (intptr_t i = 0; i < InputCount(); ++i) { 38 for (intptr_t i = 0; i < InputCount(); ++i) {
39 if (!InputAt(i)->Equals(other->InputAt(i))) return false; 39 if (!InputAt(i)->Equals(other->InputAt(i))) return false;
40 } 40 }
41 return AttributesEqual(other); 41 return AttributesEqual(other);
42 } 42 }
43 43
44 44
45 bool Value::Equals(Value* other) const { 45 bool Value::Equals(Value* other) const {
46 return definition() == other->definition(); 46 return definition() == other->definition();
47 } 47 }
48 48
49 49
50 bool CheckClassInstr::AttributesEqual(Definition* other) const { 50 bool CheckClassComp::AttributesEqual(Computation* other) const {
51 CheckClassInstr* other_check = other->AsCheckClass(); 51 CheckClassComp* other_check = other->AsCheckClass();
52 ASSERT(other_check != NULL); 52 if (other_check == NULL) return false;
53 if (unary_checks().NumberOfChecks() != 53 if (unary_checks().NumberOfChecks() !=
54 other_check->unary_checks().NumberOfChecks()) { 54 other_check->unary_checks().NumberOfChecks()) {
55 return false; 55 return false;
56 } 56 }
57 for (intptr_t i = 0; i < unary_checks().NumberOfChecks(); ++i) { 57 for (intptr_t i = 0; i < unary_checks().NumberOfChecks(); ++i) {
58 // TODO(fschneider): Make sure ic_data are sorted to hit more cases. 58 // TODO(fschneider): Make sure ic_data are sorted to hit more cases.
59 if (unary_checks().GetReceiverClassIdAt(i) != 59 if (unary_checks().GetReceiverClassIdAt(i) !=
60 other_check->unary_checks().GetReceiverClassIdAt(i)) { 60 other_check->unary_checks().GetReceiverClassIdAt(i)) {
61 return false; 61 return false;
62 } 62 }
63 } 63 }
64 return true; 64 return true;
65 } 65 }
66 66
67 67
68 bool CheckArrayBoundInstr::AttributesEqual(Definition* other) const { 68 bool CheckArrayBoundComp::AttributesEqual(Computation* other) const {
69 CheckArrayBoundInstr* other_check = other->AsCheckArrayBound(); 69 CheckArrayBoundComp* other_check = other->AsCheckArrayBound();
70 ASSERT(other_check != NULL); 70 if (other_check == NULL) return false;
71 return array_type() == other_check->array_type(); 71 return array_type() == other_check->array_type();
72 } 72 }
73 73
74 74
75 // Returns true if the value represents a constant. 75 // Returns true if the value represents a constant.
76 bool Value::BindsToConstant() const { 76 bool Value::BindsToConstant() const {
77 return definition()->IsConstant(); 77 BindInstr* bind = definition()->AsBind();
78 return (bind != NULL) && (bind->computation()->AsConstant() != NULL);
78 } 79 }
79 80
80 81
81 // Returns true if the value represents constant null. 82 // Returns true if the value represents constant null.
82 bool Value::BindsToConstantNull() const { 83 bool Value::BindsToConstantNull() const {
83 ConstantInstr* constant = definition()->AsConstant(); 84 BindInstr* bind = definition()->AsBind();
85 if (bind == NULL) {
86 return false;
87 }
88 ConstantComp* constant = bind->computation()->AsConstant();
84 return (constant != NULL) && constant->value().IsNull(); 89 return (constant != NULL) && constant->value().IsNull();
85 } 90 }
86 91
87 92
88 const Object& Value::BoundConstant() const { 93 const Object& Value::BoundConstant() const {
89 ASSERT(BindsToConstant()); 94 ASSERT(BindsToConstant());
90 ConstantInstr* constant = definition()->AsConstant(); 95 BindInstr* bind = definition()->AsBind();
96 ASSERT(bind != NULL);
97 ConstantComp* constant = bind->computation()->AsConstant();
91 ASSERT(constant != NULL); 98 ASSERT(constant != NULL);
92 return constant->value(); 99 return constant->value();
93 } 100 }
94 101
95 102
96 bool ConstantInstr::AttributesEqual(Definition* other) const { 103 bool ConstantComp::AttributesEqual(Computation* other) const {
97 ConstantInstr* other_constant = other->AsConstant(); 104 ConstantComp* other_constant = other->AsConstant();
98 ASSERT(other_constant != NULL); 105 return (other_constant != NULL) &&
99 return (value().raw() == other_constant->value().raw()); 106 (value().raw() == other_constant->value().raw());
100 } 107 }
101 108
102 109
103 GraphEntryInstr::GraphEntryInstr(TargetEntryInstr* normal_entry) 110 GraphEntryInstr::GraphEntryInstr(TargetEntryInstr* normal_entry)
104 : BlockEntryInstr(CatchClauseNode::kInvalidTryIndex), 111 : BlockEntryInstr(CatchClauseNode::kInvalidTryIndex),
105 normal_entry_(normal_entry), 112 normal_entry_(normal_entry),
106 catch_entries_(), 113 catch_entries_(),
107 start_env_(NULL), 114 start_env_(NULL),
108 constant_null_(new ConstantInstr(Object::ZoneHandle())), 115 constant_null_(new BindInstr(Definition::kValue,
116 new ConstantComp(Object::ZoneHandle()))),
109 spill_slot_count_(0) { 117 spill_slot_count_(0) {
110 } 118 }
111 119
112 120
113 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( 121 MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
114 const Function& function) { 122 const Function& function) {
115 // Only core and math library methods can be recognized. 123 // Only core and math library methods can be recognized.
116 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 124 const Library& core_lib = Library::Handle(Library::CoreLibrary());
117 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); 125 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary());
118 const Library& math_lib = Library::Handle(Library::MathLibrary()); 126 const Library& math_lib = Library::Handle(Library::MathLibrary());
(...skipping 23 matching lines...) Expand all
142 const char* MethodRecognizer::KindToCString(Kind kind) { 150 const char* MethodRecognizer::KindToCString(Kind kind) {
143 #define KIND_TO_STRING(class_name, function_name, enum_name) \ 151 #define KIND_TO_STRING(class_name, function_name, enum_name) \
144 if (kind == k##enum_name) return #enum_name; 152 if (kind == k##enum_name) return #enum_name;
145 RECOGNIZED_LIST(KIND_TO_STRING) 153 RECOGNIZED_LIST(KIND_TO_STRING)
146 #undef KIND_TO_STRING 154 #undef KIND_TO_STRING
147 return "?"; 155 return "?";
148 } 156 }
149 157
150 158
151 // ==== Support for visiting flow graphs. 159 // ==== Support for visiting flow graphs.
160 #define DEFINE_ACCEPT(ShortName, ClassName) \
161 void ClassName::Accept(FlowGraphVisitor* visitor, BindInstr* instr) { \
162 visitor->Visit##ShortName(this, instr); \
163 }
164
165 FOR_EACH_COMPUTATION(DEFINE_ACCEPT)
166
167 #undef DEFINE_ACCEPT
168
169
152 #define DEFINE_ACCEPT(ShortName) \ 170 #define DEFINE_ACCEPT(ShortName) \
153 void ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \ 171 void ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \
154 visitor->Visit##ShortName(this); \ 172 visitor->Visit##ShortName(this); \
155 } 173 }
156 174
157 FOR_EACH_INSTRUCTION(DEFINE_ACCEPT) 175 FOR_EACH_INSTRUCTION(DEFINE_ACCEPT)
158 176
159 #undef DEFINE_ACCEPT 177 #undef DEFINE_ACCEPT
160 178
161 179
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 void Definition::InsertAfter(Instruction* prev) { 212 void Definition::InsertAfter(Instruction* prev) {
195 ASSERT(previous_ == NULL); 213 ASSERT(previous_ == NULL);
196 ASSERT(next_ == NULL); 214 ASSERT(next_ == NULL);
197 previous_ = prev; 215 previous_ = prev;
198 next_ = prev->next_; 216 next_ = prev->next_;
199 next_->previous_ = this; 217 next_->previous_ = this;
200 previous_->next_ = this; 218 previous_->next_ = this;
201 } 219 }
202 220
203 221
222 ConstantComp* Definition::AsConstant() {
223 BindInstr* bind = AsBind();
224 return (bind != NULL) ? bind->computation()->AsConstant() : NULL;
225 }
226
227
204 void ForwardInstructionIterator::RemoveCurrentFromGraph() { 228 void ForwardInstructionIterator::RemoveCurrentFromGraph() {
205 current_ = current_->RemoveFromGraph(true); // Set current_ to previous. 229 current_ = current_->RemoveFromGraph(true); // Set current_ to previous.
206 } 230 }
207 231
208 232
209 void ForwardInstructionIterator::ReplaceCurrentWith(Definition* other) {
210 Definition* defn = current_->AsDefinition();
211 ASSERT(defn != NULL);
212 defn->ReplaceUsesWith(other);
213 ASSERT(other->env() == NULL);
214 other->set_env(defn->env());
215 defn->set_env(NULL);
216 ASSERT(!other->HasSSATemp());
217 if (defn->HasSSATemp()) other->set_ssa_temp_index(defn->ssa_temp_index());
218
219 other->InsertBefore(current_); // So other will be current.
220 RemoveCurrentFromGraph();
221 }
222
223
224 // Default implementation of visiting basic blocks. Can be overridden. 233 // Default implementation of visiting basic blocks. Can be overridden.
225 void FlowGraphVisitor::VisitBlocks() { 234 void FlowGraphVisitor::VisitBlocks() {
226 ASSERT(current_iterator_ == NULL); 235 ASSERT(current_iterator_ == NULL);
227 for (intptr_t i = 0; i < block_order_.length(); ++i) { 236 for (intptr_t i = 0; i < block_order_.length(); ++i) {
228 BlockEntryInstr* entry = block_order_[i]; 237 BlockEntryInstr* entry = block_order_[i];
229 entry->Accept(this); 238 entry->Accept(this);
230 ForwardInstructionIterator it(entry); 239 ForwardInstructionIterator it(entry);
231 current_iterator_ = &it; 240 current_iterator_ = &it;
232 for (; !it.Done(); it.Advance()) { 241 for (; !it.Done(); it.Advance()) {
233 it.Current()->Accept(this); 242 it.Current()->Accept(this);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 371
363 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const { 372 intptr_t JoinEntryInstr::IndexOfPredecessor(BlockEntryInstr* pred) const {
364 for (intptr_t i = 0; i < predecessors_.length(); ++i) { 373 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
365 if (predecessors_[i] == pred) return i; 374 if (predecessors_[i] == pred) return i;
366 } 375 }
367 return -1; 376 return -1;
368 } 377 }
369 378
370 379
371 // ==== Recording assigned variables. 380 // ==== Recording assigned variables.
372 void Definition::RecordAssignedVars(BitVector* assigned_vars, 381 void Computation::RecordAssignedVars(BitVector* assigned_vars,
373 intptr_t fixed_parameter_count) { 382 intptr_t fixed_parameter_count) {
374 // Nothing to do for the base class. 383 // Nothing to do for the base class.
375 } 384 }
376 385
377 386
378 void StoreLocalInstr::RecordAssignedVars(BitVector* assigned_vars, 387 void StoreLocalComp::RecordAssignedVars(BitVector* assigned_vars,
379 intptr_t fixed_parameter_count) { 388 intptr_t fixed_parameter_count) {
380 if (!local().is_captured()) { 389 if (!local().is_captured()) {
381 assigned_vars->Add(local().BitIndexIn(fixed_parameter_count)); 390 assigned_vars->Add(local().BitIndexIn(fixed_parameter_count));
382 } 391 }
383 } 392 }
384 393
385 394
386 void Instruction::RecordAssignedVars(BitVector* assigned_vars, 395 void Instruction::RecordAssignedVars(BitVector* assigned_vars,
387 intptr_t fixed_parameter_count) { 396 intptr_t fixed_parameter_count) {
388 // Nothing to do for the base class. 397 // Nothing to do for the base class.
389 } 398 }
(...skipping 22 matching lines...) Expand all
412 } 421 }
413 while (env_use_list_ != NULL) { 422 while (env_use_list_ != NULL) {
414 Value* current = env_use_list_; 423 Value* current = env_use_list_;
415 env_use_list_ = env_use_list_->next_use(); 424 env_use_list_ = env_use_list_->next_use();
416 current->set_definition(other); 425 current->set_definition(other);
417 current->AddToEnvUseList(); 426 current->AddToEnvUseList();
418 } 427 }
419 } 428 }
420 429
421 430
422 void Definition::ReplaceWith(Definition* other,
423 ForwardInstructionIterator* iterator) {
424 if ((iterator != NULL) && (other == iterator->Current())) {
425 iterator->ReplaceCurrentWith(other);
426 } else {
427 ReplaceUsesWith(other);
428 ASSERT(other->env() == NULL);
429 other->set_env(env());
430 set_env(NULL);
431 ASSERT(!other->HasSSATemp());
432 if (HasSSATemp()) other->set_ssa_temp_index(ssa_temp_index());
433
434 other->set_previous(previous());
435 previous()->set_next(other);
436 set_previous(NULL);
437
438 other->set_next(next());
439 next()->set_previous(other);
440 set_next(NULL);
441 }
442 }
443
444
445 bool Definition::SetPropagatedCid(intptr_t cid) { 431 bool Definition::SetPropagatedCid(intptr_t cid) {
446 if (cid == kIllegalCid) { 432 if (cid == kIllegalCid) {
447 return false; 433 return false;
448 } 434 }
449 if (propagated_cid_ == kIllegalCid) { 435 if (propagated_cid_ == kIllegalCid) {
450 // First setting, nothing has changed. 436 // First setting, nothing has changed.
451 propagated_cid_ = cid; 437 propagated_cid_ = cid;
452 return false; 438 return false;
453 } 439 }
454 bool has_changed = (propagated_cid_ != cid); 440 bool has_changed = (propagated_cid_ != cid);
455 propagated_cid_ = cid; 441 propagated_cid_ = cid;
456 return has_changed; 442 return has_changed;
457 } 443 }
458 444
445 RawAbstractType* BindInstr::CompileType() const {
446 ASSERT(!HasPropagatedType());
447 // The compile type may be requested when building the flow graph, i.e. before
448 // type propagation has occurred.
449 return computation()->CompileType();
450 }
459 451
460 intptr_t Definition::GetPropagatedCid() { 452
453 intptr_t BindInstr::GetPropagatedCid() {
461 if (has_propagated_cid()) return propagated_cid(); 454 if (has_propagated_cid()) return propagated_cid();
462 intptr_t cid = ResultCid(); 455 intptr_t cid = computation()->ResultCid();
463 ASSERT(cid != kIllegalCid); 456 ASSERT(cid != kIllegalCid);
464 SetPropagatedCid(cid); 457 SetPropagatedCid(cid);
465 return cid; 458 return cid;
466 } 459 }
467 460
468 461 void BindInstr::RecordAssignedVars(BitVector* assigned_vars,
469 intptr_t PhiInstr::GetPropagatedCid() { 462 intptr_t fixed_parameter_count) {
470 return propagated_cid(); 463 computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count);
471 } 464 }
472 465
473 466
474 intptr_t ParameterInstr::GetPropagatedCid() {
475 return propagated_cid();
476 }
477
478
479 // ==== Postorder graph traversal. 467 // ==== Postorder graph traversal.
480 void GraphEntryInstr::DiscoverBlocks( 468 void GraphEntryInstr::DiscoverBlocks(
481 BlockEntryInstr* current_block, 469 BlockEntryInstr* current_block,
482 GrowableArray<BlockEntryInstr*>* preorder, 470 GrowableArray<BlockEntryInstr*>* preorder,
483 GrowableArray<BlockEntryInstr*>* postorder, 471 GrowableArray<BlockEntryInstr*>* postorder,
484 GrowableArray<intptr_t>* parent, 472 GrowableArray<intptr_t>* parent,
485 GrowableArray<BitVector*>* assigned_vars, 473 GrowableArray<BitVector*>* assigned_vars,
486 intptr_t variable_count, 474 intptr_t variable_count,
487 intptr_t fixed_parameter_count) { 475 intptr_t fixed_parameter_count) {
488 // We only visit this block once, first of all blocks. 476 // We only visit this block once, first of all blocks.
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 return type.raw(); 696 return type.raw();
709 } 697 }
710 698
711 699
712 intptr_t Value::ResultCid() const { 700 intptr_t Value::ResultCid() const {
713 return definition()->GetPropagatedCid(); 701 return definition()->GetPropagatedCid();
714 } 702 }
715 703
716 704
717 705
718 RawAbstractType* ConstantInstr::CompileType() const { 706 RawAbstractType* ConstantComp::CompileType() const {
719 if (value().IsNull()) { 707 if (value().IsNull()) {
720 return Type::NullType(); 708 return Type::NullType();
721 } 709 }
722 if (value().IsInstance()) { 710 if (value().IsInstance()) {
723 return Instance::Cast(value()).GetType(); 711 return Instance::Cast(value()).GetType();
724 } else { 712 } else {
725 ASSERT(value().IsAbstractTypeArguments()); 713 ASSERT(value().IsAbstractTypeArguments());
726 return AbstractType::null(); 714 return AbstractType::null();
727 } 715 }
728 } 716 }
729 717
730 718
731 intptr_t ConstantInstr::ResultCid() const { 719 intptr_t ConstantComp::ResultCid() const {
732 if (value().IsNull()) { 720 if (value().IsNull()) {
733 return kNullCid; 721 return kNullCid;
734 } 722 }
735 if (value().IsInstance()) { 723 if (value().IsInstance()) {
736 return Class::Handle(value().clazz()).id(); 724 return Class::Handle(value().clazz()).id();
737 } else { 725 } else {
738 ASSERT(value().IsAbstractTypeArguments()); 726 ASSERT(value().IsAbstractTypeArguments());
739 return kDynamicCid; 727 return kDynamicCid;
740 } 728 }
741 } 729 }
742 730
743 731
744 RawAbstractType* AssertAssignableInstr::CompileType() const { 732 RawAbstractType* AssertAssignableComp::CompileType() const {
745 const AbstractType& value_compile_type = 733 const AbstractType& value_compile_type =
746 AbstractType::Handle(value()->CompileType()); 734 AbstractType::Handle(value()->CompileType());
747 if (!value_compile_type.IsNull() && 735 if (!value_compile_type.IsNull() &&
748 value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) { 736 value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) {
749 return value_compile_type.raw(); 737 return value_compile_type.raw();
750 } 738 }
751 return dst_type().raw(); 739 return dst_type().raw();
752 } 740 }
753 741
754 742
755 RawAbstractType* AssertBooleanInstr::CompileType() const { 743 RawAbstractType* AssertBooleanComp::CompileType() const {
756 return Type::BoolType(); 744 return Type::BoolType();
757 } 745 }
758 746
759 747
760 RawAbstractType* ArgumentDefinitionTestInstr::CompileType() const { 748 RawAbstractType* ArgumentDefinitionTestComp::CompileType() const {
761 return Type::BoolType(); 749 return Type::BoolType();
762 } 750 }
763 751
764 752
765 RawAbstractType* CurrentContextInstr::CompileType() const { 753 RawAbstractType* CurrentContextComp::CompileType() const {
766 return AbstractType::null(); 754 return AbstractType::null();
767 } 755 }
768 756
769 757
770 RawAbstractType* StoreContextInstr::CompileType() const { 758 RawAbstractType* StoreContextComp::CompileType() const {
771 return AbstractType::null(); 759 return AbstractType::null();
772 } 760 }
773 761
774 762
775 RawAbstractType* ClosureCallInstr::CompileType() const { 763 RawAbstractType* ClosureCallComp::CompileType() const {
776 // Because of function subtyping rules, the declared return type of a closure 764 // Because of function subtyping rules, the declared return type of a closure
777 // call cannot be relied upon for compile type analysis. For example, a 765 // call cannot be relied upon for compile type analysis. For example, a
778 // function returning Dynamic can be assigned to a closure variable declared 766 // function returning Dynamic can be assigned to a closure variable declared
779 // to return int and may actually return a double at run-time. 767 // to return int and may actually return a double at run-time.
780 return Type::DynamicType(); 768 return Type::DynamicType();
781 } 769 }
782 770
783 771
784 RawAbstractType* InstanceCallInstr::CompileType() const { 772 RawAbstractType* InstanceCallComp::CompileType() const {
785 // TODO(regis): Return a more specific type than Dynamic for recognized 773 // TODO(regis): Return a more specific type than Dynamic for recognized
786 // combinations of receiver type and method name. 774 // combinations of receiver type and method name.
787 return Type::DynamicType(); 775 return Type::DynamicType();
788 } 776 }
789 777
790 778
791 RawAbstractType* PolymorphicInstanceCallInstr::CompileType() const { 779 RawAbstractType* PolymorphicInstanceCallComp::CompileType() const {
792 return Type::DynamicType(); 780 return Type::DynamicType();
793 } 781 }
794 782
795 783
796 RawAbstractType* StaticCallInstr::CompileType() const { 784 RawAbstractType* StaticCallComp::CompileType() const {
797 if (FLAG_enable_type_checks) { 785 if (FLAG_enable_type_checks) {
798 return function().result_type(); 786 return function().result_type();
799 } 787 }
800 return Type::DynamicType(); 788 return Type::DynamicType();
801 } 789 }
802 790
803 791
804 RawAbstractType* LoadLocalInstr::CompileType() const { 792 RawAbstractType* LoadLocalComp::CompileType() const {
805 if (FLAG_enable_type_checks) { 793 if (FLAG_enable_type_checks) {
806 return local().type().raw(); 794 return local().type().raw();
807 } 795 }
808 return Type::DynamicType(); 796 return Type::DynamicType();
809 } 797 }
810 798
811 799
812 RawAbstractType* StoreLocalInstr::CompileType() const { 800 RawAbstractType* StoreLocalComp::CompileType() const {
813 return value()->CompileType(); 801 return value()->CompileType();
814 } 802 }
815 803
816 804
817 RawAbstractType* StrictCompareInstr::CompileType() const { 805 RawAbstractType* StrictCompareComp::CompileType() const {
818 return Type::BoolType(); 806 return Type::BoolType();
819 } 807 }
820 808
821 809
822 // Only known == targets return a Boolean. 810 // Only known == targets return a Boolean.
823 RawAbstractType* EqualityCompareInstr::CompileType() const { 811 RawAbstractType* EqualityCompareComp::CompileType() const {
824 if ((receiver_class_id() == kSmiCid) || 812 if ((receiver_class_id() == kSmiCid) ||
825 (receiver_class_id() == kDoubleCid) || 813 (receiver_class_id() == kDoubleCid) ||
826 (receiver_class_id() == kNumberCid)) { 814 (receiver_class_id() == kNumberCid)) {
827 return Type::BoolType(); 815 return Type::BoolType();
828 } 816 }
829 return Type::DynamicType(); 817 return Type::DynamicType();
830 } 818 }
831 819
832 820
833 intptr_t EqualityCompareInstr::ResultCid() const { 821 intptr_t EqualityCompareComp::ResultCid() const {
834 if ((receiver_class_id() == kSmiCid) || 822 if ((receiver_class_id() == kSmiCid) ||
835 (receiver_class_id() == kDoubleCid) || 823 (receiver_class_id() == kDoubleCid) ||
836 (receiver_class_id() == kNumberCid)) { 824 (receiver_class_id() == kNumberCid)) {
837 // Known/library equalities that are guaranteed to return Boolean. 825 // Known/library equalities that are guaranteed to return Boolean.
838 return kBoolCid; 826 return kBoolCid;
839 } 827 }
840 return kDynamicCid; 828 return kDynamicCid;
841 } 829 }
842 830
843 831
844 RawAbstractType* RelationalOpInstr::CompileType() const { 832 RawAbstractType* RelationalOpComp::CompileType() const {
845 if ((operands_class_id() == kSmiCid) || 833 if ((operands_class_id() == kSmiCid) ||
846 (operands_class_id() == kDoubleCid) || 834 (operands_class_id() == kDoubleCid) ||
847 (operands_class_id() == kNumberCid)) { 835 (operands_class_id() == kNumberCid)) {
848 // Known/library relational ops that are guaranteed to return Boolean. 836 // Known/library relational ops that are guaranteed to return Boolean.
849 return Type::BoolType(); 837 return Type::BoolType();
850 } 838 }
851 return Type::DynamicType(); 839 return Type::DynamicType();
852 } 840 }
853 841
854 842
855 intptr_t RelationalOpInstr::ResultCid() const { 843 intptr_t RelationalOpComp::ResultCid() const {
856 if ((operands_class_id() == kSmiCid) || 844 if ((operands_class_id() == kSmiCid) ||
857 (operands_class_id() == kDoubleCid) || 845 (operands_class_id() == kDoubleCid) ||
858 (operands_class_id() == kNumberCid)) { 846 (operands_class_id() == kNumberCid)) {
859 // Known/library relational ops that are guaranteed to return Boolean. 847 // Known/library relational ops that are guaranteed to return Boolean.
860 return kBoolCid; 848 return kBoolCid;
861 } 849 }
862 return kDynamicCid; 850 return kDynamicCid;
863 } 851 }
864 852
865 853
866 RawAbstractType* NativeCallInstr::CompileType() const { 854 RawAbstractType* NativeCallComp::CompileType() const {
867 // The result type of the native function is identical to the result type of 855 // The result type of the native function is identical to the result type of
868 // the enclosing native Dart function. However, we prefer to check the type 856 // the enclosing native Dart function. However, we prefer to check the type
869 // of the value returned from the native call. 857 // of the value returned from the native call.
870 return Type::DynamicType(); 858 return Type::DynamicType();
871 } 859 }
872 860
873 861
874 RawAbstractType* LoadIndexedInstr::CompileType() const { 862 RawAbstractType* LoadIndexedComp::CompileType() const {
875 return Type::DynamicType(); 863 return Type::DynamicType();
876 } 864 }
877 865
878 866
879 RawAbstractType* StoreIndexedInstr::CompileType() const { 867 RawAbstractType* StoreIndexedComp::CompileType() const {
880 return AbstractType::null(); 868 return AbstractType::null();
881 } 869 }
882 870
883 871
884 RawAbstractType* LoadInstanceFieldInstr::CompileType() const { 872 RawAbstractType* LoadInstanceFieldComp::CompileType() const {
885 if (FLAG_enable_type_checks) { 873 if (FLAG_enable_type_checks) {
886 return field().type(); 874 return field().type();
887 } 875 }
888 return Type::DynamicType(); 876 return Type::DynamicType();
889 } 877 }
890 878
891 879
892 RawAbstractType* StoreInstanceFieldInstr::CompileType() const { 880 RawAbstractType* StoreInstanceFieldComp::CompileType() const {
893 return value()->CompileType(); 881 return value()->CompileType();
894 } 882 }
895 883
896 884
897 RawAbstractType* LoadStaticFieldInstr::CompileType() const { 885 RawAbstractType* LoadStaticFieldComp::CompileType() const {
898 if (FLAG_enable_type_checks) { 886 if (FLAG_enable_type_checks) {
899 return field().type(); 887 return field().type();
900 } 888 }
901 return Type::DynamicType(); 889 return Type::DynamicType();
902 } 890 }
903 891
904 892
905 RawAbstractType* StoreStaticFieldInstr::CompileType() const { 893 RawAbstractType* StoreStaticFieldComp::CompileType() const {
906 return value()->CompileType(); 894 return value()->CompileType();
907 } 895 }
908 896
909 897
910 RawAbstractType* BooleanNegateInstr::CompileType() const { 898 RawAbstractType* BooleanNegateComp::CompileType() const {
911 return Type::BoolType(); 899 return Type::BoolType();
912 } 900 }
913 901
914 902
915 RawAbstractType* InstanceOfInstr::CompileType() const { 903 RawAbstractType* InstanceOfComp::CompileType() const {
916 return Type::BoolType(); 904 return Type::BoolType();
917 } 905 }
918 906
919 907
920 RawAbstractType* CreateArrayInstr::CompileType() const { 908 RawAbstractType* CreateArrayComp::CompileType() const {
921 return type().raw(); 909 return type().raw();
922 } 910 }
923 911
924 912
925 RawAbstractType* CreateClosureInstr::CompileType() const { 913 RawAbstractType* CreateClosureComp::CompileType() const {
926 const Function& fun = function(); 914 const Function& fun = function();
927 const Class& signature_class = Class::Handle(fun.signature_class()); 915 const Class& signature_class = Class::Handle(fun.signature_class());
928 return signature_class.SignatureType(); 916 return signature_class.SignatureType();
929 } 917 }
930 918
931 919
932 RawAbstractType* AllocateObjectInstr::CompileType() const { 920 RawAbstractType* AllocateObjectComp::CompileType() const {
933 // TODO(regis): Be more specific. 921 // TODO(regis): Be more specific.
934 return Type::DynamicType(); 922 return Type::DynamicType();
935 } 923 }
936 924
937 925
938 RawAbstractType* AllocateObjectWithBoundsCheckInstr::CompileType() const { 926 RawAbstractType* AllocateObjectWithBoundsCheckComp::CompileType() const {
939 // TODO(regis): Be more specific. 927 // TODO(regis): Be more specific.
940 return Type::DynamicType(); 928 return Type::DynamicType();
941 } 929 }
942 930
943 931
944 RawAbstractType* LoadVMFieldInstr::CompileType() const { 932 RawAbstractType* LoadVMFieldComp::CompileType() const {
945 // Type may be null if the field is a VM field, e.g. context parent. 933 // Type may be null if the field is a VM field, e.g. context parent.
946 // Keep it as null for debug purposes and do not return Dynamic in production 934 // Keep it as null for debug purposes and do not return Dynamic in production
947 // mode, since misuse of the type would remain undetected. 935 // mode, since misuse of the type would remain undetected.
948 if (type().IsNull()) { 936 if (type().IsNull()) {
949 return AbstractType::null(); 937 return AbstractType::null();
950 } 938 }
951 if (FLAG_enable_type_checks) { 939 if (FLAG_enable_type_checks) {
952 return type().raw(); 940 return type().raw();
953 } 941 }
954 return Type::DynamicType(); 942 return Type::DynamicType();
955 } 943 }
956 944
957 945
958 RawAbstractType* StoreVMFieldInstr::CompileType() const { 946 RawAbstractType* StoreVMFieldComp::CompileType() const {
959 return value()->CompileType(); 947 return value()->CompileType();
960 } 948 }
961 949
962 950
963 RawAbstractType* InstantiateTypeArgumentsInstr::CompileType() const { 951 RawAbstractType* InstantiateTypeArgumentsComp::CompileType() const {
964 return AbstractType::null(); 952 return AbstractType::null();
965 } 953 }
966 954
967 955
968 RawAbstractType* ExtractConstructorTypeArgumentsInstr::CompileType() const { 956 RawAbstractType* ExtractConstructorTypeArgumentsComp::CompileType() const {
969 return AbstractType::null(); 957 return AbstractType::null();
970 } 958 }
971 959
972 960
973 RawAbstractType* ExtractConstructorInstantiatorInstr::CompileType() const { 961 RawAbstractType* ExtractConstructorInstantiatorComp::CompileType() const {
974 return AbstractType::null(); 962 return AbstractType::null();
975 } 963 }
976 964
977 965
978 RawAbstractType* AllocateContextInstr::CompileType() const { 966 RawAbstractType* AllocateContextComp::CompileType() const {
979 return AbstractType::null(); 967 return AbstractType::null();
980 } 968 }
981 969
982 970
983 RawAbstractType* ChainContextInstr::CompileType() const { 971 RawAbstractType* ChainContextComp::CompileType() const {
984 return AbstractType::null(); 972 return AbstractType::null();
985 } 973 }
986 974
987 975
988 RawAbstractType* CloneContextInstr::CompileType() const { 976 RawAbstractType* CloneContextComp::CompileType() const {
989 return AbstractType::null(); 977 return AbstractType::null();
990 } 978 }
991 979
992 980
993 RawAbstractType* CatchEntryInstr::CompileType() const { 981 RawAbstractType* CatchEntryComp::CompileType() const {
994 return AbstractType::null(); 982 return AbstractType::null();
995 } 983 }
996 984
997 985
998 RawAbstractType* CheckStackOverflowInstr::CompileType() const { 986 RawAbstractType* CheckStackOverflowComp::CompileType() const {
999 return AbstractType::null(); 987 return AbstractType::null();
1000 } 988 }
1001 989
1002 990
1003 RawAbstractType* BinarySmiOpInstr::CompileType() const { 991 RawAbstractType* BinarySmiOpComp::CompileType() const {
1004 return (op_kind() == Token::kSHL) ? Type::IntInterface() : Type::SmiType(); 992 return (op_kind() == Token::kSHL) ? Type::IntInterface() : Type::SmiType();
1005 } 993 }
1006 994
1007 995
1008 intptr_t BinarySmiOpInstr::ResultCid() const { 996 intptr_t BinarySmiOpComp::ResultCid() const {
1009 return (op_kind() == Token::kSHL) ? kDynamicCid : kSmiCid; 997 return (op_kind() == Token::kSHL) ? kDynamicCid : kSmiCid;
1010 } 998 }
1011 999
1012 1000
1013 bool BinarySmiOpInstr::CanDeoptimize() const { 1001 bool BinarySmiOpComp::CanDeoptimize() const {
1014 switch (op_kind()) { 1002 switch (op_kind()) {
1015 case Token::kBIT_AND: 1003 case Token::kBIT_AND:
1016 case Token::kBIT_OR: 1004 case Token::kBIT_OR:
1017 case Token::kBIT_XOR: 1005 case Token::kBIT_XOR:
1018 return false; 1006 return false;
1019 default: 1007 default:
1020 return true; 1008 return true;
1021 } 1009 }
1022 } 1010 }
1023 1011
1024 1012
1025 RawAbstractType* BinaryMintOpInstr::CompileType() const { 1013 RawAbstractType* BinaryMintOpComp::CompileType() const {
1026 return Type::MintType(); 1014 return Type::MintType();
1027 } 1015 }
1028 1016
1029 1017
1030 intptr_t BinaryMintOpInstr::ResultCid() const { 1018 intptr_t BinaryMintOpComp::ResultCid() const {
1031 return kMintCid; 1019 return kMintCid;
1032 } 1020 }
1033 1021
1034 1022
1035 RawAbstractType* UnboxedDoubleBinaryOpInstr::CompileType() const { 1023 RawAbstractType* UnboxedDoubleBinaryOpComp::CompileType() const {
1036 return Type::Double(); 1024 return Type::Double();
1037 } 1025 }
1038 1026
1039 1027
1040 RawAbstractType* UnboxDoubleInstr::CompileType() const { 1028 RawAbstractType* UnboxDoubleComp::CompileType() const {
1041 return Type::null(); 1029 return Type::null();
1042 } 1030 }
1043 1031
1044 1032
1045 intptr_t BoxDoubleInstr::ResultCid() const { 1033 intptr_t BoxDoubleComp::ResultCid() const {
1046 return kDoubleCid; 1034 return kDoubleCid;
1047 } 1035 }
1048 1036
1049 1037
1050 RawAbstractType* BoxDoubleInstr::CompileType() const { 1038 RawAbstractType* BoxDoubleComp::CompileType() const {
1051 return Type::Double(); 1039 return Type::Double();
1052 } 1040 }
1053 1041
1054 1042
1055 RawAbstractType* UnarySmiOpInstr::CompileType() const { 1043 RawAbstractType* UnarySmiOpComp::CompileType() const {
1056 return Type::SmiType(); 1044 return Type::SmiType();
1057 } 1045 }
1058 1046
1059 1047
1060 RawAbstractType* NumberNegateInstr::CompileType() const { 1048 RawAbstractType* NumberNegateComp::CompileType() const {
1061 // Implemented only for doubles. 1049 // Implemented only for doubles.
1062 return Type::Double(); 1050 return Type::Double();
1063 } 1051 }
1064 1052
1065 1053
1066 RawAbstractType* DoubleToDoubleInstr::CompileType() const { 1054 RawAbstractType* DoubleToDoubleComp::CompileType() const {
1067 return Type::Double(); 1055 return Type::Double();
1068 } 1056 }
1069 1057
1070 1058
1071 RawAbstractType* SmiToDoubleInstr::CompileType() const { 1059 RawAbstractType* SmiToDoubleComp::CompileType() const {
1072 return Type::Double(); 1060 return Type::Double();
1073 } 1061 }
1074 1062
1075 1063
1076 RawAbstractType* CheckClassInstr::CompileType() const { 1064 RawAbstractType* CheckClassComp::CompileType() const {
1077 return AbstractType::null(); 1065 return AbstractType::null();
1078 } 1066 }
1079 1067
1080 1068
1081 RawAbstractType* CheckSmiInstr::CompileType() const { 1069 RawAbstractType* CheckSmiComp::CompileType() const {
1082 return AbstractType::null(); 1070 return AbstractType::null();
1083 } 1071 }
1084 1072
1085 1073
1086 RawAbstractType* CheckArrayBoundInstr::CompileType() const { 1074 RawAbstractType* CheckArrayBoundComp::CompileType() const {
1087 return AbstractType::null(); 1075 return AbstractType::null();
1088 } 1076 }
1089 1077
1090 1078
1091 RawAbstractType* CheckEitherNonSmiInstr::CompileType() const { 1079 RawAbstractType* CheckEitherNonSmiComp::CompileType() const {
1092 return AbstractType::null(); 1080 return AbstractType::null();
1093 } 1081 }
1094 1082
1095 1083
1096 // Optimizations that eliminate or simplify individual computations. 1084 // Optimizations that eliminate or simplify individual computations.
1097 Definition* Definition::Canonicalize() { 1085 Definition* Computation::TryReplace(BindInstr* instr) const {
1098 return this; 1086 return instr;
1099 } 1087 }
1100 1088
1101 1089
1102 Definition* StrictCompareInstr::Canonicalize() { 1090 Definition* StrictCompareComp::TryReplace(BindInstr* instr) const {
1103 if (!right()->BindsToConstant()) return this; 1091 if (!right()->BindsToConstant()) return instr;
1104 const Object& right_constant = right()->BoundConstant(); 1092 const Object& right_constant = right()->BoundConstant();
1105 Definition* left_defn = left()->definition(); 1093 Definition* left_defn = left()->definition();
1106 // TODO(fschneider): Handle other cases: e === false and e !== true/false. 1094 // TODO(fschneider): Handle other cases: e === false and e !== true/false.
1107 // Handles e === true. 1095 // Handles e === true.
1108 if ((kind() == Token::kEQ_STRICT) && 1096 if ((kind() == Token::kEQ_STRICT) &&
1109 (right_constant.raw() == Bool::True()) && 1097 (right_constant.raw() == Bool::True()) &&
1110 (left()->ResultCid() == kBoolCid)) { 1098 (left()->ResultCid() == kBoolCid)) {
1111 // Remove the constant from the graph. 1099 // Remove the constant from the graph.
1112 Definition* right_defn = right()->definition(); 1100 BindInstr* right_defn = right()->definition()->AsBind();
1113 right_defn->RemoveFromGraph(); 1101 if (right_defn != NULL) {
1102 right_defn->RemoveFromGraph();
1103 }
1114 // Return left subexpression as the replacement for this instruction. 1104 // Return left subexpression as the replacement for this instruction.
1115 return left_defn; 1105 return left_defn;
1116 } 1106 }
1117 return this; 1107 return instr;
1118 } 1108 }
1119 1109
1120 1110
1121 Definition* CheckClassInstr::Canonicalize() { 1111 Definition* CheckClassComp::TryReplace(BindInstr* instr) const {
1122 const intptr_t v_cid = value()->ResultCid(); 1112 const intptr_t v_cid = value()->ResultCid();
1123 const intptr_t num_checks = unary_checks().NumberOfChecks(); 1113 const intptr_t num_checks = unary_checks().NumberOfChecks();
1124 if ((num_checks == 1) && 1114 if ((num_checks == 1) &&
1125 (v_cid == unary_checks().GetReceiverClassIdAt(0))) { 1115 (v_cid == unary_checks().GetReceiverClassIdAt(0))) {
1126 // No checks needed. 1116 // No checks needed.
1127 return NULL; 1117 return NULL;
1128 } 1118 }
1129 return this; 1119 return instr;
1130 } 1120 }
1131 1121
1132 1122
1133 Definition* CheckSmiInstr::Canonicalize() { 1123 Definition* CheckSmiComp::TryReplace(BindInstr* instr) const {
1134 return (value()->ResultCid() == kSmiCid) ? NULL : this; 1124 return (value()->ResultCid() == kSmiCid) ? NULL : instr;
1135 } 1125 }
1136 1126
1137 1127
1138 Definition* CheckEitherNonSmiInstr::Canonicalize() { 1128 Definition* CheckEitherNonSmiComp::TryReplace(BindInstr* instr) const {
1139 if ((left()->ResultCid() == kDoubleCid) || 1129 if ((left()->ResultCid() == kDoubleCid) ||
1140 (right()->ResultCid() == kDoubleCid)) { 1130 (right()->ResultCid() == kDoubleCid)) {
1141 return NULL; // Remove from the graph. 1131 return NULL; // Remove from the graph.
1142 } 1132 }
1143 return this; 1133 return instr;
1144 } 1134 }
1145 1135
1146 1136
1147 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and 1137 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
1148 // PrepareEntry). Only assembly code that can be shared across all architectures 1138 // PrepareEntry). Only assembly code that can be shared across all architectures
1149 // can be used. Machine specific register allocation and code generation 1139 // can be used. Machine specific register allocation and code generation
1150 // is located in intermediate_language_<arch>.cc 1140 // is located in intermediate_language_<arch>.cc
1151 1141
1152 #define __ compiler->assembler()-> 1142 #define __ compiler->assembler()->
1153 1143
(...skipping 15 matching lines...) Expand all
1169 if (IsCatchEntry()) { 1159 if (IsCatchEntry()) {
1170 compiler->AddExceptionHandler(catch_try_index(), 1160 compiler->AddExceptionHandler(catch_try_index(),
1171 compiler->assembler()->CodeSize()); 1161 compiler->assembler()->CodeSize());
1172 } 1162 }
1173 if (HasParallelMove()) { 1163 if (HasParallelMove()) {
1174 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 1164 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1175 } 1165 }
1176 } 1166 }
1177 1167
1178 1168
1179 LocationSummary* GraphEntryInstr::MakeLocationSummary() const {
1180 UNREACHABLE();
1181 return NULL;
1182 }
1183
1184
1185 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1186 UNREACHABLE();
1187 }
1188
1189
1190 LocationSummary* JoinEntryInstr::MakeLocationSummary() const {
1191 UNREACHABLE();
1192 return NULL;
1193 }
1194
1195
1196 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1197 UNREACHABLE();
1198 }
1199
1200
1201 LocationSummary* TargetEntryInstr::MakeLocationSummary() const {
1202 UNREACHABLE();
1203 return NULL;
1204 }
1205
1206
1207 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1208 UNREACHABLE();
1209 }
1210
1211
1212 LocationSummary* PhiInstr::MakeLocationSummary() const {
1213 UNREACHABLE();
1214 return NULL;
1215 }
1216
1217
1218 void PhiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1219 UNREACHABLE();
1220 }
1221
1222
1223 LocationSummary* ParameterInstr::MakeLocationSummary() const {
1224 UNREACHABLE();
1225 return NULL;
1226 }
1227
1228
1229 void ParameterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1230 UNREACHABLE();
1231 }
1232
1233
1234 LocationSummary* ParallelMoveInstr::MakeLocationSummary() const {
1235 return NULL;
1236 }
1237
1238
1239 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1240 UNREACHABLE();
1241 }
1242
1243
1244 LocationSummary* ThrowInstr::MakeLocationSummary() const { 1169 LocationSummary* ThrowInstr::MakeLocationSummary() const {
1245 return new LocationSummary(0, 0, LocationSummary::kCall); 1170 return new LocationSummary(0, 0, LocationSummary::kCall);
1246 } 1171 }
1247 1172
1248 1173
1249 1174
1250 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1175 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1251 compiler->GenerateCallRuntime(token_pos(), 1176 compiler->GenerateCallRuntime(token_pos(),
1252 kThrowRuntimeEntry, 1177 kThrowRuntimeEntry,
1253 locs()); 1178 locs());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 } else { 1239 } else {
1315 // If the next block is the true successor we negate comparison and fall 1240 // If the next block is the true successor we negate comparison and fall
1316 // through to it. 1241 // through to it.
1317 ASSERT(compiler->IsNextBlock(true_successor())); 1242 ASSERT(compiler->IsNextBlock(true_successor()));
1318 Condition false_condition = NegateCondition(true_condition); 1243 Condition false_condition = NegateCondition(true_condition);
1319 __ j(false_condition, compiler->GetBlockLabel(false_successor())); 1244 __ j(false_condition, compiler->GetBlockLabel(false_successor()));
1320 } 1245 }
1321 } 1246 }
1322 1247
1323 1248
1324 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 1249 LocationSummary* CurrentContextComp::MakeLocationSummary() const {
1325 return LocationSummary::Make(0, 1250 return LocationSummary::Make(0,
1326 Location::RequiresRegister(), 1251 Location::RequiresRegister(),
1327 LocationSummary::kNoCall); 1252 LocationSummary::kNoCall);
1328 } 1253 }
1329 1254
1330 1255
1331 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1256 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1332 __ MoveRegister(locs()->out().reg(), CTX); 1257 __ MoveRegister(locs()->out().reg(), CTX);
1333 } 1258 }
1334 1259
1335 1260
1336 LocationSummary* StoreContextInstr::MakeLocationSummary() const { 1261 LocationSummary* StoreContextComp::MakeLocationSummary() const {
1337 const intptr_t kNumInputs = 1; 1262 const intptr_t kNumInputs = 1;
1338 const intptr_t kNumTemps = 0; 1263 const intptr_t kNumTemps = 0;
1339 LocationSummary* summary = 1264 LocationSummary* summary =
1340 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1265 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1341 summary->set_in(0, Location::RegisterLocation(CTX)); 1266 summary->set_in(0, Location::RegisterLocation(CTX));
1342 return summary; 1267 return summary;
1343 } 1268 }
1344 1269
1345 1270
1346 void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1271 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1347 // Nothing to do. Context register were loaded by register allocator. 1272 // Nothing to do. Context register were loaded by register allocator.
1348 ASSERT(locs()->in(0).reg() == CTX); 1273 ASSERT(locs()->in(0).reg() == CTX);
1349 } 1274 }
1350 1275
1351 1276
1352 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { 1277 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
1353 return LocationSummary::Make(2, 1278 return LocationSummary::Make(2,
1354 Location::SameAsFirstInput(), 1279 Location::SameAsFirstInput(),
1355 LocationSummary::kNoCall); 1280 LocationSummary::kNoCall);
1356 } 1281 }
1357 1282
1358 1283
1359 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1284 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1360 Register left = locs()->in(0).reg(); 1285 Register left = locs()->in(0).reg();
1361 Register right = locs()->in(1).reg(); 1286 Register right = locs()->in(1).reg();
1362 1287
1363 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 1288 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1364 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 1289 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1365 __ CompareRegisters(left, right); 1290 __ CompareRegisters(left, right);
1366 1291
1367 Register result = locs()->out().reg(); 1292 Register result = locs()->out().reg();
1368 Label load_true, done; 1293 Label load_true, done;
1369 __ j(true_condition, &load_true, Assembler::kNearJump); 1294 __ j(true_condition, &load_true, Assembler::kNearJump);
1370 __ LoadObject(result, compiler->bool_false()); 1295 __ LoadObject(result, compiler->bool_false());
1371 __ jmp(&done, Assembler::kNearJump); 1296 __ jmp(&done, Assembler::kNearJump);
1372 __ Bind(&load_true); 1297 __ Bind(&load_true);
1373 __ LoadObject(result, compiler->bool_true()); 1298 __ LoadObject(result, compiler->bool_true());
1374 __ Bind(&done); 1299 __ Bind(&done);
1375 } 1300 }
1376 1301
1377 1302
1378 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1303 void StrictCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
1379 BranchInstr* branch) { 1304 BranchInstr* branch) {
1380 Register left = locs()->in(0).reg(); 1305 Register left = locs()->in(0).reg();
1381 Register right = locs()->in(1).reg(); 1306 Register right = locs()->in(1).reg();
1382 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 1307 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1383 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 1308 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1384 __ CompareRegisters(left, right); 1309 __ CompareRegisters(left, right);
1385 branch->EmitBranchOnCondition(compiler, true_condition); 1310 branch->EmitBranchOnCondition(compiler, true_condition);
1386 } 1311 }
1387 1312
1388 1313
1389 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1314 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1390 // The arguments to the stub include the closure. The arguments 1315 // The arguments to the stub include the closure. The arguments
1391 // descriptor describes the closure's arguments (and so does not include 1316 // descriptor describes the closure's arguments (and so does not include
1392 // the closure). 1317 // the closure).
1393 Register temp_reg = locs()->temp(0).reg(); 1318 Register temp_reg = locs()->temp(0).reg();
1394 int argument_count = ArgumentCount(); 1319 int argument_count = ArgumentCount();
1395 const Array& arguments_descriptor = 1320 const Array& arguments_descriptor =
1396 DartEntry::ArgumentsDescriptor(argument_count - 1, 1321 DartEntry::ArgumentsDescriptor(argument_count - 1,
1397 argument_names()); 1322 argument_names());
1398 __ LoadObject(temp_reg, arguments_descriptor); 1323 __ LoadObject(temp_reg, arguments_descriptor);
1399 compiler->GenerateDartCall(deopt_id(), 1324 compiler->GenerateDartCall(deopt_id(),
1400 token_pos(), 1325 token_pos(),
1401 &StubCode::CallClosureFunctionLabel(), 1326 &StubCode::CallClosureFunctionLabel(),
1402 PcDescriptors::kOther, 1327 PcDescriptors::kOther,
1403 locs()); 1328 locs());
1404 __ Drop(argument_count); 1329 __ Drop(argument_count);
1405 } 1330 }
1406 1331
1407 1332
1408 LocationSummary* InstanceCallInstr::MakeLocationSummary() const { 1333 LocationSummary* InstanceCallComp::MakeLocationSummary() const {
1409 return MakeCallSummary(); 1334 return MakeCallSummary();
1410 } 1335 }
1411 1336
1412 1337
1413 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1338 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1414 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 1339 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
1415 deopt_id(), 1340 deopt_id(),
1416 token_pos()); 1341 token_pos());
1417 compiler->GenerateInstanceCall(deopt_id(), 1342 compiler->GenerateInstanceCall(deopt_id(),
1418 token_pos(), 1343 token_pos(),
1419 function_name(), 1344 function_name(),
1420 ArgumentCount(), 1345 ArgumentCount(),
1421 argument_names(), 1346 argument_names(),
1422 checked_argument_count(), 1347 checked_argument_count(),
1423 locs()); 1348 locs());
1424 } 1349 }
1425 1350
1426 1351
1427 LocationSummary* StaticCallInstr::MakeLocationSummary() const { 1352 LocationSummary* StaticCallComp::MakeLocationSummary() const {
1428 return MakeCallSummary(); 1353 return MakeCallSummary();
1429 } 1354 }
1430 1355
1431 1356
1432 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1357 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1433 Label done; 1358 Label done;
1434 if (recognized() == MethodRecognizer::kMathSqrt) { 1359 if (recognized() == MethodRecognizer::kMathSqrt) {
1435 compiler->GenerateInlinedMathSqrt(&done); 1360 compiler->GenerateInlinedMathSqrt(&done);
1436 // Falls through to static call when operand type is not double or smi. 1361 // Falls through to static call when operand type is not double or smi.
1437 } 1362 }
1438 compiler->GenerateStaticCall(deopt_id(), 1363 compiler->GenerateStaticCall(deopt_id(),
1439 token_pos(), 1364 token_pos(),
1440 function(), 1365 function(),
1441 ArgumentCount(), 1366 ArgumentCount(),
1442 argument_names(), 1367 argument_names(),
1443 locs()); 1368 locs());
1444 __ Bind(&done); 1369 __ Bind(&done);
1445 } 1370 }
1446 1371
1447 1372
1448 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1373 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1449 if (!is_eliminated()) { 1374 if (!is_eliminated()) {
1450 compiler->GenerateAssertAssignable(token_pos(), 1375 compiler->GenerateAssertAssignable(token_pos(),
1451 dst_type(), 1376 dst_type(),
1452 dst_name(), 1377 dst_name(),
1453 locs()); 1378 locs());
1454 } 1379 }
1455 ASSERT(locs()->in(0).reg() == locs()->out().reg()); 1380 ASSERT(locs()->in(0).reg() == locs()->out().reg());
1456 } 1381 }
1457 1382
1458 1383
1459 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 1384 LocationSummary* BooleanNegateComp::MakeLocationSummary() const {
1460 return LocationSummary::Make(1, 1385 return LocationSummary::Make(1,
1461 Location::RequiresRegister(), 1386 Location::RequiresRegister(),
1462 LocationSummary::kNoCall); 1387 LocationSummary::kNoCall);
1463 } 1388 }
1464 1389
1465 1390
1466 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1391 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1467 Register value = locs()->in(0).reg(); 1392 Register value = locs()->in(0).reg();
1468 Register result = locs()->out().reg(); 1393 Register result = locs()->out().reg();
1469 1394
1470 Label done; 1395 Label done;
1471 __ LoadObject(result, compiler->bool_true()); 1396 __ LoadObject(result, compiler->bool_true());
1472 __ CompareRegisters(result, value); 1397 __ CompareRegisters(result, value);
1473 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1398 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1474 __ LoadObject(result, compiler->bool_false()); 1399 __ LoadObject(result, compiler->bool_false());
1475 __ Bind(&done); 1400 __ Bind(&done);
1476 } 1401 }
1477 1402
1478 1403
1479 LocationSummary* ChainContextInstr::MakeLocationSummary() const { 1404 LocationSummary* ChainContextComp::MakeLocationSummary() const {
1480 return LocationSummary::Make(1, 1405 return LocationSummary::Make(1,
1481 Location::NoLocation(), 1406 Location::NoLocation(),
1482 LocationSummary::kNoCall); 1407 LocationSummary::kNoCall);
1483 } 1408 }
1484 1409
1485 1410
1486 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1411 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1487 Register context_value = locs()->in(0).reg(); 1412 Register context_value = locs()->in(0).reg();
1488 1413
1489 // Chain the new context in context_value to its parent in CTX. 1414 // Chain the new context in context_value to its parent in CTX.
1490 __ StoreIntoObject(context_value, 1415 __ StoreIntoObject(context_value,
1491 FieldAddress(context_value, Context::parent_offset()), 1416 FieldAddress(context_value, Context::parent_offset()),
1492 CTX); 1417 CTX);
1493 // Set new context as current context. 1418 // Set new context as current context.
1494 __ MoveRegister(CTX, context_value); 1419 __ MoveRegister(CTX, context_value);
1495 } 1420 }
1496 1421
1497 1422
1498 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { 1423 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const {
1499 return LocationSummary::Make(2, 1424 return LocationSummary::Make(2,
1500 Location::SameAsFirstInput(), 1425 Location::SameAsFirstInput(),
1501 LocationSummary::kNoCall); 1426 LocationSummary::kNoCall);
1502 } 1427 }
1503 1428
1504 1429
1505 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1430 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1506 Register value_reg = locs()->in(0).reg(); 1431 Register value_reg = locs()->in(0).reg();
1507 Register dest_reg = locs()->in(1).reg(); 1432 Register dest_reg = locs()->in(1).reg();
1508 ASSERT(value_reg == locs()->out().reg()); 1433 ASSERT(value_reg == locs()->out().reg());
1509 1434
1510 if (value()->NeedsStoreBuffer()) { 1435 if (value()->NeedsStoreBuffer()) {
1511 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 1436 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
1512 value_reg); 1437 value_reg);
1513 } else { 1438 } else {
1514 __ StoreIntoObjectNoBarrier( 1439 __ StoreIntoObjectNoBarrier(
1515 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg); 1440 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
1516 } 1441 }
1517 } 1442 }
1518 1443
1519 1444
1520 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 1445 LocationSummary* AllocateObjectComp::MakeLocationSummary() const {
1521 return MakeCallSummary(); 1446 return MakeCallSummary();
1522 } 1447 }
1523 1448
1524 1449
1525 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1450 void AllocateObjectComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1526 const Class& cls = Class::ZoneHandle(constructor().Owner()); 1451 const Class& cls = Class::ZoneHandle(constructor().Owner());
1527 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 1452 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
1528 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 1453 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1529 compiler->GenerateCall(token_pos(), 1454 compiler->GenerateCall(token_pos(),
1530 &label, 1455 &label,
1531 PcDescriptors::kOther, 1456 PcDescriptors::kOther,
1532 locs()); 1457 locs());
1533 __ Drop(ArgumentCount()); // Discard arguments. 1458 __ Drop(ArgumentCount()); // Discard arguments.
1534 } 1459 }
1535 1460
1536 1461
1537 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { 1462 LocationSummary* CreateClosureComp::MakeLocationSummary() const {
1538 return MakeCallSummary(); 1463 return MakeCallSummary();
1539 } 1464 }
1540 1465
1541 1466
1542 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1467 void CreateClosureComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1543 const Function& closure_function = function(); 1468 const Function& closure_function = function();
1544 const Code& stub = Code::Handle( 1469 const Code& stub = Code::Handle(
1545 StubCode::GetAllocationStubForClosure(closure_function)); 1470 StubCode::GetAllocationStubForClosure(closure_function));
1546 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); 1471 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
1547 compiler->GenerateCall(token_pos(), 1472 compiler->GenerateCall(token_pos(),
1548 &label, 1473 &label,
1549 PcDescriptors::kOther, 1474 PcDescriptors::kOther,
1550 locs()); 1475 locs());
1551 __ Drop(2); // Discard type arguments and receiver. 1476 __ Drop(2); // Discard type arguments and receiver.
1552 } 1477 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 value->set_use_index(i); 1522 value->set_use_index(i);
1598 value->AddToEnvUseList(); 1523 value->AddToEnvUseList();
1599 } 1524 }
1600 instr->set_env(copy); 1525 instr->set_env(copy);
1601 } 1526 }
1602 1527
1603 1528
1604 #undef __ 1529 #undef __
1605 1530
1606 } // namespace dart 1531 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698