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);