Chromium Code Reviews| 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/flow_graph.h" | 5 #include "vm/flow_graph.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 | 264 |
| 265 // Initialize start environment. | 265 // Initialize start environment. |
| 266 GrowableArray<Definition*> start_env(variable_count()); | 266 GrowableArray<Definition*> start_env(variable_count()); |
| 267 for (intptr_t i = 0; i < parameter_count(); ++i) { | 267 for (intptr_t i = 0; i < parameter_count(); ++i) { |
| 268 ParameterInstr* param = new ParameterInstr(i); | 268 ParameterInstr* param = new ParameterInstr(i); |
| 269 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 269 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 270 start_env.Add(param); | 270 start_env.Add(param); |
| 271 } | 271 } |
| 272 | 272 |
| 273 // All locals are initialized with #null. | 273 // All locals are initialized with #null. |
| 274 Definition* null_def = new BindInstr(BindInstr::kUsed, | 274 Definition* null_defn = new BindInstr(BindInstr::kUsed, |
| 275 new ConstantVal(Object::ZoneHandle())); | 275 new ConstantVal(Object::ZoneHandle())); |
| 276 null_def->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 276 // The null definition should not appear in input positions. |
| 277 ASSERT(null_defn->ssa_temp_index() == -1); | |
| 277 while (start_env.length() < variable_count()) { | 278 while (start_env.length() < variable_count()) { |
| 278 start_env.Add(null_def); | 279 start_env.Add(null_defn); |
| 279 } | 280 } |
| 280 graph_entry_->set_start_env( | 281 graph_entry_->set_start_env( |
| 281 new Environment(start_env, non_copied_parameter_count_)); | 282 new Environment(start_env, non_copied_parameter_count_)); |
| 282 | 283 |
| 283 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); | 284 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| 284 ASSERT(normal_entry != NULL); // Must have entry. | 285 ASSERT(normal_entry != NULL); // Must have entry. |
| 285 GrowableArray<Definition*> env(variable_count()); | 286 GrowableArray<Definition*> env(variable_count()); |
| 286 env.AddArray(start_env); | 287 env.AddArray(start_env); |
| 287 RenameRecursive(normal_entry, &env, live_phis); | 288 RenameRecursive(normal_entry, &env, live_phis); |
| 288 } | 289 } |
| 289 | 290 |
| 290 | 291 |
| 292 // Helper to either use the constant value of a defintion or the defintion. | |
|
srdjan
2012/08/20 16:54:20
s/defintion/definition/ (twice)
| |
| 293 static Value* UseDefinition(Definition* defn) { | |
| 294 if (defn->IsBind() && defn->AsBind()->computation()->IsConstant()) { | |
| 295 return defn->AsBind()->computation()->AsConstant(); | |
| 296 } else { | |
| 297 return new UseVal(defn); | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 | |
| 291 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, | 302 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, |
| 292 GrowableArray<Definition*>* env, | 303 GrowableArray<Definition*>* env, |
| 293 GrowableArray<PhiInstr*>* live_phis) { | 304 GrowableArray<PhiInstr*>* live_phis) { |
| 294 // 1. Process phis first. | 305 // 1. Process phis first. |
| 295 if (block_entry->IsJoinEntry()) { | 306 if (block_entry->IsJoinEntry()) { |
| 296 JoinEntryInstr* join = block_entry->AsJoinEntry(); | 307 JoinEntryInstr* join = block_entry->AsJoinEntry(); |
| 297 if (join->phis() != NULL) { | 308 if (join->phis() != NULL) { |
| 298 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 309 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 299 PhiInstr* phi = (*join->phis())[i]; | 310 PhiInstr* phi = (*join->phis())[i]; |
| 300 if (phi != NULL) { | 311 if (phi != NULL) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 329 BindInstr* as_bind = v->AsUse()->definition()->AsBind(); | 340 BindInstr* as_bind = v->AsUse()->definition()->AsBind(); |
| 330 if ((as_bind != NULL) && | 341 if ((as_bind != NULL) && |
| 331 (as_bind->computation()->IsLoadLocal() || | 342 (as_bind->computation()->IsLoadLocal() || |
| 332 as_bind->computation()->IsStoreLocal())) { | 343 as_bind->computation()->IsStoreLocal())) { |
| 333 // Assert exactly one use. | 344 // Assert exactly one use. |
| 334 ASSERT(as_bind->use_list() == v); | 345 ASSERT(as_bind->use_list() == v); |
| 335 ASSERT(as_bind->use_list()->next_use() == NULL); | 346 ASSERT(as_bind->use_list()->next_use() == NULL); |
| 336 // Remove the use, its definition and copy the environment value. | 347 // Remove the use, its definition and copy the environment value. |
| 337 v->RemoveFromUseList(); | 348 v->RemoveFromUseList(); |
| 338 as_bind->RemoveFromGraph(); | 349 as_bind->RemoveFromGraph(); |
| 350 // Assert we are not referencing nulls in the initial environment. | |
| 351 ASSERT(input_defn->ssa_temp_index() != -1); | |
| 339 current->SetInputAt(i, new UseVal(input_defn)); | 352 current->SetInputAt(i, new UseVal(input_defn)); |
| 340 } | 353 } |
| 341 } | 354 } |
| 342 | 355 |
| 343 // Drop pushed arguments for calls. | 356 // Drop pushed arguments for calls. |
| 344 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { | 357 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { |
| 345 env->RemoveLast(); | 358 env->RemoveLast(); |
| 346 } | 359 } |
| 347 | 360 |
| 348 // 2b. Handle LoadLocal and StoreLocal. | 361 // 2b. Handle LoadLocal and StoreLocal. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | 425 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { |
| 413 JoinEntryInstr* successor = | 426 JoinEntryInstr* successor = |
| 414 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | 427 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); |
| 415 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); | 428 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); |
| 416 ASSERT(pred_index >= 0); | 429 ASSERT(pred_index >= 0); |
| 417 if (successor->phis() != NULL) { | 430 if (successor->phis() != NULL) { |
| 418 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { | 431 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { |
| 419 PhiInstr* phi = (*successor->phis())[i]; | 432 PhiInstr* phi = (*successor->phis())[i]; |
| 420 if (phi != NULL) { | 433 if (phi != NULL) { |
| 421 // Rename input operand. | 434 // Rename input operand. |
| 422 phi->SetInputAt(pred_index, new UseVal((*env)[i])); | 435 phi->SetInputAt(pred_index, UseDefinition((*env)[i])); |
| 423 } | 436 } |
| 424 } | 437 } |
| 425 } | 438 } |
| 426 } | 439 } |
| 427 } | 440 } |
| 428 | 441 |
| 429 | 442 |
| 430 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { | 443 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { |
| 431 while (!live_phis->is_empty()) { | 444 while (!live_phis->is_empty()) { |
| 432 PhiInstr* phi = live_phis->Last(); | 445 PhiInstr* phi = live_phis->Last(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 450 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 463 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 451 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 464 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 452 OS::SNPrint(chars, len, kFormat, function_name, reason); | 465 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 453 const Error& error = Error::Handle( | 466 const Error& error = Error::Handle( |
| 454 LanguageError::New(String::Handle(String::New(chars)))); | 467 LanguageError::New(String::Handle(String::New(chars)))); |
| 455 Isolate::Current()->long_jump_base()->Jump(1, error); | 468 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 456 } | 469 } |
| 457 | 470 |
| 458 | 471 |
| 459 } // namespace dart | 472 } // namespace dart |
| OLD | NEW |