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

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

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

Powered by Google App Engine
This is Rietveld 408576698