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

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

Issue 11043016: Set previous instruction pointers when building the graph. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 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
« no previous file with comments | « no previous file | runtime/vm/flow_graph_allocator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.h" 5 #include "vm/flow_graph.h"
6 6
7 #include "vm/assert.h" 7 #include "vm/assert.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/intermediate_language.h" 10 #include "vm/intermediate_language.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 assigned_vars_.Clear(); 44 assigned_vars_.Clear();
45 // Perform a depth-first traversal of the graph to build preorder and 45 // Perform a depth-first traversal of the graph to build preorder and
46 // postorder block orders. 46 // postorder block orders.
47 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. 47 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor.
48 &preorder_, 48 &preorder_,
49 &postorder_, 49 &postorder_,
50 &parent_, 50 &parent_,
51 &assigned_vars_, 51 &assigned_vars_,
52 variable_count(), 52 variable_count(),
53 num_non_copied_params()); 53 num_non_copied_params());
54 // Number blocks in reverse postorder. 54 // Create an array of blocks in reverse postorder.
55 intptr_t block_count = postorder_.length(); 55 intptr_t block_count = postorder_.length();
56 for (intptr_t i = 0; i < block_count; ++i) { 56 for (intptr_t i = 0; i < block_count; ++i) {
57 reverse_postorder_.Add(postorder_[block_count - i - 1]); 57 reverse_postorder_.Add(postorder_[block_count - i - 1]);
58 } 58 }
59 // Link instructions backwards for optimized compilation.
60 // TODO(zerny): The builder should do this at construction time.
61 for (intptr_t i = 0; i < block_count; ++i) {
62 BlockEntryInstr* entry = postorder_[i];
63 Instruction* previous = entry;
64 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
65 Instruction* current = it.Current();
66 current->set_previous(previous);
67 previous = current;
68 }
69 }
70 } 59 }
71 60
72 61
73 #ifdef DEBUG 62 #ifdef DEBUG
74 // Debugging code to verify the construction of use lists. 63 // Debugging code to verify the construction of use lists.
75 64
76 static intptr_t MembershipCount(Value* use, Value* list) { 65 static intptr_t MembershipCount(Value* use, Value* list) {
77 intptr_t count = 0; 66 intptr_t count = 0;
78 while (list != NULL) { 67 while (list != NULL) {
79 if (list == use) ++count; 68 if (list == use) ++count;
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 phi->SetInputAt(i, use); 749 phi->SetInputAt(i, use);
761 use->set_use_index(i); 750 use->set_use_index(i);
762 } 751 }
763 // Write the predecessor use at the end. 752 // Write the predecessor use at the end.
764 phi->SetInputAt(pred_count - 1, pred_use); 753 phi->SetInputAt(pred_count - 1, pred_use);
765 pred_use->set_use_index(pred_count - 1); 754 pred_use->set_use_index(pred_count - 1);
766 } 755 }
767 } 756 }
768 757
769 758
770 // Helper to link two instructions in the graph.
771 static void Link(Instruction* prev, Instruction* next) {
772 ASSERT(prev != next);
773 prev->set_next(next);
774 next->set_previous(prev);
775 }
776
777
778 // Helper to sort a list of blocks. 759 // Helper to sort a list of blocks.
779 static int LowestBlockIdFirst(BlockEntryInstr* const* a, 760 static int LowestBlockIdFirst(BlockEntryInstr* const* a,
780 BlockEntryInstr* const* b) { 761 BlockEntryInstr* const* b) {
781 return (*a)->block_id() - (*b)->block_id(); 762 return (*a)->block_id() - (*b)->block_id();
782 } 763 }
783 764
784 765
785 // Inline a flow graph at a call site. 766 // Inline a flow graph at a call site.
786 // 767 //
787 // Assumes the callee graph was computed by BuildGraph with an inlining context 768 // Assumes the callee graph was computed by BuildGraph with an inlining context
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 807
827 // Insert the callee graph into the caller graph. 808 // Insert the callee graph into the caller graph.
828 if (callee_exits->is_empty()) { 809 if (callee_exits->is_empty()) {
829 // TODO(zerny): Add support for non-local exits, such as throw. 810 // TODO(zerny): Add support for non-local exits, such as throw.
830 UNREACHABLE(); 811 UNREACHABLE();
831 } else if (callee_exits->length() == 1) { 812 } else if (callee_exits->length() == 1) {
832 ReturnInstr* exit = (*callee_exits)[0]; 813 ReturnInstr* exit = (*callee_exits)[0];
833 ASSERT(exit->previous() != NULL); 814 ASSERT(exit->previous() != NULL);
834 // For just one exit, replace the uses and remove the call from the graph. 815 // For just one exit, replace the uses and remove the call from the graph.
835 call->ReplaceUsesWith(exit->value()->definition()); 816 call->ReplaceUsesWith(exit->value()->definition());
836 Link(call->previous(), callee_entry->next()); 817 call->previous()->LinkTo(callee_entry->next());
837 Link(exit->previous(), call->next()); 818 exit->previous()->LinkTo(call->next());
838 // In case of control flow, locally update the dominator tree. 819 // In case of control flow, locally update the dominator tree.
839 if (callee_graph->preorder().length() > 2) { 820 if (callee_graph->preorder().length() > 2) {
840 // The caller block is split and the new block id is that of the exit 821 // The caller block is split and the new block id is that of the exit
841 // block. If the caller block had outgoing edges, reorder the phis so they 822 // block. If the caller block had outgoing edges, reorder the phis so they
842 // are still ordered by block id. 823 // are still ordered by block id.
843 ReorderPhis(caller_entry); 824 ReorderPhis(caller_entry);
844 // The callee return is now the immediate dominator of blocks whose 825 // The callee return is now the immediate dominator of blocks whose
845 // immediate dominator was the caller entry. 826 // immediate dominator was the caller entry.
846 BlockEntryInstr* exit_block = exit->GetBlock(); 827 BlockEntryInstr* exit_block = exit->GetBlock();
847 ASSERT(exit_block->dominated_blocks().is_empty()); 828 ASSERT(exit_block->dominated_blocks().is_empty());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 ASSERT(exit_instr != NULL); 874 ASSERT(exit_instr != NULL);
894 Value* use = exit_instr->value(); 875 Value* use = exit_instr->value();
895 phi->SetInputAt(i, use); 876 phi->SetInputAt(i, use);
896 use->set_instruction(phi); 877 use->set_instruction(phi);
897 use->set_use_index(i); 878 use->set_use_index(i);
898 } 879 }
899 // Replace uses of the call with the phi. 880 // Replace uses of the call with the phi.
900 call->ReplaceUsesWith(phi); 881 call->ReplaceUsesWith(phi);
901 } 882 }
902 // Remove the call from the graph. 883 // Remove the call from the graph.
903 Link(call->previous(), callee_entry->next()); 884 call->previous()->LinkTo(callee_entry->next());
904 Link(join, call->next()); 885 join->LinkTo(call->next());
905 // The caller block is split and the new block id is that of the join 886 // The caller block is split and the new block id is that of the join
906 // block. If the caller block had outgoing edges, reorder the phis so they 887 // block. If the caller block had outgoing edges, reorder the phis so they
907 // are still ordered by block id. 888 // are still ordered by block id.
908 ReorderPhis(caller_entry); 889 ReorderPhis(caller_entry);
909 // Adjust pre/post orders and update the dominator tree. 890 // Adjust pre/post orders and update the dominator tree.
910 DiscoverBlocks(); 891 DiscoverBlocks();
911 // TODO(zerny): Compute the dominator frontier locally. 892 // TODO(zerny): Compute the dominator frontier locally.
912 GrowableArray<BitVector*> dominance_frontier; 893 GrowableArray<BitVector*> dominance_frontier;
913 ComputeDominators(&dominance_frontier); 894 ComputeDominators(&dominance_frontier);
914 } 895 }
915 } 896 }
916 897
917 898
918 intptr_t FlowGraph::InstructionCount() const { 899 intptr_t FlowGraph::InstructionCount() const {
919 intptr_t size = 0; 900 intptr_t size = 0;
920 // Iterate each block, skipping the graph entry. 901 // Iterate each block, skipping the graph entry.
921 for (intptr_t i = 1; i < preorder_.length(); ++i) { 902 for (intptr_t i = 1; i < preorder_.length(); ++i) {
922 for (ForwardInstructionIterator it(preorder_[i]); 903 for (ForwardInstructionIterator it(preorder_[i]);
923 !it.Done(); 904 !it.Done();
924 it.Advance()) { 905 it.Advance()) {
925 ++size; 906 ++size;
926 } 907 }
927 } 908 }
928 return size; 909 return size;
929 } 910 }
930 911
931 912
932 } // namespace dart 913 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698