Mercurial > hg > graal-compiler
comparison graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java @ 2763:5e8a69041cd7
Model phi inputs as direct inputs in the graph instead of referring to the framestates of the predecessors.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Mon, 23 May 2011 14:51:18 +0200 |
parents | bdaf31906620 |
children | 99912abb3ff7 |
comparison
equal
deleted
inserted
replaced
2762:ca31e84ff154 | 2763:5e8a69041cd7 |
---|---|
254 /** | 254 /** |
255 * Inserts a phi statement into the stack at the specified stack index. | 255 * Inserts a phi statement into the stack at the specified stack index. |
256 * @param block the block begin for which we are creating the phi | 256 * @param block the block begin for which we are creating the phi |
257 * @param i the index into the stack for which to create a phi | 257 * @param i the index into the stack for which to create a phi |
258 */ | 258 */ |
259 public void setupPhiForStack(BlockBegin block, int i) { | 259 public Phi setupPhiForStack(BlockBegin block, int i) { |
260 Value p = stackAt(i); | 260 Value p = stackAt(i); |
261 if (p != null) { | 261 if (p != null) { |
262 if (p instanceof Phi) { | 262 if (p instanceof Phi) { |
263 Phi phi = (Phi) p; | 263 Phi phi = (Phi) p; |
264 if (phi.block() == block && phi.isOnStack() && phi.stackIndex() == i) { | 264 if (phi.block() == block && phi.isOnStack() && phi.stackIndex() == i) { |
265 return; | 265 return phi; |
266 } | 266 } |
267 } | 267 } |
268 inputs().set(localsSize + i, new Phi(p.kind, block, -i - 1, graph())); | 268 Phi phi = new Phi(p.kind, block, -i - 1, graph()); |
269 } | 269 inputs().set(localsSize + i, phi); |
270 return phi; | |
271 } | |
272 return null; | |
270 } | 273 } |
271 | 274 |
272 /** | 275 /** |
273 * Inserts a phi statement for the local at the specified index. | 276 * Inserts a phi statement for the local at the specified index. |
274 * @param block the block begin for which we are creating the phi | 277 * @param block the block begin for which we are creating the phi |
275 * @param i the index of the local variable for which to create the phi | 278 * @param i the index of the local variable for which to create the phi |
276 */ | 279 */ |
277 public void setupPhiForLocal(BlockBegin block, int i) { | 280 public Phi setupPhiForLocal(BlockBegin block, int i) { |
278 Value p = localAt(i); | 281 Value p = localAt(i); |
279 if (p instanceof Phi) { | 282 if (p instanceof Phi) { |
280 Phi phi = (Phi) p; | 283 Phi phi = (Phi) p; |
281 if (phi.block() == block && phi.isLocal() && phi.localIndex() == i) { | 284 if (phi.block() == block && phi.isLocal() && phi.localIndex() == i) { |
282 return; | 285 return phi; |
283 } | 286 } |
284 } | 287 } |
285 storeLocal(i, new Phi(p.kind, block, i, graph())); | 288 Phi phi = new Phi(p.kind, block, i, graph()); |
289 storeLocal(i, phi); | |
290 return phi; | |
286 } | 291 } |
287 | 292 |
288 /** | 293 /** |
289 * Gets the value at a specified index in the set of operand stack and local values represented by this frame. | 294 * Gets the value at a specified index in the set of operand stack and local values represented by this frame. |
290 * This method should only be used to iterate over all the values in this frame, irrespective of whether | 295 * This method should only be used to iterate over all the values in this frame, irrespective of whether |
310 */ | 315 */ |
311 public int valuesSize() { | 316 public int valuesSize() { |
312 return localsSize + stackSize; | 317 return localsSize + stackSize; |
313 } | 318 } |
314 | 319 |
315 public void checkPhis(BlockBegin block, FrameState other) { | |
316 checkSize(other); | |
317 for (int i = 0; i < valuesSize(); i++) { | |
318 Value x = valueAt(i); | |
319 Value y = other.valueAt(i); | |
320 if (x != null && x != y) { | |
321 if (x instanceof Phi) { | |
322 Phi phi = (Phi) x; | |
323 if (phi.block() == block) { | |
324 for (int j = 0; j < phi.phiInputCount(); j++) { | |
325 if (phi.inputIn(other) == null) { | |
326 throw new CiBailout("phi " + phi + " has null operand at new predecessor"); | |
327 } | |
328 } | |
329 continue; | |
330 } | |
331 } | |
332 throw new CiBailout("instruction is not a phi or null at " + i); | |
333 } | |
334 } | |
335 } | |
336 | |
337 private void checkSize(FrameStateAccess other) { | 320 private void checkSize(FrameStateAccess other) { |
338 if (other.stackSize() != stackSize()) { | 321 if (other.stackSize() != stackSize()) { |
339 throw new CiBailout("stack sizes do not match"); | 322 throw new CiBailout("stack sizes do not match"); |
340 } else if (other.localsSize() != localsSize) { | 323 } else if (other.localsSize() != localsSize) { |
341 throw new CiBailout("local sizes do not match"); | 324 throw new CiBailout("local sizes do not match"); |
342 } | 325 } |
343 } | 326 } |
344 | 327 |
345 public void merge(BlockBegin block, FrameStateAccess other) { | 328 public void merge(BlockBegin block, FrameStateAccess other, boolean blockAppended) { |
346 checkSize(other); | 329 checkSize(other); |
347 for (int i = 0; i < valuesSize(); i++) { | 330 for (int i = 0; i < valuesSize(); i++) { |
348 Value x = valueAt(i); | 331 Value x = valueAt(i); |
349 if (x != null) { | 332 if (x != null) { |
350 Value y = other.valueAt(i); | 333 Value y = other.valueAt(i); |
357 } | 340 } |
358 } | 341 } |
359 inputs().set(i, null); | 342 inputs().set(i, null); |
360 continue; | 343 continue; |
361 } | 344 } |
345 Phi phi = null; | |
362 if (i < localsSize) { | 346 if (i < localsSize) { |
363 // this a local | 347 // this a local |
364 setupPhiForLocal(block, i); | 348 phi = setupPhiForLocal(block, i); |
365 } else { | 349 } else { |
366 // this is a stack slot | 350 // this is a stack slot |
367 setupPhiForStack(block, i - localsSize); | 351 phi = setupPhiForStack(block, i - localsSize); |
352 } | |
353 | |
354 Phi originalPhi = phi; | |
355 if (phi.phiInputCount() == 0) { | |
356 int size = block.predecessors().size(); | |
357 if (blockAppended) { | |
358 size--; | |
359 } | |
360 for (int j = 0; j < size; ++j) { | |
361 phi = phi.addInput(x); | |
362 } | |
363 phi = phi.addInput(y); | |
364 } else { | |
365 phi = phi.addInput(y); | |
366 } | |
367 if (originalPhi != phi) { | |
368 for (int j = 0; j < other.localsSize() + other.stackSize(); ++j) { | |
369 if (other.valueAt(j) == originalPhi) { | |
370 other.setValueAt(j, phi); | |
371 } | |
372 } | |
368 } | 373 } |
369 } | 374 } |
370 } | 375 } |
371 } | 376 } |
372 } | 377 } |
465 } | 470 } |
466 | 471 |
467 public void visitFrameState(FrameState i) { | 472 public void visitFrameState(FrameState i) { |
468 // nothing to do for now | 473 // nothing to do for now |
469 } | 474 } |
475 | |
476 @Override | |
477 public void setValueAt(int j, Value v) { | |
478 inputs().set(j, v); | |
479 } | |
470 } | 480 } |