comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2820:2b8ef0a06391

Clean up in the graph builder.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Mon, 30 May 2011 16:24:22 +0200
parents c3f64b66fc78
children 244921d7cf50
comparison
equal deleted inserted replaced
2819:774d2bc06148 2820:2b8ef0a06391
57 * The minimum value to which {@link C1XOptions#TraceBytecodeParserLevel} must be set to trace 57 * The minimum value to which {@link C1XOptions#TraceBytecodeParserLevel} must be set to trace
58 * the frame state before each bytecode instruction as it is parsed. 58 * the frame state before each bytecode instruction as it is parsed.
59 */ 59 */
60 public static final int TRACELEVEL_STATE = 2; 60 public static final int TRACELEVEL_STATE = 2;
61 61
62 /**
63 * An enumeration of flags describing scope attributes.
64 */
65 public enum Flag {
66 /**
67 * Scope is protected by an exception handler.
68 * This attribute is inherited by nested scopes.
69 */
70 HasHandler,
71
72 /**
73 * Code in scope cannot contain safepoints.
74 * This attribute is inherited by nested scopes.
75 */
76 NoSafepoints;
77
78 public final int mask = 1 << ordinal();
79 }
80
81 private final IR ir; 62 private final IR ir;
82 private final C1XCompilation compilation; 63 private final C1XCompilation compilation;
83 private final CiStatistics stats; 64 private final CiStatistics stats;
84 65
85 private final BytecodeStream stream; // the bytecode stream 66 private final BytecodeStream stream; // the bytecode stream
95 public int compare(Block o1, Block o2) { 76 public int compare(Block o1, Block o2) {
96 return o1.blockID - o2.blockID; 77 return o1.blockID - o2.blockID;
97 } 78 }
98 }); 79 });
99 80
100 /**
101 * Mask of {@link Flag} values.
102 */
103 private int flags;
104
105 // Exception handler list 81 // Exception handler list
106 private List<ExceptionHandler> exceptionHandlers; 82 private List<ExceptionHandler> exceptionHandlers;
107 83
108 private FrameStateBuilder frameState; // the current execution state 84 private FrameStateBuilder frameState; // the current execution state
109 private Instruction lastInstr; // the last instruction added 85 private Instruction lastInstr; // the last instruction added
111 private final LogStream log; 87 private final LogStream log;
112 88
113 private Value rootMethodSynchronizedObject; 89 private Value rootMethodSynchronizedObject;
114 90
115 private final Graph graph; 91 private final Graph graph;
116
117 private Merge unwindBlock;
118 92
119 /** 93 /**
120 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. 94 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation.
121 * 95 *
122 * @param compilation the compilation 96 * @param compilation the compilation
144 if (log != null) { 118 if (log != null) {
145 log.println(); 119 log.println();
146 log.println("Compiling " + compilation.method); 120 log.println("Compiling " + compilation.method);
147 } 121 }
148 122
149 if (rootMethod.noSafepoints()) {
150 flags |= Flag.NoSafepoints.mask;
151 }
152
153 // 2. compute the block map, setup exception handlers and get the entrypoint(s) 123 // 2. compute the block map, setup exception handlers and get the entrypoint(s)
154 BlockMap blockMap = compilation.getBlockMap(rootMethod); 124 BlockMap blockMap = compilation.getBlockMap(rootMethod);
155 125
156 blockList = new ArrayList<Block>(blockMap.blocks); 126 blockList = new ArrayList<Block>(blockMap.blocks);
157 blockFromBci = new Block[rootMethod.code().length]; 127 blockFromBci = new Block[rootMethod.code().length];
175 ExceptionHandler h = new ExceptionHandler(ch); 145 ExceptionHandler h = new ExceptionHandler(ch);
176 h.setEntryBlock(entry); 146 h.setEntryBlock(entry);
177 exceptionHandlers.add(h); 147 exceptionHandlers.add(h);
178 } 148 }
179 } 149 }
180 flags |= Flag.HasHandler.mask;
181
182 } 150 }
183 151
184 // 1. create the start block 152 // 1. create the start block
185 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); 153 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
186 markOnWorkList(startBlock); 154 markOnWorkList(startBlock);
295 int bci = target.startBci; 263 int bci = target.startBci;
296 264
297 FrameState existingState = ((StateSplit) first).stateBefore(); 265 FrameState existingState = ((StateSplit) first).stateBefore();
298 266
299 if (existingState == null) { 267 if (existingState == null) {
300 // assert first instanceof Merge ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader;
301
302 // copy state because it is modified 268 // copy state because it is modified
303 FrameState duplicate = newState.duplicate(bci); 269 FrameState duplicate = newState.duplicate(bci);
304 270
305 // if the block is a loop header, insert all necessary phis 271 // if the block is a loop header, insert all necessary phis
306 if (first instanceof LoopBegin && target.isLoopHeader) { 272 if (first instanceof LoopBegin && target.isLoopHeader) {
420 FrameState entryState = frameState.duplicateWithEmptyStack(bci); 386 FrameState entryState = frameState.duplicateWithEmptyStack(bci);
421 387
422 StateSplit entry = new Placeholder(graph); 388 StateSplit entry = new Placeholder(graph);
423 entry.setStateBefore(entryState); 389 entry.setStateBefore(entryState);
424 ExceptionObject exception = new ExceptionObject(graph); 390 ExceptionObject exception = new ExceptionObject(graph);
425 entry.appendNext(exception); 391 entry.setNext(exception);
426 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); 392 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception);
427 393
428 Instruction successor = createTarget(dispatchBlock, stateWithException); 394 Instruction successor = createTarget(dispatchBlock, stateWithException);
429 BlockEnd end = new Anchor(successor, graph); 395 BlockEnd end = new Anchor(successor, graph);
430 exception.appendNext(end); 396 exception.setNext(end);
431
432 if (x instanceof Invoke) { 397 if (x instanceof Invoke) {
433 ((Invoke) x).setExceptionEdge(entry); 398 ((Invoke) x).setExceptionEdge(entry);
434 } else { 399 } else {
435 ((Throw) x).setExceptionEdge(entry); 400 ((Throw) x).setExceptionEdge(entry);
436 } 401 }
1041 private Value append(Value v) { 1006 private Value append(Value v) {
1042 return v; 1007 return v;
1043 } 1008 }
1044 1009
1045 private Value appendWithBCI(Instruction x) { 1010 private Value appendWithBCI(Instruction x) {
1046 if (x.isAppended()) { 1011 assert x.next() == null && x.predecessors().size() == 0 : "instruction should not have been appended yet";
1047 // the instruction has already been added
1048 return x;
1049 }
1050
1051 assert x.next() == null : "instruction should not have been appended yet";
1052 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; 1012 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
1053 1013 lastInstr.setNext(x);
1054 lastInstr = lastInstr.appendNext(x); 1014
1015 lastInstr = x;
1055 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { 1016 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) {
1056 // bailout if we've exceeded the maximum inlining size 1017 // bailout if we've exceeded the maximum inlining size
1057 throw new CiBailout("Method and/or inlining is too large"); 1018 throw new CiBailout("Method and/or inlining is too large");
1058 } 1019 }
1059 1020
1112 1073
1113 frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore()); 1074 frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore());
1114 1075
1115 assert lock != null; 1076 assert lock != null;
1116 assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock; 1077 assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock;
1117 if (lock instanceof Instruction) { 1078
1118 Instruction l = (Instruction) lock;
1119 if (!l.isAppended()) {
1120 lock = appendWithBCI(l);
1121 }
1122 }
1123 // Exit the monitor and unwind the stack. 1079 // Exit the monitor and unwind the stack.
1124 genMonitorExit(lock); 1080 genMonitorExit(lock);
1125 append(new Unwind(frameState.apop(), graph)); 1081 append(new Unwind(frameState.apop(), graph));
1126 1082
1127 // The sync handler is always the last thing to add => we can clear the frameState. 1083 // The sync handler is always the last thing to add => we can clear the frameState.
1208 } 1164 }
1209 } 1165 }
1210 } 1166 }
1211 1167
1212 private void appendGoto(Instruction target) { 1168 private void appendGoto(Instruction target) {
1213 //if (target instanceof BlockBegin && !((BlockBegin)target).isLoopHeader) { 1169 lastInstr.setNext(target);
1214 // System.out.println("NOTOMITTED");
1215 //append(new Goto(target, graph));
1216 //} else {
1217 // System.out.println("omitted");
1218 lastInstr.appendNext(target);
1219 //}
1220 } 1170 }
1221 1171
1222 private void iterateBytecodesForBlock(Block block) { 1172 private void iterateBytecodesForBlock(Block block) {
1223 assert frameState != null; 1173 assert frameState != null;
1224 1174
1523 private void addExceptionHandler(ExceptionHandler handler) { 1473 private void addExceptionHandler(ExceptionHandler handler) {
1524 if (exceptionHandlers == null) { 1474 if (exceptionHandlers == null) {
1525 exceptionHandlers = new ArrayList<ExceptionHandler>(); 1475 exceptionHandlers = new ArrayList<ExceptionHandler>();
1526 } 1476 }
1527 exceptionHandlers.add(handler); 1477 exceptionHandlers.add(handler);
1528 flags |= Flag.HasHandler.mask;
1529 } 1478 }
1530 1479
1531 /** 1480 /**
1532 * Adds a block to the worklist, if it is not already in the worklist. 1481 * Adds a block to the worklist, if it is not already in the worklist.
1533 * This method will keep the worklist topologically stored (i.e. the lower 1482 * This method will keep the worklist topologically stored (i.e. the lower
1558 /** 1507 /**
1559 * Checks whether this graph has any handlers. 1508 * Checks whether this graph has any handlers.
1560 * @return {@code true} if there are any exception handlers 1509 * @return {@code true} if there are any exception handlers
1561 */ 1510 */
1562 private boolean hasHandler() { 1511 private boolean hasHandler() {
1563 return (flags & Flag.HasHandler.mask) != 0; 1512 return Modifier.isSynchronized(compilation.method.accessFlags()) || (compilation.method.exceptionHandlers() != null && compilation.method.exceptionHandlers().length > 0);
1564 }
1565
1566 /**
1567 * Checks whether this graph can contain safepoints.
1568 */
1569 private boolean noSafepoints() {
1570 return (flags & Flag.NoSafepoints.mask) != 0;
1571 } 1513 }
1572 } 1514 }