| OLD | NEW |
| 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" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // TODO(fschneider): Make sure ic_data are sorted to hit more cases. | 66 // TODO(fschneider): Make sure ic_data are sorted to hit more cases. |
| 67 if (ic_data()->GetReceiverClassIdAt(i) != | 67 if (ic_data()->GetReceiverClassIdAt(i) != |
| 68 other->ic_data()->GetReceiverClassIdAt(i)) { | 68 other->ic_data()->GetReceiverClassIdAt(i)) { |
| 69 return false; | 69 return false; |
| 70 } | 70 } |
| 71 } | 71 } |
| 72 return true; | 72 return true; |
| 73 } | 73 } |
| 74 | 74 |
| 75 | 75 |
| 76 UseVal::UseVal(Definition* definition) | |
| 77 : definition_(definition), next_use_(NULL), previous_use_(NULL) { | |
| 78 AddToUseList(); | |
| 79 } | |
| 80 | |
| 81 | |
| 82 void UseVal::SetDefinition(Definition* definition) { | |
| 83 ASSERT(definition != NULL); | |
| 84 RemoveFromUseList(); | |
| 85 definition_ = definition; | |
| 86 AddToUseList(); | |
| 87 } | |
| 88 | |
| 89 | |
| 90 // Returns true if the value represents a constant. | 76 // Returns true if the value represents a constant. |
| 91 bool UseVal::BindsToConstant() const { | 77 bool UseVal::BindsToConstant() const { |
| 92 BindInstr* bind = definition()->AsBind(); | 78 BindInstr* bind = definition()->AsBind(); |
| 93 if (bind == NULL) { | 79 if (bind == NULL) { |
| 94 return false; | 80 return false; |
| 95 } | 81 } |
| 96 return bind->computation()->AsMaterialize() != NULL; | 82 return bind->computation()->AsMaterialize() != NULL; |
| 97 } | 83 } |
| 98 | 84 |
| 99 | 85 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 114 const Object& UseVal::BoundConstant() const { | 100 const Object& UseVal::BoundConstant() const { |
| 115 ASSERT(BindsToConstant()); | 101 ASSERT(BindsToConstant()); |
| 116 BindInstr* bind = definition()->AsBind(); | 102 BindInstr* bind = definition()->AsBind(); |
| 117 ASSERT(bind != NULL); | 103 ASSERT(bind != NULL); |
| 118 MaterializeComp* constant = bind->computation()->AsMaterialize(); | 104 MaterializeComp* constant = bind->computation()->AsMaterialize(); |
| 119 ASSERT(constant != NULL); | 105 ASSERT(constant != NULL); |
| 120 return constant->constant_val()->value(); | 106 return constant->constant_val()->value(); |
| 121 } | 107 } |
| 122 | 108 |
| 123 | 109 |
| 124 void UseVal::RemoveFromUseList() { | |
| 125 ASSERT(definition_ != NULL); | |
| 126 if (next_use_ != NULL) { | |
| 127 next_use_->previous_use_ = previous_use_; | |
| 128 } | |
| 129 if (previous_use_ != NULL) { | |
| 130 previous_use_->next_use_ = next_use_; | |
| 131 } else { | |
| 132 // This is the head of the list. | |
| 133 ASSERT(definition_->use_list() == this); | |
| 134 definition_->set_use_list(next_use_); | |
| 135 } | |
| 136 previous_use_ = next_use_ = NULL; | |
| 137 definition_ = NULL; | |
| 138 } | |
| 139 | |
| 140 | |
| 141 void UseVal::AddToUseList() { | |
| 142 ASSERT(next_use_ == NULL && previous_use_ == NULL && definition_ != NULL); | |
| 143 UseVal* head = definition_->use_list(); | |
| 144 if (head != NULL) { | |
| 145 next_use_ = head; | |
| 146 head->previous_use_ = this; | |
| 147 } | |
| 148 definition_->set_use_list(this); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( | 110 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( |
| 153 const Function& function) { | 111 const Function& function) { |
| 154 // Only core and math library methods can be recognized. | 112 // Only core and math library methods can be recognized. |
| 155 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 113 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 156 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | 114 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| 157 const Library& math_lib = Library::Handle(Library::MathLibrary()); | 115 const Library& math_lib = Library::Handle(Library::MathLibrary()); |
| 158 const Class& function_class = Class::Handle(function.Owner()); | 116 const Class& function_class = Class::Handle(function.Owner()); |
| 159 if ((function_class.library() != core_lib.raw()) && | 117 if ((function_class.library() != core_lib.raw()) && |
| 160 (function_class.library() != core_impl_lib.raw()) && | 118 (function_class.library() != core_impl_lib.raw()) && |
| 161 (function_class.library() != math_lib.raw())) { | 119 (function_class.library() != math_lib.raw())) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 Instruction* prev_instr = previous(); | 177 Instruction* prev_instr = previous(); |
| 220 Instruction* next_instr = next(); | 178 Instruction* next_instr = next(); |
| 221 ASSERT(next_instr != NULL); | 179 ASSERT(next_instr != NULL); |
| 222 ASSERT(!next_instr->IsBlockEntry()); | 180 ASSERT(!next_instr->IsBlockEntry()); |
| 223 prev_instr->set_next(next_instr); | 181 prev_instr->set_next(next_instr); |
| 224 next_instr->set_previous(prev_instr); | 182 next_instr->set_previous(prev_instr); |
| 225 // Reset successor and previous instruction to indicate | 183 // Reset successor and previous instruction to indicate |
| 226 // that the instruction is removed from the graph. | 184 // that the instruction is removed from the graph. |
| 227 set_previous(NULL); | 185 set_previous(NULL); |
| 228 set_next(NULL); | 186 set_next(NULL); |
| 229 ASSERT(!IsDefinition() || AsDefinition()->use_list() == NULL); | |
| 230 return return_previous ? prev_instr : next_instr; | 187 return return_previous ? prev_instr : next_instr; |
| 231 } | 188 } |
| 232 | 189 |
| 233 | 190 |
| 234 void BindInstr::InsertBefore(BindInstr* next) { | 191 void BindInstr::InsertBefore(BindInstr* next) { |
| 235 ASSERT(previous_ == NULL); | 192 ASSERT(previous_ == NULL); |
| 236 ASSERT(next_ == NULL); | 193 ASSERT(next_ == NULL); |
| 237 next_ = next; | 194 next_ = next; |
| 238 previous_ = next->previous_; | 195 previous_ = next->previous_; |
| 239 next->previous_ = this; | 196 next->previous_ = this; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 } | 355 } |
| 399 } | 356 } |
| 400 | 357 |
| 401 | 358 |
| 402 void Instruction::RecordAssignedVars(BitVector* assigned_vars, | 359 void Instruction::RecordAssignedVars(BitVector* assigned_vars, |
| 403 intptr_t fixed_parameter_count) { | 360 intptr_t fixed_parameter_count) { |
| 404 // Nothing to do for the base class. | 361 // Nothing to do for the base class. |
| 405 } | 362 } |
| 406 | 363 |
| 407 | 364 |
| 365 void UseVal::AddToInputUseList() { |
| 366 set_next_use(definition()->input_use_list()); |
| 367 definition()->set_input_use_list(this); |
| 368 } |
| 369 |
| 370 |
| 371 void UseVal::AddToEnvUseList() { |
| 372 set_next_use(definition()->env_use_list()); |
| 373 definition()->set_env_use_list(this); |
| 374 } |
| 375 |
| 376 |
| 408 void Definition::ReplaceUsesWith(Definition* other) { | 377 void Definition::ReplaceUsesWith(Definition* other) { |
| 409 UseVal* head = use_list(); | 378 ASSERT(other != NULL); |
| 410 if (head == NULL) return; | 379 while (input_use_list_ != NULL) { |
| 411 | 380 UseVal* current = input_use_list_; |
| 412 UseVal* current = head; | 381 input_use_list_ = input_use_list_->next_use(); |
| 413 while (current->next_use() != NULL) { | 382 current->set_definition(other); |
| 414 current->definition_ = other; | 383 current->AddToInputUseList(); |
| 415 current = current->next_use(); | |
| 416 } | 384 } |
| 417 current->definition_ = other; | 385 while (env_use_list_ != NULL) { |
| 418 | 386 UseVal* current = env_use_list_; |
| 419 if (other->use_list() != NULL) { | 387 env_use_list_ = env_use_list_->next_use(); |
| 420 current->next_use_ = other->use_list(); | 388 current->set_definition(other); |
| 421 other->use_list()->previous_use_ = current; | 389 current->AddToEnvUseList(); |
| 422 } | 390 } |
| 423 other->set_use_list(head); | |
| 424 set_use_list(NULL); | |
| 425 } | 391 } |
| 426 | 392 |
| 427 | 393 |
| 394 void Definition::ReplaceUsesWith(Value* value) { |
| 395 ASSERT(value != NULL); |
| 396 if (value->IsUse()) { |
| 397 ReplaceUsesWith(value->AsUse()->definition()); |
| 398 return; |
| 399 } |
| 400 ASSERT(value->IsConstant()); |
| 401 while (input_use_list_ != NULL) { |
| 402 Instruction* instr = input_use_list_->instruction(); |
| 403 instr->SetInputAt(input_use_list_->use_index(), value); |
| 404 input_use_list_ = input_use_list_->next_use(); |
| 405 } |
| 406 while (env_use_list_ != NULL) { |
| 407 Environment* env = env_use_list_->instruction()->env(); |
| 408 ASSERT(env != NULL); |
| 409 env->values()[env_use_list_->use_index()] = value; |
| 410 env_use_list_ = env_use_list_->next_use(); |
| 411 } |
| 412 } |
| 413 |
| 414 |
| 428 bool Definition::SetPropagatedCid(intptr_t cid) { | 415 bool Definition::SetPropagatedCid(intptr_t cid) { |
| 429 ASSERT(cid != kIllegalCid); | 416 ASSERT(cid != kIllegalCid); |
| 430 if (propagated_cid_ == kIllegalCid) { | 417 if (propagated_cid_ == kIllegalCid) { |
| 431 // First setting, nothing has changed. | 418 // First setting, nothing has changed. |
| 432 propagated_cid_ = cid; | 419 propagated_cid_ = cid; |
| 433 return false; | 420 return false; |
| 434 } | 421 } |
| 435 bool has_changed = (propagated_cid_ != cid); | 422 bool has_changed = (propagated_cid_ != cid); |
| 436 propagated_cid_ = cid; | 423 propagated_cid_ = cid; |
| 437 return has_changed; | 424 return has_changed; |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 const Object& right_constant = right_use->BoundConstant(); | 1065 const Object& right_constant = right_use->BoundConstant(); |
| 1079 Definition* left = left_use->definition(); | 1066 Definition* left = left_use->definition(); |
| 1080 // TODO(fschneider): Handle other cases: e === false and e !== true/false. | 1067 // TODO(fschneider): Handle other cases: e === false and e !== true/false. |
| 1081 // Handles e === true. | 1068 // Handles e === true. |
| 1082 if ((kind() == Token::kEQ_STRICT) && | 1069 if ((kind() == Token::kEQ_STRICT) && |
| 1083 (right_constant.raw() == Bool::True()) && | 1070 (right_constant.raw() == Bool::True()) && |
| 1084 (left_use->ResultCid() == kBoolCid)) { | 1071 (left_use->ResultCid() == kBoolCid)) { |
| 1085 // Remove the constant from the graph. | 1072 // Remove the constant from the graph. |
| 1086 BindInstr* right = right_use->definition()->AsBind(); | 1073 BindInstr* right = right_use->definition()->AsBind(); |
| 1087 if (right != NULL) { | 1074 if (right != NULL) { |
| 1088 right->set_use_list(NULL); | |
| 1089 right->RemoveFromGraph(); | 1075 right->RemoveFromGraph(); |
| 1090 } | 1076 } |
| 1091 // Return left subexpression as the replacement for this instruction. | 1077 // Return left subexpression as the replacement for this instruction. |
| 1092 return left; | 1078 return left; |
| 1093 } | 1079 } |
| 1094 return instr; | 1080 return instr; |
| 1095 } | 1081 } |
| 1096 | 1082 |
| 1097 | 1083 |
| 1098 Definition* CheckSmiComp::TryReplace(BindInstr* instr) const { | 1084 Definition* CheckSmiComp::TryReplace(BindInstr* instr) const { |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 ? UseDefinition(values()[i]->AsUse()->definition()) | 1530 ? UseDefinition(values()[i]->AsUse()->definition()) |
| 1545 : val); | 1531 : val); |
| 1546 } | 1532 } |
| 1547 return copy; | 1533 return copy; |
| 1548 } | 1534 } |
| 1549 | 1535 |
| 1550 | 1536 |
| 1551 #undef __ | 1537 #undef __ |
| 1552 | 1538 |
| 1553 } // namespace dart | 1539 } // namespace dart |
| OLD | NEW |