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

Side by Side Diff: vm/flow_graph_builder.cc

Issue 10544206: Second step for computing SSA: renaming. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 6 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/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 17 matching lines...) Expand all
28 DECLARE_FLAG(bool, enable_type_checks); 28 DECLARE_FLAG(bool, enable_type_checks);
29 29
30 30
31 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function) 31 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function)
32 : parsed_function_(parsed_function), 32 : parsed_function_(parsed_function),
33 preorder_block_entries_(), 33 preorder_block_entries_(),
34 postorder_block_entries_(), 34 postorder_block_entries_(),
35 context_level_(0), 35 context_level_(0),
36 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), 36 last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
37 try_index_(CatchClauseNode::kInvalidTryIndex), 37 try_index_(CatchClauseNode::kInvalidTryIndex),
38 graph_entry_(NULL) { } 38 graph_entry_(NULL),
39 current_ssa_temp_index_(0) { }
39 40
40 41
41 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) { 42 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) {
42 graph_entry_->AddCatchEntry(entry); 43 graph_entry_->AddCatchEntry(entry);
43 } 44 }
44 45
45 46
46 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { 47 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
47 ASSERT(is_open()); 48 ASSERT(is_open());
48 if (other_fragment.is_empty()) return; 49 if (other_fragment.is_empty()) return;
(...skipping 2292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2341 for (intptr_t i = 0; i < block_count; ++i) { 2342 for (intptr_t i = 0; i < block_count; ++i) {
2342 postorder_block_entries_[i]->set_block_id(block_count - i - 1); 2343 postorder_block_entries_[i]->set_block_id(block_count - i - 1);
2343 } 2344 }
2344 if (for_optimized && FLAG_use_ssa) { 2345 if (for_optimized && FLAG_use_ssa) {
2345 GrowableArray<BitVector*> dominance_frontier; 2346 GrowableArray<BitVector*> dominance_frontier;
2346 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); 2347 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier);
2347 InsertPhis(preorder_block_entries_, 2348 InsertPhis(preorder_block_entries_,
2348 assigned_vars, 2349 assigned_vars,
2349 variable_count, 2350 variable_count,
2350 dominance_frontier); 2351 dominance_frontier);
2351 // TODO(fschneider): Perform SSA renaming. 2352 Rename(variable_count);
2352 } 2353 }
2353 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { 2354 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) {
2354 intptr_t length = postorder_block_entries_.length(); 2355 intptr_t length = postorder_block_entries_.length();
2355 GrowableArray<BlockEntryInstr*> reverse_postorder(length); 2356 GrowableArray<BlockEntryInstr*> reverse_postorder(length);
2356 for (intptr_t i = length - 1; i >= 0; --i) { 2357 for (intptr_t i = length - 1; i >= 0; --i) {
2357 reverse_postorder.Add(postorder_block_entries_[i]); 2358 reverse_postorder.Add(postorder_block_entries_[i]);
2358 } 2359 }
2359 if (FLAG_print_flow_graph) { 2360 if (FLAG_print_flow_graph) {
2360 // Print flow graph to stdout. 2361 // Print flow graph to stdout.
2361 FlowGraphPrinter printer(function, reverse_postorder); 2362 FlowGraphPrinter printer(function, reverse_postorder);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 work[index] = var_index; 2548 work[index] = var_index;
2548 worklist.Add(block); 2549 worklist.Add(block);
2549 } 2550 }
2550 } 2551 }
2551 } 2552 }
2552 } 2553 }
2553 } 2554 }
2554 } 2555 }
2555 2556
2556 2557
2558 void FlowGraphBuilder::Rename(intptr_t var_count) {
2559 // Initialize start environment:
2560 // All locals are initialized with #null.
2561 // TODO(fschneider): Support paramters. All parameters are initially located
srdjan 2012/06/18 18:04:38 parameters
Florian Schneider 2012/06/19 11:26:40 Done.
2562 // on the stack.
2563 ZoneGrowableArray<Value*>* start_env =
2564 new ZoneGrowableArray<Value*>(var_count);
2565 if (parsed_function().function().num_fixed_parameters() > 0) {
2566 Bailout("Fixed parameter support in SSA");
2567 }
2568 if (parsed_function().copied_parameter_count()) {
2569 Bailout("Copied parameter support in SSA");
2570 }
2571 Value* null_value = new ConstantVal(Object::ZoneHandle());
2572 ASSERT(var_count == parsed_function().stack_local_count());
srdjan 2012/06/18 18:04:38 Why don't you use stack_local_count instead of pas
Florian Schneider 2012/06/19 11:26:40 Yes, in one of the next CLs it will change to: va
2573 for (intptr_t i = 0; i < var_count; i++) {
2574 start_env->Add(null_value);
2575 }
2576 graph_entry_->set_start_env(start_env);
2577
2578 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0);
2579 ASSERT(normal_entry != NULL); // Graph entry is empty.
srdjan 2012/06/18 18:04:38 Maybe change comment to: "Must have entry" or simi
Florian Schneider 2012/06/19 11:26:40 Done.
2580 ZoneGrowableArray<Value*>* env = new ZoneGrowableArray<Value*>(var_count);
2581 env->AddArray(*start_env);
2582 RenameRecursive(normal_entry, env, var_count);
2583 }
2584
2585
2586 static intptr_t WhichPred(BlockEntryInstr* predecessor,
2587 JoinEntryInstr* join_block) {
2588 for (intptr_t i = 0; i < join_block->PredecessorCount(); ++i) {
2589 if (join_block->PredecessorAt(i) == predecessor) return i;
2590 }
2591 UNREACHABLE();
2592 return -1;
2593 }
2594
2595
2596 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry,
2597 ZoneGrowableArray<Value*>* env,
2598 intptr_t var_count) {
2599 // Iterate over instructions.
2600 // 1. Handle phis first.
2601 if (block_entry->IsJoinEntry()) {
2602 JoinEntryInstr* join = block_entry->AsJoinEntry();
2603 if (join->phis() != NULL) {
srdjan 2012/06/18 18:04:38 ASSERT(join->phis() != NULL) ?
Florian Schneider 2012/06/19 11:26:40 Right now I lazily allocate the phis() array when
2604 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
2605 PhiInstr* phi = (*join->phis())[i];
2606 if (phi != NULL) {
2607 (*env)[i] = new UseVal(phi);
2608 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp.
2609 }
2610 }
2611 }
2612 }
2613
2614 // 2. Handle normal instructions.
2615 Instruction* current = block_entry->StraightLineSuccessor();
2616 Instruction* prev = block_entry;
2617 while (current != NULL && !current->IsBlockEntry()) {
srdjan 2012/06/18 18:04:38 add parenthesis
Florian Schneider 2012/06/19 11:26:40 Done.
2618 // 2a. Handle LoadLocal and StoreLocal.
2619 LoadLocalComp* load = NULL;
2620 if (current->IsDo() &&
2621 current->AsDo()->computation()->IsLoadLocal()) {
2622 load = current->AsDo()->computation()->AsLoadLocal();
srdjan 2012/06/18 18:04:38 A LoadLocal in a Do has no side effect and can be
Florian Schneider 2012/06/19 11:26:40 Yes. I remove it from the graph below, but better
2623 } else if (current->IsBind() &&
2624 current->AsBind()->computation()->IsLoadLocal()) {
2625 load = current->AsBind()->computation()->AsLoadLocal();
2626 }
2627 StoreLocalComp* store = NULL;
2628 if (current->IsDo() &&
2629 current->AsDo()->computation()->IsStoreLocal()) {
2630 store = current->AsDo()->computation()->AsStoreLocal();
2631 } else if (current->IsBind() &&
2632 current->AsBind()->computation()->IsStoreLocal()) {
2633 store = current->AsBind()->computation()->AsStoreLocal();
2634 }
2635
2636 if (load != NULL || store != NULL) {
srdjan 2012/06/18 18:04:38 Add parenthesis
Florian Schneider 2012/06/19 11:26:40 Done.
2637 // Remove instruction with LoadLocal or StoreLocal.
2638 prev->SetSuccessor(current->StraightLineSuccessor());
2639 // Update renaming environment for StoreLocal.
2640 if (store != NULL) {
2641 (*env)[store->local().BitIndexIn(var_count)] = store->value();
2642 }
2643 } else {
2644 // Assign new SSA temporary.
2645 if (current->IsBind()) {
2646 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
2647 }
2648 }
2649
2650 // 2b. Handle uses of LoadLocal / StoreLocal
2651 for (intptr_t i = 0; i < current->InputCount(); ++i) {
2652 // For each use of a LoadLocal/StoreLocal: Replace it with the definition
2653 // from the enviroment.
srdjan 2012/06/18 18:04:38 environment
Florian Schneider 2012/06/19 11:26:40 Done.
2654 Value* v = current->InputAt(i);
2655 if (v->IsUse() &&
2656 v->AsUse()->definition()->IsBind() &&
2657 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) {
2658 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
2659 intptr_t index = comp->AsLoadLocal()->local().BitIndexIn(var_count);
2660 Value* new_value = (*env)[index];
2661 // Make a copy if it is a UseVal.
2662 if (new_value->IsUse()) {
2663 new_value = new UseVal(new_value->AsUse()->definition());
2664 }
2665 current->SetInputAt(i, new_value);
2666 }
2667 if (v->IsUse() &&
2668 v->AsUse()->definition()->IsBind() &&
2669 v->AsUse()->definition()->AsBind()->computation()->IsStoreLocal()) {
2670 // For each use of a LoadLocal: Replace LoadLocal with the definition
2671 // from the enviroment.
2672 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
2673 intptr_t index = comp->AsStoreLocal()->local().BitIndexIn(var_count);
2674 Value* new_value = (*env)[index];
2675 // Make a copy if it is a UseVal.
2676 if (new_value->IsUse()) {
2677 new_value = new UseVal(new_value->AsUse()->definition());
2678 }
2679 current->SetInputAt(i, new_value);
2680 }
2681 }
2682
2683 // Update previous only if no instruction was removed from the graph.
2684 if (load == NULL && store == NULL) {
srdjan 2012/06/18 18:04:38 parenthesis
Florian Schneider 2012/06/19 11:26:40 Done.
2685 prev = current;
2686 }
2687 current = current->StraightLineSuccessor();
2688 }
2689
2690 // 3. Process dominated blocks.
2691 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) {
2692 BlockEntryInstr* block = block_entry->dominated_blocks()[i];
2693 ZoneGrowableArray<Value*>* new_env =
2694 new ZoneGrowableArray<Value*>(var_count);
2695 new_env->AddArray(*env);
2696 RenameRecursive(block, new_env, var_count);
2697 }
2698
2699 // 4. Process successor block. We have edge-split form, so that only blocks
2700 // with one successor can have a join block as successor.
2701 if (block_entry->last_instruction()->SuccessorCount() == 1 &&
srdjan 2012/06/18 18:04:38 ditto
Florian Schneider 2012/06/19 11:26:40 Done.
2702 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) {
2703 JoinEntryInstr* successor =
2704 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry();
2705 intptr_t pred_index = WhichPred(block_entry, successor);
2706 if (successor->phis() != NULL) {
2707 for (intptr_t i = 0; i < successor->phis()->length(); ++i) {
2708 PhiInstr* phi = (*successor->phis())[i];
2709 if (phi != NULL) phi->SetInputAt(pred_index, (*env)[i]);
2710 }
2711 }
2712 }
2713 }
2714
2715
2557 void FlowGraphBuilder::Bailout(const char* reason) { 2716 void FlowGraphBuilder::Bailout(const char* reason) {
2558 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2717 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2559 const char* function_name = parsed_function_.function().ToCString(); 2718 const char* function_name = parsed_function_.function().ToCString();
2560 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2719 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2561 char* chars = reinterpret_cast<char*>( 2720 char* chars = reinterpret_cast<char*>(
2562 Isolate::Current()->current_zone()->Allocate(len)); 2721 Isolate::Current()->current_zone()->Allocate(len));
2563 OS::SNPrint(chars, len, kFormat, function_name, reason); 2722 OS::SNPrint(chars, len, kFormat, function_name, reason);
2564 const Error& error = Error::Handle( 2723 const Error& error = Error::Handle(
2565 LanguageError::New(String::Handle(String::New(chars)))); 2724 LanguageError::New(String::Handle(String::New(chars))));
2566 Isolate::Current()->long_jump_base()->Jump(1, error); 2725 Isolate::Current()->long_jump_base()->Jump(1, error);
2567 } 2726 }
2568 2727
2569 2728
2570 } // namespace dart 2729 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698