| 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_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 2475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2486 Bailout("Catch-entry support in SSA."); | 2486 Bailout("Catch-entry support in SSA."); |
| 2487 } | 2487 } |
| 2488 // TODO(fschneider): Support copied parameters. | 2488 // TODO(fschneider): Support copied parameters. |
| 2489 if (parsed_function().copied_parameter_count()) { | 2489 if (parsed_function().copied_parameter_count()) { |
| 2490 Bailout("Copied parameter support in SSA"); | 2490 Bailout("Copied parameter support in SSA"); |
| 2491 } | 2491 } |
| 2492 ASSERT(var_count == (parsed_function().stack_local_count() + | 2492 ASSERT(var_count == (parsed_function().stack_local_count() + |
| 2493 parsed_function().function().num_fixed_parameters())); | 2493 parsed_function().function().num_fixed_parameters())); |
| 2494 | 2494 |
| 2495 // Initialize start environment. | 2495 // Initialize start environment. |
| 2496 ZoneGrowableArray<Value*>* start_env = | 2496 GrowableArray<Value*> start_env(var_count); |
| 2497 new ZoneGrowableArray<Value*>(var_count); | |
| 2498 intptr_t i = 0; | 2497 intptr_t i = 0; |
| 2499 for (; i < parsed_function().function().num_fixed_parameters(); ++i) { | 2498 for (; i < parsed_function().function().num_fixed_parameters(); ++i) { |
| 2500 ParameterInstr* param = new ParameterInstr(i); | 2499 ParameterInstr* param = new ParameterInstr(i); |
| 2501 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 2500 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 2502 start_env->Add(new UseVal(param)); | 2501 start_env.Add(new UseVal(param)); |
| 2503 } | 2502 } |
| 2504 | 2503 |
| 2505 // All locals are initialized with #null. | 2504 // All locals are initialized with #null. |
| 2506 Value* null_value = new ConstantVal(Object::ZoneHandle()); | 2505 Value* null_value = new ConstantVal(Object::ZoneHandle()); |
| 2507 for (; i < var_count; i++) { | 2506 for (; i < var_count; i++) { |
| 2508 start_env->Add(null_value); | 2507 start_env.Add(null_value); |
| 2509 } | 2508 } |
| 2510 graph_entry_->set_start_env(new Environment(start_env)); | 2509 graph_entry_->set_start_env(new Environment(start_env)); |
| 2511 | 2510 |
| 2512 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); | 2511 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| 2513 ASSERT(normal_entry != NULL); // Must have entry. | 2512 ASSERT(normal_entry != NULL); // Must have entry. |
| 2514 ZoneGrowableArray<Value*>* env = new ZoneGrowableArray<Value*>(var_count); | 2513 GrowableArray<Value*> env(var_count); |
| 2515 env->AddArray(*start_env); | 2514 env.AddArray(start_env); |
| 2516 RenameRecursive(normal_entry, env, var_count); | 2515 RenameRecursive(normal_entry, &env, var_count); |
| 2517 } | 2516 } |
| 2518 | 2517 |
| 2519 | 2518 |
| 2520 static intptr_t WhichPred(BlockEntryInstr* predecessor, | 2519 static intptr_t WhichPred(BlockEntryInstr* predecessor, |
| 2521 JoinEntryInstr* join_block) { | 2520 JoinEntryInstr* join_block) { |
| 2522 for (intptr_t i = 0; i < join_block->PredecessorCount(); ++i) { | 2521 for (intptr_t i = 0; i < join_block->PredecessorCount(); ++i) { |
| 2523 if (join_block->PredecessorAt(i) == predecessor) return i; | 2522 if (join_block->PredecessorAt(i) == predecessor) return i; |
| 2524 } | 2523 } |
| 2525 UNREACHABLE(); | 2524 UNREACHABLE(); |
| 2526 return -1; | 2525 return -1; |
| 2527 } | 2526 } |
| 2528 | 2527 |
| 2529 | 2528 |
| 2530 // Helper to a copy a value iff it is a UseVal. | 2529 // Helper to a copy a value iff it is a UseVal. |
| 2531 static Value* CopyValue(Value* value) { | 2530 static Value* CopyValue(Value* value) { |
| 2532 return value->IsUse() | 2531 return value->IsUse() |
| 2533 ? new UseVal(value->AsUse()->definition()) | 2532 ? new UseVal(value->AsUse()->definition()) |
| 2534 : value; | 2533 : value; |
| 2535 } | 2534 } |
| 2536 | 2535 |
| 2537 | 2536 |
| 2538 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry, | 2537 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry, |
| 2539 ZoneGrowableArray<Value*>* env, | 2538 GrowableArray<Value*>* env, |
| 2540 intptr_t var_count) { | 2539 intptr_t var_count) { |
| 2541 // 1. Process phis first. | 2540 // 1. Process phis first. |
| 2542 if (block_entry->IsJoinEntry()) { | 2541 if (block_entry->IsJoinEntry()) { |
| 2543 JoinEntryInstr* join = block_entry->AsJoinEntry(); | 2542 JoinEntryInstr* join = block_entry->AsJoinEntry(); |
| 2544 if (join->phis() != NULL) { | 2543 if (join->phis() != NULL) { |
| 2545 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 2544 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 2546 PhiInstr* phi = (*join->phis())[i]; | 2545 PhiInstr* phi = (*join->phis())[i]; |
| 2547 if (phi != NULL) { | 2546 if (phi != NULL) { |
| 2548 (*env)[i] = new UseVal(phi); | 2547 (*env)[i] = new UseVal(phi); |
| 2549 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 2548 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 2550 } | 2549 } |
| 2551 } | 2550 } |
| 2552 } | 2551 } |
| 2553 } | 2552 } |
| 2554 | 2553 |
| 2555 // 2. Process normal instructions. | 2554 // 2. Process normal instructions. |
| 2556 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { | 2555 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { |
| 2557 Instruction* current = it.Current(); | 2556 Instruction* current = it.Current(); |
| 2558 // Attach current environment to the instruction. | 2557 // Attach current environment to the instruction. |
| 2559 // TODO(fschneider): Currently each instruction gets a full copy of the | 2558 // TODO(fschneider): Currently each instruction gets a full copy of the |
| 2560 // enviroment. This should be optimized: Only instructions that can | 2559 // enviroment. This should be optimized: Only instructions that can |
| 2561 // deoptimize will should have uses of the environment values. | 2560 // deoptimize will should have uses of the environment values. |
| 2562 current->set_env(new Environment(env)); | 2561 current->set_env(new Environment(*env)); |
| 2563 | 2562 |
| 2564 // 2a. Handle uses: | 2563 // 2a. Handle uses: |
| 2565 // Update expression stack environment for each use. | 2564 // Update expression stack environment for each use. |
| 2566 // For each use of a LoadLocal or StoreLocal: Replace it with the value | 2565 // For each use of a LoadLocal or StoreLocal: Replace it with the value |
| 2567 // from the environment. | 2566 // from the environment. |
| 2568 for (intptr_t i = 0; i < current->InputCount(); ++i) { | 2567 for (intptr_t i = 0; i < current->InputCount(); ++i) { |
| 2569 Value* v = current->InputAt(i); | 2568 Value* v = current->InputAt(i); |
| 2570 if (!v->IsUse()) continue; | 2569 if (!v->IsUse()) continue; |
| 2571 // Update expression stack. | 2570 // Update expression stack. |
| 2572 ASSERT(env->length() > var_count); | 2571 ASSERT(env->length() > var_count); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2618 bind->set_ssa_temp_index(alloc_ssa_temp_index()); | 2617 bind->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 2619 env->Add(new UseVal(bind)); | 2618 env->Add(new UseVal(bind)); |
| 2620 } | 2619 } |
| 2621 } | 2620 } |
| 2622 } | 2621 } |
| 2623 } | 2622 } |
| 2624 | 2623 |
| 2625 // 3. Process dominated blocks. | 2624 // 3. Process dominated blocks. |
| 2626 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { | 2625 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { |
| 2627 BlockEntryInstr* block = block_entry->dominated_blocks()[i]; | 2626 BlockEntryInstr* block = block_entry->dominated_blocks()[i]; |
| 2628 ZoneGrowableArray<Value*>* new_env = | 2627 GrowableArray<Value*> new_env(env->length()); |
| 2629 new ZoneGrowableArray<Value*>(env->length()); | 2628 new_env.AddArray(*env); |
| 2630 new_env->AddArray(*env); | 2629 RenameRecursive(block, &new_env, var_count); |
| 2631 RenameRecursive(block, new_env, var_count); | |
| 2632 } | 2630 } |
| 2633 | 2631 |
| 2634 // 4. Process successor block. We have edge-split form, so that only blocks | 2632 // 4. Process successor block. We have edge-split form, so that only blocks |
| 2635 // with one successor can have a join block as successor. | 2633 // with one successor can have a join block as successor. |
| 2636 if ((block_entry->last_instruction()->SuccessorCount() == 1) && | 2634 if ((block_entry->last_instruction()->SuccessorCount() == 1) && |
| 2637 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | 2635 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { |
| 2638 JoinEntryInstr* successor = | 2636 JoinEntryInstr* successor = |
| 2639 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | 2637 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); |
| 2640 intptr_t pred_index = WhichPred(block_entry, successor); | 2638 intptr_t pred_index = WhichPred(block_entry, successor); |
| 2641 if (successor->phis() != NULL) { | 2639 if (successor->phis() != NULL) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2661 char* chars = reinterpret_cast<char*>( | 2659 char* chars = reinterpret_cast<char*>( |
| 2662 Isolate::Current()->current_zone()->Allocate(len)); | 2660 Isolate::Current()->current_zone()->Allocate(len)); |
| 2663 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2661 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2664 const Error& error = Error::Handle( | 2662 const Error& error = Error::Handle( |
| 2665 LanguageError::New(String::Handle(String::New(chars)))); | 2663 LanguageError::New(String::Handle(String::New(chars)))); |
| 2666 Isolate::Current()->long_jump_base()->Jump(1, error); | 2664 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2667 } | 2665 } |
| 2668 | 2666 |
| 2669 | 2667 |
| 2670 } // namespace dart | 2668 } // namespace dart |
| OLD | NEW |