Mercurial > hg > truffle
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2782:915456e4959e
Merge
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 25 May 2011 11:15:24 +0200 |
parents | bda5972a40a5 |
children | 9bc0c2eb00d6 |
comparison
equal
deleted
inserted
replaced
2780:79dda81dd337 | 2782:915456e4959e |
---|---|
163 blockFromBci[block.startBci] = block; | 163 blockFromBci[block.startBci] = block; |
164 } | 164 } |
165 // System.out.println("block " + blockID + " @ " + block.startBci); | 165 // System.out.println("block " + blockID + " @ " + block.startBci); |
166 } | 166 } |
167 | 167 |
168 // 1. create the start block | |
169 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); | |
170 BlockBegin startBlockBegin = new BlockBegin(0, startBlock.blockID, false, graph); | |
171 startBlock.firstInstruction = startBlockBegin; | |
172 | |
173 graph.start().setStart(startBlockBegin); | |
174 | |
175 RiExceptionHandler[] handlers = rootMethod.exceptionHandlers(); | 168 RiExceptionHandler[] handlers = rootMethod.exceptionHandlers(); |
176 if (handlers != null && handlers.length > 0) { | 169 if (handlers != null && handlers.length > 0) { |
177 exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length); | 170 exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length); |
178 for (RiExceptionHandler ch : handlers) { | 171 for (RiExceptionHandler ch : handlers) { |
179 Block entry = blockFromBci[ch.handlerBCI()]; | 172 Block entry = blockFromBci[ch.handlerBCI()]; |
185 } | 178 } |
186 } | 179 } |
187 flags |= Flag.HasHandler.mask; | 180 flags |= Flag.HasHandler.mask; |
188 } | 181 } |
189 | 182 |
190 mergeOrClone(startBlock, frameState); | 183 // 1. create the start block |
191 | 184 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); |
192 // 3. setup internal state for appending instructions | 185 markOnWorkList(startBlock); |
193 lastInstr = startBlockBegin; | 186 lastInstr = createTarget(startBlock, frameState); |
194 lastInstr.appendNext(null); | 187 graph.start().setStart(lastInstr); |
195 | 188 |
196 BlockBegin syncHandler = null; | |
197 Block syncBlock = null; | 189 Block syncBlock = null; |
198 if (isSynchronized(rootMethod.accessFlags())) { | 190 if (isSynchronized(rootMethod.accessFlags())) { |
199 // 4A.1 add a monitor enter to the start block | 191 // 4A.1 add a monitor enter to the start block |
200 rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method); | 192 rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method); |
201 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); | 193 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); |
202 // 4A.2 finish the start block | 194 // 4A.2 finish the start block |
203 finishStartBlock(startBlock); | 195 finishStartBlock(startBlock); |
204 | 196 |
205 // 4A.3 setup an exception handler to unlock the root method synchronized object | 197 // 4A.3 setup an exception handler to unlock the root method synchronized object |
206 syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); | 198 syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); |
207 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, syncBlock.blockID, false, graph); | |
208 syncBlock.firstInstruction = syncHandler; | |
209 markOnWorkList(syncBlock); | 199 markOnWorkList(syncBlock); |
210 | 200 |
211 ExceptionBlock excBlock = new ExceptionBlock(); | |
212 excBlock.startBci = -1; | |
213 excBlock.endBci = -1; | |
214 excBlock.blockID = ir.nextBlockNumber(); | |
215 blockList.add(excBlock); | |
216 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); | 201 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); |
217 h.setEntryBlock(syncBlock); | 202 h.setEntryBlock(syncBlock); |
218 addExceptionHandler(h); | 203 addExceptionHandler(h); |
219 } else { | 204 } else { |
220 // 4B.1 simply finish the start block | 205 // 4B.1 simply finish the start block |
225 | 210 |
226 // 6B.1 do the normal parsing | 211 // 6B.1 do the normal parsing |
227 addToWorkList(blockFromBci[0]); | 212 addToWorkList(blockFromBci[0]); |
228 iterateAllBlocks(); | 213 iterateAllBlocks(); |
229 | 214 |
230 if (syncBlock != null && syncHandler.stateBefore() != null) { | 215 if (syncBlock != null && syncBlock.firstInstruction != null) { |
231 // generate unlocking code if the exception handler is reachable | 216 // generate unlocking code if the exception handler is reachable |
232 fillSyncHandler(rootMethodSynchronizedObject, syncBlock); | 217 fillSyncHandler(rootMethodSynchronizedObject, syncBlock); |
233 } | 218 } |
234 | 219 |
235 // for (Node n : graph.getNodes()) { | 220 for (Node n : graph.getNodes()) { |
236 // if (n instanceof FrameState) { | 221 if (n instanceof Placeholder) { |
237 // boolean delete = false; | 222 Placeholder p = (Placeholder) n; |
238 // if (n.usages().size() == 0 && n.predecessors().size() == 0) { | 223 |
239 // delete = true; | 224 if (p == graph.start().successors().get(0)) { |
240 // } | 225 // nothing to do... |
226 } else if (p.blockPredecessors().size() == 0) { | |
227 assert p.next() == null; | |
228 p.delete(); | |
229 } else { | |
230 assert p.blockPredecessors().size() == 1; | |
231 for (Node pred : new ArrayList<Node>(p.predecessors())) { | |
232 pred.successors().replace(p, p.next()); | |
233 } | |
234 p.successors().clearAll(); | |
235 p.delete(); | |
236 } | |
237 } | |
238 } | |
239 for (Node n : graph.getNodes()) { | |
240 if (n instanceof FrameState) { | |
241 boolean delete = false; | |
242 if (n.usages().size() == 0 && n.predecessors().size() == 0) { | |
243 delete = true; | |
244 } | |
241 // if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) { | 245 // if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) { |
242 // n.usages().get(0).inputs().replace(n, null); | 246 // n.usages().get(0).inputs().replace(n, null); |
243 // delete = true; | 247 // delete = true; |
244 // } | 248 // } |
245 // if (delete) { | 249 if (delete) { |
246 // n.delete(); | 250 n.delete(); |
247 // System.out.println("deleted framestate"); | 251 } |
248 // } | 252 } |
249 // } | 253 } |
250 // } | |
251 } | 254 } |
252 | 255 |
253 private Block nextBlock(int bci) { | 256 private Block nextBlock(int bci) { |
254 Block block = new Block(); | 257 Block block = new Block(); |
255 block.startBci = bci; | 258 block.startBci = bci; |
285 appendWithBCI(base); | 288 appendWithBCI(base); |
286 } | 289 } |
287 | 290 |
288 public void mergeOrClone(Block target, FrameStateAccess newState) { | 291 public void mergeOrClone(Block target, FrameStateAccess newState) { |
289 Instruction first = target.firstInstruction; | 292 Instruction first = target.firstInstruction; |
293 assert first instanceof StateSplit; | |
294 | |
290 int bci = target.startBci; | 295 int bci = target.startBci; |
291 boolean loopHeader = target.isLoopHeader; | 296 |
292 | 297 FrameState existingState = ((StateSplit) first).stateBefore(); |
293 FrameState existingState; | |
294 if (first instanceof Placeholder) { | |
295 existingState = ((Placeholder) first).stateBefore(); | |
296 } else { | |
297 assert first instanceof BlockBegin; | |
298 existingState = ((BlockBegin) first).stateBefore(); | |
299 } | |
300 | 298 |
301 if (existingState == null) { | 299 if (existingState == null) { |
300 assert first instanceof BlockBegin ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader; | |
301 | |
302 // copy state because it is modified | 302 // copy state because it is modified |
303 FrameState duplicate = newState.duplicate(bci); | 303 FrameState duplicate = newState.duplicate(bci); |
304 | 304 |
305 // if the block is a loop header, insert all necessary phis | 305 // if the block is a loop header, insert all necessary phis |
306 if (loopHeader) { | 306 if (target.isLoopHeader) { |
307 assert first instanceof BlockBegin; | 307 assert first instanceof BlockBegin; |
308 insertLoopPhis((BlockBegin) first, duplicate); | 308 insertLoopPhis((BlockBegin) first, duplicate); |
309 ((BlockBegin) first).setStateBefore(duplicate); | 309 ((BlockBegin) first).setStateBefore(duplicate); |
310 } else { | 310 } else { |
311 if (first instanceof Placeholder) { | 311 ((StateSplit) first).setStateBefore(duplicate); |
312 ((Placeholder) first).setStateBefore(duplicate); | |
313 } else { | |
314 ((BlockBegin) first).setStateBefore(duplicate); | |
315 } | |
316 } | 312 } |
317 } else { | 313 } else { |
318 | |
319 if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { | 314 if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { |
320 // stacks or locks do not match--bytecodes would not verify | 315 // stacks or locks do not match--bytecodes would not verify |
321 throw new CiBailout("stack or locks do not match"); | 316 throw new CiBailout("stack or locks do not match"); |
322 } | 317 } |
323 | |
324 assert existingState.localsSize() == newState.localsSize(); | 318 assert existingState.localsSize() == newState.localsSize(); |
325 assert existingState.stackSize() == newState.stackSize(); | 319 assert existingState.stackSize() == newState.stackSize(); |
326 | 320 |
327 existingState.merge((BlockBegin) first, newState); | 321 if (first instanceof Placeholder) { |
322 BlockBegin merge = new BlockBegin(existingState.bci, target.blockID, target.isLoopHeader, graph); | |
323 for (Node n : new ArrayList<Node>(first.predecessors())) { | |
324 n.successors().replace(first, merge); | |
325 } | |
326 target.firstInstruction = merge; | |
327 merge.setStateBefore(existingState); | |
328 } | |
329 | |
330 existingState.merge((BlockBegin) target.firstInstruction, newState); | |
328 } | 331 } |
329 | 332 |
330 for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { | 333 for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { |
331 if (frameState.valueAt(j) != null) { | 334 if (frameState.valueAt(j) != null) { |
332 assert !frameState.valueAt(j).isDeleted(); | 335 assert !frameState.valueAt(j).isDeleted(); |
409 assert firstHandler.isCatchAll(); | 412 assert firstHandler.isCatchAll(); |
410 dispatchBlock = firstHandler.entryBlock(); | 413 dispatchBlock = firstHandler.entryBlock(); |
411 } | 414 } |
412 FrameState entryState = frameState.duplicateWithEmptyStack(bci); | 415 FrameState entryState = frameState.duplicateWithEmptyStack(bci); |
413 | 416 |
414 BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); | 417 StateSplit entry = new Placeholder(graph); |
415 entry.setStateBefore(entryState); | 418 entry.setStateBefore(entryState); |
416 ExceptionObject exception = new ExceptionObject(graph); | 419 ExceptionObject exception = new ExceptionObject(graph); |
417 entry.appendNext(exception); | 420 entry.appendNext(exception); |
418 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); | 421 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); |
419 | 422 |
1052 return createTarget(blockFromBci[bci], stateAfter); | 1055 return createTarget(blockFromBci[bci], stateAfter); |
1053 } | 1056 } |
1054 | 1057 |
1055 private Instruction createTarget(Block block, FrameStateAccess stateAfter) { | 1058 private Instruction createTarget(Block block, FrameStateAccess stateAfter) { |
1056 assert block != null && stateAfter != null; | 1059 assert block != null && stateAfter != null; |
1060 assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors"; | |
1061 | |
1057 if (block.firstInstruction == null) { | 1062 if (block.firstInstruction == null) { |
1058 // if (block.isLoopHeader) { | 1063 if (block.isLoopHeader) { |
1059 block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); | 1064 block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); |
1060 // } else { | 1065 } else { |
1061 // block.firstInstruction = new Placeholder(graph); | 1066 block.firstInstruction = new Placeholder(graph); |
1062 // } | 1067 } |
1063 } | 1068 } |
1064 mergeOrClone(block, stateAfter); | 1069 mergeOrClone(block, stateAfter); |
1065 addToWorkList(block); | 1070 addToWorkList(block); |
1066 return block.firstInstruction; | 1071 return block.firstInstruction; |
1067 } | 1072 } |
1117 } | 1122 } |
1118 | 1123 |
1119 if (!isVisited(block)) { | 1124 if (!isVisited(block)) { |
1120 markVisited(block); | 1125 markVisited(block); |
1121 // now parse the block | 1126 // now parse the block |
1122 frameState.initializeFrom(((BlockBegin) block.firstInstruction).stateBefore()); | 1127 frameState.initializeFrom(((StateSplit) block.firstInstruction).stateBefore()); |
1123 lastInstr = block.firstInstruction; | 1128 lastInstr = block.firstInstruction; |
1124 assert block.firstInstruction.next() == null; | 1129 assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID; |
1125 | 1130 |
1126 if (block instanceof ExceptionBlock) { | 1131 if (block instanceof ExceptionBlock) { |
1127 createExceptionDispatch((ExceptionBlock) block); | 1132 createExceptionDispatch((ExceptionBlock) block); |
1128 } else { | 1133 } else { |
1129 iterateBytecodesForBlock(block); | 1134 iterateBytecodesForBlock(block); |