comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2746:05c92e53a50d

merge and clone before connecting blocks
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 20 May 2011 13:20:21 +0200
parents a3cd5eb68837
children 84f4c7dceb14
comparison
equal deleted inserted replaced
2743:55f1db570dfa 2746:05c92e53a50d
104 // Exception handler list 104 // Exception handler list
105 private List<ExceptionHandler> exceptionHandlers; 105 private List<ExceptionHandler> exceptionHandlers;
106 106
107 private final FrameStateBuilder frameState; // the current execution state 107 private final FrameStateBuilder frameState; // the current execution state
108 private Instruction lastInstr; // the last instruction added 108 private Instruction lastInstr; // the last instruction added
109 private Instruction placeholder;
110
111 109
112 private final LogStream log; 110 private final LogStream log;
113 111
114 private Value rootMethodSynchronizedObject; 112 private Value rootMethodSynchronizedObject;
115 113
195 } 193 }
196 } 194 }
197 flags |= Flag.HasHandler.mask; 195 flags |= Flag.HasHandler.mask;
198 } 196 }
199 197
200 assert !loopHeaders.contains(startBlock);
201 mergeOrClone(startBlockBegin, frameState, false); 198 mergeOrClone(startBlockBegin, frameState, false);
202 199
203 // 3. setup internal state for appending instructions 200 // 3. setup internal state for appending instructions
204 lastInstr = startBlockBegin; 201 lastInstr = startBlockBegin;
205 lastInstr.appendNext(null); 202 lastInstr.appendNext(null);
206 203
207 Instruction entryBlock = blockAt(0);
208 BlockBegin syncHandler = null; 204 BlockBegin syncHandler = null;
209 Block syncBlock = null; 205 Block syncBlock = null;
210 if (isSynchronized(rootMethod.accessFlags())) { 206 if (isSynchronized(rootMethod.accessFlags())) {
211 // 4A.1 add a monitor enter to the start block 207 // 4A.1 add a monitor enter to the start block
212 rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method); 208 rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method);
213 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); 209 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI);
214 // 4A.2 finish the start block 210 // 4A.2 finish the start block
215 finishStartBlock(startBlockBegin, entryBlock); 211 finishStartBlock(startBlock);
216 212
217 // 4A.3 setup an exception handler to unlock the root method synchronized object 213 // 4A.3 setup an exception handler to unlock the root method synchronized object
218 syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); 214 syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
219 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, graph); 215 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, graph);
220 syncBlock.firstInstruction = syncHandler; 216 syncBlock.firstInstruction = syncHandler;
223 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); 219 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null));
224 h.setEntryBlock(syncBlock); 220 h.setEntryBlock(syncBlock);
225 addExceptionHandler(h); 221 addExceptionHandler(h);
226 } else { 222 } else {
227 // 4B.1 simply finish the start block 223 // 4B.1 simply finish the start block
228 finishStartBlock(startBlockBegin, entryBlock); 224 finishStartBlock(startBlock);
229 } 225 }
230 226
231 // 5. SKIPPED: look for intrinsics 227 // 5. SKIPPED: look for intrinsics
232 228
233 // 6B.1 do the normal parsing 229 // 6B.1 do the normal parsing
266 262
267 private boolean isVisited(Block block) { 263 private boolean isVisited(Block block) {
268 return blocksVisited.contains(block); 264 return blocksVisited.contains(block);
269 } 265 }
270 266
271 private void finishStartBlock(BlockBegin startBlock, Instruction stdEntry) { 267 private void finishStartBlock(Block startBlock) {
272 assert bci() == 0; 268 assert bci() == 0;
273 FrameState stateAfter = frameState.create(bci()); 269 FrameState stateAfter = frameState.create(bci());
274 Goto base = new Goto((BlockBegin) stdEntry, stateAfter, graph); 270 Instruction target = createTargetAt(0, stateAfter);
271 Goto base = new Goto((BlockBegin) target, stateAfter, graph);
275 appendWithBCI(base); 272 appendWithBCI(base);
276 startBlock.setEnd(base); 273 ((BlockBegin) startBlock.firstInstruction).setEnd(base);
277 // assert stdEntry instanceof Placeholder; 274 }
278 assert ((BlockBegin) stdEntry).stateBefore() == null;
279 prepareTarget(0);
280 mergeOrClone(stdEntry, stateAfter, loopHeaders.contains(stdEntry));
281 }
282
283 private void prepareTarget(int bci) {
284 }
285
286 275
287 public void mergeOrClone(Block target, FrameStateAccess newState) { 276 public void mergeOrClone(Block target, FrameStateAccess newState) {
277 assert target.firstInstruction instanceof BlockBegin;
288 if (target.isLoopHeader) { 278 if (target.isLoopHeader) {
289 assert target.firstInstruction instanceof BlockBegin;
290 mergeOrClone(target.firstInstruction, newState, true); 279 mergeOrClone(target.firstInstruction, newState, true);
291 280 } else {
292 281 mergeOrClone(target.firstInstruction, newState, false);
293 } 282 }
294 } 283 }
295 284
296 285
297 private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader) { 286 private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader) {
503 ExceptionHandler newHandler = new ExceptionHandler(handler); 492 ExceptionHandler newHandler = new ExceptionHandler(handler);
504 493
505 // fill in exception handler subgraph lazily 494 // fill in exception handler subgraph lazily
506 if (!isVisited(entry)) { 495 if (!isVisited(entry)) {
507 if (handler.handlerBCI() != Instruction.SYNCHRONIZATION_ENTRY_BCI) { 496 if (handler.handlerBCI() != Instruction.SYNCHRONIZATION_ENTRY_BCI) {
508 addToWorkList(blockList[handler.handlerBCI()]); 497 addToWorkList(entry);
509 } 498 }
510 } else { 499 } else {
511 // This will occur for exception handlers that cover themselves. This code 500 // This will occur for exception handlers that cover themselves. This code
512 // pattern is generated by javac for synchronized blocks. See the following 501 // pattern is generated by javac for synchronized blocks. See the following
513 // for why this change to javac was made: 502 // for why this change to javac was made:
1080 private Instruction createTargetAt(int bci, FrameStateAccess stateAfter) { 1069 private Instruction createTargetAt(int bci, FrameStateAccess stateAfter) {
1081 return createTarget(blockList[bci], stateAfter); 1070 return createTarget(blockList[bci], stateAfter);
1082 } 1071 }
1083 1072
1084 private Instruction createTarget(Block block, FrameStateAccess stateAfter) { 1073 private Instruction createTarget(Block block, FrameStateAccess stateAfter) {
1074 mergeOrClone(block, stateAfter);
1075 addToWorkList(block);
1085 return block.firstInstruction; 1076 return block.firstInstruction;
1086 } 1077 }
1087 1078
1088 private void genLookupswitch() { 1079 private void genLookupswitch() {
1089 int bci = bci(); 1080 int bci = bci();
1122 } 1113 }
1123 1114
1124 assert x.next() == null : "instruction should not have been appended yet"; 1115 assert x.next() == null : "instruction should not have been appended yet";
1125 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; 1116 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
1126 1117
1127 if (placeholder != null) {
1128 placeholder = null;
1129 }
1130
1131 lastInstr = lastInstr.appendNext(x); 1118 lastInstr = lastInstr.appendNext(x);
1132 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { 1119 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) {
1133 // bailout if we've exceeded the maximum inlining size 1120 // bailout if we've exceeded the maximum inlining size
1134 throw new CiBailout("Method and/or inlining is too large"); 1121 throw new CiBailout("Method and/or inlining is too large");
1135 } 1122 }
1201 } 1188 }
1202 1189
1203 if (!isVisited(block)) { 1190 if (!isVisited(block)) {
1204 markVisited(block); 1191 markVisited(block);
1205 // now parse the block 1192 // now parse the block
1206 if (block.firstInstruction instanceof Placeholder) { 1193 frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore());
1207 assert false; 1194 lastInstr = block.firstInstruction;
1208 placeholder = block.firstInstruction;
1209 frameState.initializeFrom(((Placeholder) placeholder).stateBefore());
1210 lastInstr = null;
1211 } else {
1212 assert block.firstInstruction instanceof BlockBegin;
1213 placeholder = null;
1214 frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore());
1215 lastInstr = block.firstInstruction;
1216 }
1217 assert block.firstInstruction.next() == null; 1195 assert block.firstInstruction.next() == null;
1218 1196
1219 iterateBytecodesForBlock(block); 1197 iterateBytecodesForBlock(block);
1220 } 1198 }
1221 } 1199 }
1271 assert end != null : "end should exist after iterating over bytecodes"; 1249 assert end != null : "end should exist after iterating over bytecodes";
1272 FrameState stateAtEnd = frameState.create(bci()); 1250 FrameState stateAtEnd = frameState.create(bci());
1273 end.setStateAfter(stateAtEnd); 1251 end.setStateAfter(stateAtEnd);
1274 if (block.firstInstruction instanceof BlockBegin) { 1252 if (block.firstInstruction instanceof BlockBegin) {
1275 ((BlockBegin) block.firstInstruction).setEnd(end); 1253 ((BlockBegin) block.firstInstruction).setEnd(end);
1276 }
1277
1278 // propagate the state
1279 for (BlockBegin succ : end.blockSuccessors()) {
1280 assert succ.blockPredecessors().contains(end);
1281 mergeOrClone(succ, stateAtEnd, loopHeaders.contains(succ));
1282 addToWorkList(blockList[succ.bci()]);
1283 } 1254 }
1284 return end; 1255 return end;
1285 } 1256 }
1286 1257
1287 private void traceState() { 1258 private void traceState() {