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

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

Issue 10879036: Compute the def-use list on-demand by walking the dominator tree. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Unneeded include. 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"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698