comparison graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java @ 2616:3558ca7088c0

FrameState and Graphviz changes: * removed popx, pushx methods from GraphBuilder * FrameState subclass of Value * added String shortName() to Node * added GraphvizPrinter option to use short names * small hack in GraphvizPrinter: omit FrameState->Local connections * added GraalGraphviz to implicit classpatch (read from GRAAL env var)
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 09 May 2011 17:00:25 +0200
parents bd235cb4375a
children dd115f80acf8
comparison
equal deleted inserted replaced
2615:5768534fd4e5 2616:3558ca7088c0
39 * about the basic block, including the successor and 39 * about the basic block, including the successor and
40 * predecessor blocks, exception handlers, liveness information, etc. 40 * predecessor blocks, exception handlers, liveness information, etc.
41 */ 41 */
42 public final class BlockBegin extends Instruction { 42 public final class BlockBegin extends Instruction {
43 43
44 private static final int INPUT_COUNT = 0; 44 private static final int INPUT_COUNT = 1;
45 private static final int INPUT_STATE_BEFORE = 0;
46
45 private static final int SUCCESSOR_COUNT = 0; 47 private static final int SUCCESSOR_COUNT = 0;
48
49 @Override
50 protected int inputCount() {
51 return super.inputCount() + INPUT_COUNT;
52 }
53
54 @Override
55 protected int successorCount() {
56 return super.successorCount() + SUCCESSOR_COUNT;
57 }
58
59 /**
60 * The frame state before execution of the first instruction in this block.
61 */
62 @Override
63 public FrameState stateBefore() {
64 return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE);
65 }
66
67 public FrameState setStateBefore(FrameState n) {
68 assert stateBefore() == null;
69 return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n);
70 }
46 71
47 private static final List<BlockBegin> NO_HANDLERS = Collections.emptyList(); 72 private static final List<BlockBegin> NO_HANDLERS = Collections.emptyList();
48 73
49 /** 74 /**
50 * An enumeration of flags for block entries indicating various things. 75 * An enumeration of flags for block entries indicating various things.
74 * Denotes the current set of {@link BlockBegin.BlockFlag} settings. 99 * Denotes the current set of {@link BlockBegin.BlockFlag} settings.
75 */ 100 */
76 private int blockFlags; 101 private int blockFlags;
77 102
78 /** 103 /**
79 * The frame state before execution of the first instruction in this block.
80 */
81 private FrameState stateBefore;
82
83 /**
84 * A link to the last node in the block (which contains the successors). 104 * A link to the last node in the block (which contains the successors).
85 */ 105 */
86 private BlockEnd end; 106 private BlockEnd end;
87 107
88 /** 108 /**
178 * Gets the block end associated with this basic block. 198 * Gets the block end associated with this basic block.
179 * @return the block end 199 * @return the block end
180 */ 200 */
181 public BlockEnd end() { 201 public BlockEnd end() {
182 return end; 202 return end;
183 }
184
185 /**
186 * Gets the state at the start of this block.
187 * @return the state at the start of this block
188 */
189 @Override
190 public FrameState stateBefore() {
191 return stateBefore;
192 }
193
194 /**
195 * Sets the initial state for this block.
196 * @param stateBefore the state for this block
197 */
198 public void setStateBefore(FrameState stateBefore) {
199 assert this.stateBefore == null;
200 this.stateBefore = stateBefore;
201 } 203 }
202 204
203 /** 205 /**
204 * Gets the exception handlers that cover one or more instructions of this basic block. 206 * Gets the exception handlers that cover one or more instructions of this basic block.
205 * 207 *
397 @Override 399 @Override
398 public void accept(ValueVisitor v) { 400 public void accept(ValueVisitor v) {
399 v.visitBlockBegin(this); 401 v.visitBlockBegin(this);
400 } 402 }
401 403
402 public void mergeOrClone(FrameState newState, RiMethod method) { 404 public void mergeOrClone(FrameStateAccess newState, RiMethod method) {
403 FrameState existingState = stateBefore; 405 FrameState existingState = stateBefore();
404 406
405 if (existingState == null) { 407 if (existingState == null) {
406 // this is the first state for the block 408 // this is the first state for the block
407 if (wasVisited()) { 409 if (wasVisited()) {
408 // this can happen for complex jsr/ret patterns; just bail out 410 // this can happen for complex jsr/ret patterns; just bail out
409 throw new CiBailout("jsr/ret too complex"); 411 throw new CiBailout("jsr/ret too complex");
410 } 412 }
411 413
412 // copy state because it is modified 414 // copy state because it is modified
413 newState = newState.copy(); 415 FrameState duplicate = newState.duplicate();
414 416
415 if (C1XOptions.UseStackMapTableLiveness) { 417 if (C1XOptions.UseStackMapTableLiveness) {
416 // if a liveness map is available, use it to invalidate dead locals 418 // if a liveness map is available, use it to invalidate dead locals
417 CiBitMap[] livenessMap = method.livenessMap(); 419 CiBitMap[] livenessMap = method.livenessMap();
418 if (livenessMap != null && bci() >= 0) { 420 if (livenessMap != null && bci() >= 0) {
419 assert bci() < livenessMap.length; 421 assert bci() < livenessMap.length;
420 CiBitMap liveness = livenessMap[bci()]; 422 CiBitMap liveness = livenessMap[bci()];
421 if (liveness != null) { 423 if (liveness != null) {
422 invalidateDeadLocals(newState, liveness); 424 invalidateDeadLocals(duplicate, liveness);
423 } 425 }
424 } 426 }
425 } 427 }
426 428
427 // if the block is a loop header, insert all necessary phis 429 // if the block is a loop header, insert all necessary phis
428 if (isParserLoopHeader()) { 430 if (isParserLoopHeader()) {
429 insertLoopPhis(newState); 431 insertLoopPhis(duplicate);
430 } 432 }
431 433
432 stateBefore = newState; 434 setStateBefore(duplicate);
433 } else { 435 } else {
434 if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { 436 if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
435 // stacks or locks do not match--bytecodes would not verify 437 // stacks or locks do not match--bytecodes would not verify
436 throw new CiBailout("stack or locks do not match"); 438 throw new CiBailout("stack or locks do not match");
437 } 439 }
441 443
442 if (wasVisited() && !isParserLoopHeader()) { 444 if (wasVisited() && !isParserLoopHeader()) {
443 throw new CiBailout("jsr/ret too complicated"); 445 throw new CiBailout("jsr/ret too complicated");
444 } 446 }
445 447
446 existingState.merge(this, newState, graph()); 448 existingState.merge(this, newState);
447 } 449 }
448 } 450 }
449 451
450 private void invalidateDeadLocals(FrameState newState, CiBitMap liveness) { 452 private void invalidateDeadLocals(FrameState newState, CiBitMap liveness) {
451 int max = newState.localsSize(); 453 int max = newState.localsSize();
463 465
464 private void insertLoopPhis(FrameState newState) { 466 private void insertLoopPhis(FrameState newState) {
465 int stackSize = newState.stackSize(); 467 int stackSize = newState.stackSize();
466 for (int i = 0; i < stackSize; i++) { 468 for (int i = 0; i < stackSize; i++) {
467 // always insert phis for the stack 469 // always insert phis for the stack
468 newState.setupPhiForStack(this, i, graph()); 470 newState.setupPhiForStack(this, i);
469 } 471 }
470 int localsSize = newState.localsSize(); 472 int localsSize = newState.localsSize();
471 for (int i = 0; i < localsSize; i++) { 473 for (int i = 0; i < localsSize; i++) {
472 Value x = newState.localAt(i); 474 Value x = newState.localAt(i);
473 if (x != null) { 475 if (x != null) {
474 newState.setupPhiForLocal(this, i, graph()); 476 newState.setupPhiForLocal(this, i);
475 } 477 }
476 } 478 }
477 } 479 }
478 480
479 public boolean isStandardEntry() { 481 public boolean isStandardEntry() {