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

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

Issue 10657044: Fix a bug in liveness analysis code and add more comments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
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
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | no next file » | 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_allocator.h" 5 #include "vm/flow_graph_allocator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/flow_graph_compiler.h" 9 #include "vm/flow_graph_compiler.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 DEFINE_FLAG(bool, print_ssa_liveness, false, 13 DEFINE_FLAG(bool, print_ssa_liveness, false,
14 "Print liveness for ssa variables."); 14 "Print liveness for ssa variables.");
15 15
16 FlowGraphAllocator::FlowGraphAllocator( 16 FlowGraphAllocator::FlowGraphAllocator(
17 const GrowableArray<BlockEntryInstr*>& postorder, 17 const GrowableArray<BlockEntryInstr*>& postorder,
18 intptr_t max_ssa_temp_index) 18 intptr_t max_ssa_temp_index)
19 : live_out_(postorder.length()), 19 : live_out_(postorder.length()),
20 kill_(postorder.length()), 20 kill_(postorder.length()),
21 gen_(postorder.length()),
22 live_in_(postorder.length()), 21 live_in_(postorder.length()),
23 postorder_(postorder), 22 postorder_(postorder),
24 vreg_count_(max_ssa_temp_index) { 23 vreg_count_(max_ssa_temp_index) {
25 } 24 }
26 25
27 26
28 void FlowGraphAllocator::ResolveConstraints() { 27 void FlowGraphAllocator::ResolveConstraints() {
29 // TODO(fschneider): Resolve register constraints. 28 // TODO(fschneider): Resolve register constraints.
30 } 29 }
31 30
32 31
33 static intptr_t ToVirtualRegister(Instruction* instr) { 32 static intptr_t ToVirtualRegister(Instruction* instr) {
34 const Definition* def = instr->AsDefinition(); 33 const Definition* def = instr->AsDefinition();
35 if (def == NULL) return -1; 34 return (def == NULL) ? -1 : def->ssa_temp_index();
36 return def->ssa_temp_index();
37 } 35 }
38 36
39 37
40 void FlowGraphAllocator::ComputeKillAndGenSets() { 38 void FlowGraphAllocator::ComputeInitialSets() {
41 const intptr_t block_count = postorder_.length(); 39 const intptr_t block_count = postorder_.length();
42 for (intptr_t i = 0; i < block_count; i++) { 40 for (intptr_t i = 0; i < block_count; i++) {
43 BlockEntryInstr* block = postorder_[i]; 41 BlockEntryInstr* block = postorder_[i];
44 42
45 BitVector* kill = kill_[i]; 43 BitVector* kill = kill_[i];
46 BitVector* live_in = live_in_[i]; 44 BitVector* live_in = live_in_[i];
47 45
48 if (block->IsJoinEntry()) { 46 if (block->IsJoinEntry()) {
49 JoinEntryInstr* join = block->AsJoinEntry(); 47 JoinEntryInstr* join = block->AsJoinEntry();
50 if (join->phis() != NULL) { 48 if (join->phis() != NULL) {
(...skipping 25 matching lines...) Expand all
76 if (!input->IsUse()) continue; 74 if (!input->IsUse()) continue;
77 const intptr_t use = ToVirtualRegister(input->AsUse()->definition()); 75 const intptr_t use = ToVirtualRegister(input->AsUse()->definition());
78 if ((use >= 0) && !kill->Contains(use)) live_in->Add(use); 76 if ((use >= 0) && !kill->Contains(use)) live_in->Add(use);
79 } 77 }
80 78
81 const intptr_t def = ToVirtualRegister(current); 79 const intptr_t def = ToVirtualRegister(current);
82 if (def >= 0) kill->Add(def); 80 if (def >= 0) kill->Add(def);
83 81
84 current = current->StraightLineSuccessor(); 82 current = current->StraightLineSuccessor();
85 } 83 }
84 }
86 85
87 UpdateLiveIn(block); 86 // Update initial live_in sets to match live_out sets. Has to be
87 // done in a separate path because of backwards branches.
88 for (intptr_t i = 0; i < block_count; i++) {
89 UpdateLiveIn(postorder_[i]);
88 } 90 }
89 } 91 }
90 92
91 93
92 bool FlowGraphAllocator::UpdateLiveOut(BlockEntryInstr* instr) { 94 bool FlowGraphAllocator::UpdateLiveOut(BlockEntryInstr* instr) {
93 BitVector* live_out = live_out_[instr->postorder_number()]; 95 BitVector* live_out = live_out_[instr->postorder_number()];
94 bool changed = false; 96 bool changed = false;
95 Instruction* last = instr->last_instruction(); 97 Instruction* last = instr->last_instruction();
98 ASSERT(last != NULL);
96 for (intptr_t i = 0; i < last->SuccessorCount(); i++) { 99 for (intptr_t i = 0; i < last->SuccessorCount(); i++) {
97 BlockEntryInstr* succ = last->SuccessorAt(i); 100 BlockEntryInstr* succ = last->SuccessorAt(i);
101 ASSERT(succ != NULL);
98 if (live_out->AddAll(live_in_[succ->postorder_number()])) { 102 if (live_out->AddAll(live_in_[succ->postorder_number()])) {
99 changed = true; 103 changed = true;
100 } 104 }
101 } 105 }
102 return changed; 106 return changed;
103 } 107 }
104 108
105 109
106 bool FlowGraphAllocator::UpdateLiveIn(BlockEntryInstr* instr) { 110 bool FlowGraphAllocator::UpdateLiveIn(BlockEntryInstr* instr) {
107 BitVector* live_out = live_out_[instr->postorder_number()]; 111 BitVector* live_out = live_out_[instr->postorder_number()];
108 BitVector* kill = kill_[instr->postorder_number()]; 112 BitVector* kill = kill_[instr->postorder_number()];
109 BitVector* live_in = live_in_[instr->postorder_number()]; 113 BitVector* live_in = live_in_[instr->postorder_number()];
110 return live_in->KillAndAdd(kill, live_out); 114 return live_in->KillAndAdd(kill, live_out);
111 } 115 }
112 116
113 117
114 void FlowGraphAllocator::ComputeLiveInAndLiveOutSets() { 118 void FlowGraphAllocator::ComputeLiveInAndLiveOutSets() {
115 const intptr_t block_count = postorder_.length(); 119 const intptr_t block_count = postorder_.length();
116 bool changed; 120 bool changed;
117 do { 121 do {
118 changed = false; 122 changed = false;
119 123
120 for (intptr_t i = 0; i < block_count; i++) { 124 for (intptr_t i = 0; i < block_count; i++) {
121 BlockEntryInstr* block = postorder_[i]; 125 BlockEntryInstr* block = postorder_[i];
126
127 // Live-in set depends only on kill set which does not
128 // change in this loop and live-out set. If live-out
129 // set does not change there is no need to recompute
130 // live-in set.
122 if (UpdateLiveOut(block) && UpdateLiveIn(block)) { 131 if (UpdateLiveOut(block) && UpdateLiveIn(block)) {
123 changed = true; 132 changed = true;
124 } 133 }
125 } 134 }
126 } while (changed); 135 } while (changed);
127 } 136 }
128 137
129 138
130 void FlowGraphAllocator::AnalyzeLiveness() { 139 void FlowGraphAllocator::AnalyzeLiveness() {
131 const intptr_t block_count = postorder_.length(); 140 const intptr_t block_count = postorder_.length();
132 for (intptr_t i = 0; i < block_count; i++) { 141 for (intptr_t i = 0; i < block_count; i++) {
133 live_out_.Add(new BitVector(vreg_count_)); 142 live_out_.Add(new BitVector(vreg_count_));
134 kill_.Add(new BitVector(vreg_count_)); 143 kill_.Add(new BitVector(vreg_count_));
135 live_in_.Add(new BitVector(vreg_count_)); 144 live_in_.Add(new BitVector(vreg_count_));
136 } 145 }
137 146
138 ComputeKillAndGenSets(); 147 ComputeInitialSets();
139 ComputeLiveInAndLiveOutSets(); 148 ComputeLiveInAndLiveOutSets();
140 149
141 if (FLAG_print_ssa_liveness) { 150 if (FLAG_print_ssa_liveness) {
142 DumpLiveness(); 151 DumpLiveness();
143 } 152 }
144 } 153 }
145 154
146 155
147 static void PrintBitVector(const char* tag, BitVector* v) { 156 static void PrintBitVector(const char* tag, BitVector* v) {
148 OS::Print("%s:", tag); 157 OS::Print("%s:", tag);
(...skipping 18 matching lines...) Expand all
167 OS::Print("\n"); 176 OS::Print("\n");
168 177
169 PrintBitVector(" live out", live_out_[i]); 178 PrintBitVector(" live out", live_out_[i]);
170 PrintBitVector(" kill", kill_[i]); 179 PrintBitVector(" kill", kill_[i]);
171 PrintBitVector(" live in", live_in_[i]); 180 PrintBitVector(" live in", live_in_[i]);
172 } 181 }
173 } 182 }
174 183
175 184
176 } // namespace dart 185 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698