Mercurial > hg > truffle
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() { |