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

Side by Side Diff: lib/compiler/implementation/ssa/variable_allocator.dart

Issue 10667013: Transitively mark inputs as live when they are generateAtUseSite. (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 | « lib/compiler/implementation/ssa/codegen.dart ('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 /** 5 /**
6 * The [LiveRange] class covers a range where an instruction is live. 6 * The [LiveRange] class covers a range where an instruction is live.
7 */ 7 */
8 class LiveRange { 8 class LiveRange {
9 final int start; 9 final int start;
10 // [end] is not final because it can be updated due to loops. 10 // [end] is not final because it can be updated due to loops.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 assert(!loopMarkers.containsKey(header)); 174 assert(!loopMarkers.containsKey(header));
175 loopMarkers[header] = id; 175 loopMarkers[header] = id;
176 } 176 }
177 177
178 void removeLoopMarker(HBasicBlock header) { 178 void removeLoopMarker(HBasicBlock header) {
179 assert(loopMarkers.containsKey(header)); 179 assert(loopMarkers.containsKey(header));
180 loopMarkers.remove(header); 180 loopMarkers.remove(header);
181 } 181 }
182 182
183 bool isEmpty() => liveInstructions.isEmpty() && loopMarkers.isEmpty(); 183 bool isEmpty() => liveInstructions.isEmpty() && loopMarkers.isEmpty();
184 bool contains(HInstruction instruction) => liveInstructions.containsKey(instru ction); 184 bool contains(HInstruction instruction) =>
185 liveInstructions.containsKey(instruction);
185 String toString() => liveInstructions.toString(); 186 String toString() => liveInstructions.toString();
186 } 187 }
187 188
188 /** 189 /**
189 * Builds the live intervals of each instruction. The algorithm visits 190 * Builds the live intervals of each instruction. The algorithm visits
190 * the graph post-dominator tree to find the last uses of an 191 * the graph post-dominator tree to find the last uses of an
191 * instruction, and computes the liveIns of each basic block. 192 * instruction, and computes the liveIns of each basic block.
192 */ 193 */
193 class SsaLiveIntervalBuilder extends HBaseVisitor { 194 class SsaLiveIntervalBuilder extends HBaseVisitor {
194 final Compiler compiler; 195 final Compiler compiler;
196 final Set<HInstruction> generateAtUseSite;
195 197
196 /** 198 /**
197 * A counter to assign start and end ids to live ranges. The initial 199 * A counter to assign start and end ids to live ranges. The initial
198 * value is not relevant. Note that instructionId goes downward to ease 200 * value is not relevant. Note that instructionId goes downward to ease
199 * reasoning about live ranges (the first instruction of a graph has 201 * reasoning about live ranges (the first instruction of a graph has
200 * the lowest id). 202 * the lowest id).
201 */ 203 */
202 int instructionId = 0; 204 int instructionId = 0;
203 205
204 /** 206 /**
205 * The liveIns of basic blocks. 207 * The liveIns of basic blocks.
206 */ 208 */
207 final Map<HBasicBlock, LiveEnvironment> liveInstructions; 209 final Map<HBasicBlock, LiveEnvironment> liveInstructions;
208 210
209 /** 211 /**
210 * The live intervals of instructions. 212 * The live intervals of instructions.
211 */ 213 */
212 final Map<HInstruction, LiveInterval> liveIntervals; 214 final Map<HInstruction, LiveInterval> liveIntervals;
213 215
214 SsaLiveIntervalBuilder(this.compiler) 216 SsaLiveIntervalBuilder(this.compiler, this.generateAtUseSite)
215 : liveInstructions = new Map<HBasicBlock, LiveEnvironment>(), 217 : liveInstructions = new Map<HBasicBlock, LiveEnvironment>(),
216 liveIntervals = new Map<HInstruction, LiveInterval>(); 218 liveIntervals = new Map<HInstruction, LiveInterval>();
217 219
218 void visitGraph(HGraph graph) { 220 void visitGraph(HGraph graph) {
219 visitPostDominatorTree(graph); 221 visitPostDominatorTree(graph);
220 if (!liveInstructions[graph.entry].isEmpty()) { 222 if (!liveInstructions[graph.entry].isEmpty()) {
221 compiler.internalError('LiveIntervalBuilder', 223 compiler.internalError('LiveIntervalBuilder',
222 node: compiler.currentElement.parseNode(compiler)); 224 node: compiler.currentElement.parseNode(compiler));
223 } 225 }
224 } 226 }
225 227
228 void markInputsAsLiveInEnvironment(HInstruction instruction,
229 LiveEnvironment environment) {
230 for (int i = 0, len = instruction.inputs.length; i < len; i++) {
231 markAsLiveInEnvironment(instruction.inputs[i], environment);
232 }
233 }
234
235 void markAsLiveInEnvironment(HInstruction instruction,
236 LiveEnvironment environment) {
237 if (environment.contains(instruction)) return;
238 environment.add(instruction, instructionId);
239 // HPhis are treated specially.
ngeoffray 2012/08/17 13:04:53 Do you remember if removing the HPhi check trigger
floitsch 2012/10/03 09:22:39 Sorry. Don't remember.
240 if (generateAtUseSite.contains(instruction) && instruction is !HPhi) {
241 markInputsAsLiveInEnvironment(instruction, environment);
242 }
243 }
244
226 void visitBasicBlock(HBasicBlock block) { 245 void visitBasicBlock(HBasicBlock block) {
227 LiveEnvironment environment = new LiveEnvironment(liveIntervals, instruction Id); 246 LiveEnvironment environment =
247 new LiveEnvironment(liveIntervals, instructionId);
228 248
229 // Add to the environment the liveIn of its successor, as well as 249 // Add to the environment the liveIn of its successor, as well as
230 // the inputs of the phis of the successor that flow from this block. 250 // the inputs of the phis of the successor that flow from this block.
231 for (int i = 0; i < block.successors.length; i++) { 251 for (int i = 0; i < block.successors.length; i++) {
232 HBasicBlock successor = block.successors[i]; 252 HBasicBlock successor = block.successors[i];
233 LiveEnvironment successorEnv = liveInstructions[successor]; 253 LiveEnvironment successorEnv = liveInstructions[successor];
234 if (successorEnv !== null) { 254 if (successorEnv !== null) {
235 environment.mergeWith(successorEnv); 255 environment.mergeWith(successorEnv);
236 } else { 256 } else {
237 environment.addLoopMarker(successor, instructionId); 257 environment.addLoopMarker(successor, instructionId);
238 } 258 }
239 259
240 int index = successor.predecessors.indexOf(block); 260 int index = successor.predecessors.indexOf(block);
241 for (HPhi phi = successor.phis.first; phi != null; phi = phi.next) { 261 for (HPhi phi = successor.phis.first; phi != null; phi = phi.next) {
242 environment.add(phi.inputs[index], instructionId); 262 markAsLiveInEnvironment(phi.inputs[index], environment);
243 } 263 }
244 } 264 }
245 265
246 // Iterate over all instructions to remove an instruction from the 266 // Iterate over all instructions to remove an instruction from the
247 // environment and add its inputs. 267 // environment and add its inputs.
248 HInstruction instruction = block.last; 268 HInstruction instruction = block.last;
249 while (instruction != null) { 269 while (instruction != null) {
250 environment.remove(instruction, instructionId); 270 environment.remove(instruction, instructionId);
251 for (int i = 0, len = instruction.inputs.length; i < len; i++) { 271 markInputsAsLiveInEnvironment(instruction, environment);
252 environment.add(instruction.inputs[i], instructionId);
253 }
254 instruction = instruction.previous; 272 instruction = instruction.previous;
255 instructionId--; 273 instructionId--;
256 } 274 }
257 275
258 // We just remove the phis from the environment. The inputs of the 276 // We just remove the phis from the environment. The inputs of the
259 // phis will be put in the environment of the predecessors. 277 // phis will be put in the environment of the predecessors.
260 for (HPhi phi = block.phis.first; phi != null; phi = phi.next) { 278 for (HPhi phi = block.phis.first; phi != null; phi = phi.next) {
261 environment.remove(phi, instructionId); 279 environment.remove(phi, instructionId);
262 } 280 }
263 281
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 if (!needsName(input)) { 640 if (!needsName(input)) {
623 names.addAssignment(predecessor, input, phi); 641 names.addAssignment(predecessor, input, phi);
624 } else { 642 } else {
625 names.addCopy(predecessor, input, phi); 643 names.addCopy(predecessor, input, phi);
626 } 644 }
627 } 645 }
628 646
629 namer.allocateName(phi); 647 namer.allocateName(phi);
630 } 648 }
631 } 649 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698