comparison graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java @ 3044:0c519981c6cf

LoopBegin is not a merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Thu, 16 Jun 2011 22:36:56 +0200
parents cbece91420af
children f9e045cd2c23
comparison
equal deleted inserted replaced
3043:47aef13c569c 3044:0c519981c6cf
262 assert bci() == 0; 262 assert bci() == 0;
263 appendGoto(createTargetAt(0, frameState)); 263 appendGoto(createTargetAt(0, frameState));
264 } 264 }
265 265
266 public void mergeOrClone(Block target, FrameStateAccess newState) { 266 public void mergeOrClone(Block target, FrameStateAccess newState) {
267 Instruction first = target.firstInstruction; 267 StateSplit first = (StateSplit) target.firstInstruction;
268
268 if (target.isLoopHeader && isVisited(target)) { 269 if (target.isLoopHeader && isVisited(target)) {
269 first = ((LoopBegin) first).loopEnd(); 270 first = ((LoopBegin) target.firstInstruction.next()).loopEnd();
270 } 271 }
271 assert first instanceof StateSplit; 272 FrameState existingState = first.stateBefore();
272
273 int bci = target.startBci;
274
275 FrameState existingState = ((StateSplit) first).stateBefore();
276 273
277 if (existingState == null) { 274 if (existingState == null) {
278 // copy state because it is modified 275 // copy state because it is modified
279 FrameState duplicate = newState.duplicate(bci); 276 FrameState duplicate = newState.duplicate(target.startBci);
280 277
281 // if the block is a loop header, insert all necessary phis 278 // if the block is a loop header, insert all necessary phis
282 if (first instanceof LoopBegin && target.isLoopHeader) { 279 if (target.isLoopHeader && !isVisited(target)) {
283 assert first instanceof Merge; 280 LoopBegin loopBegin = (LoopBegin) target.firstInstruction.next();
284 insertLoopPhis((Merge) first, duplicate); 281 assert target.firstInstruction instanceof Placeholder && loopBegin != null;
285 ((Merge) first).setStateBefore(duplicate); 282 //System.out.println("insertLoopPhis with " + target.loopHeaderState);
286 } else { 283 insertLoopPhis(loopBegin, loopBegin.stateBefore());
287 ((StateSplit) first).setStateBefore(duplicate); 284 }
288 } 285 first.setStateBefore(duplicate);
289 } else { 286 } else {
290 if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { 287 if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
291 // stacks or locks do not match--bytecodes would not verify 288 // stacks or locks do not match--bytecodes would not verify
292 TTY.println(existingState.toString()); 289 TTY.println(existingState.toString());
293 TTY.println(newState.duplicate(0).toString()); 290 TTY.println(newState.duplicate(0).toString());
297 assert existingState.stackSize() == newState.stackSize(); 294 assert existingState.stackSize() == newState.stackSize();
298 295
299 if (first instanceof Placeholder) { 296 if (first instanceof Placeholder) {
300 assert !target.isLoopHeader; 297 assert !target.isLoopHeader;
301 Merge merge = new Merge(graph); 298 Merge merge = new Merge(graph);
302
303
304 299
305 Placeholder p = (Placeholder) first; 300 Placeholder p = (Placeholder) first;
306 assert p.predecessors().size() == 1; 301 assert p.predecessors().size() == 1;
307 assert p.next() == null; 302 assert p.next() == null;
308 303
323 assert !frameState.valueAt(j).isDeleted(); 318 assert !frameState.valueAt(j).isDeleted();
324 } 319 }
325 } 320 }
326 } 321 }
327 322
328 private void insertLoopPhis(Merge merge, FrameState newState) { 323 private void insertLoopPhis(LoopBegin loopBegin, FrameState newState) {
329 int stackSize = newState.stackSize(); 324 int stackSize = newState.stackSize();
330 for (int i = 0; i < stackSize; i++) { 325 for (int i = 0; i < stackSize; i++) {
331 // always insert phis for the stack 326 // always insert phis for the stack
332 Value x = newState.stackAt(i); 327 Value x = newState.stackAt(i);
333 if (x != null) { 328 if (x != null) {
334 newState.setupPhiForStack(merge, i).addInput(x); 329 newState.setupPhiForStack(loopBegin, i).addInput(x);
335 } 330 }
336 } 331 }
337 int localsSize = newState.localsSize(); 332 int localsSize = newState.localsSize();
338 for (int i = 0; i < localsSize; i++) { 333 for (int i = 0; i < localsSize; i++) {
339 Value x = newState.localAt(i); 334 Value x = newState.localAt(i);
340 if (x != null) { 335 if (x != null) {
341 newState.setupPhiForLocal(merge, i).addInput(x); 336 newState.setupPhiForLocal(loopBegin, i).addInput(x);
342 } 337 }
343 } 338 }
344 } 339 }
345 340
346 public BytecodeStream stream() { 341 public BytecodeStream stream() {
1127 if (block.firstInstruction == null) { 1122 if (block.firstInstruction == null) {
1128 if (block.isLoopHeader) { 1123 if (block.isLoopHeader) {
1129 LoopBegin loopBegin = new LoopBegin(graph); 1124 LoopBegin loopBegin = new LoopBegin(graph);
1130 LoopEnd loopEnd = new LoopEnd(graph); 1125 LoopEnd loopEnd = new LoopEnd(graph);
1131 loopEnd.setLoopBegin(loopBegin); 1126 loopEnd.setLoopBegin(loopBegin);
1132 block.firstInstruction = loopBegin; 1127 Placeholder p = new Placeholder(graph);
1128 p.setNext(loopBegin);
1129 loopBegin.setStateBefore(stateAfter.duplicate(block.startBci));
1130 block.firstInstruction = p;
1133 } else { 1131 } else {
1134 block.firstInstruction = new Placeholder(graph); 1132 block.firstInstruction = new Placeholder(graph);
1135 } 1133 }
1136 } 1134 }
1137 mergeOrClone(block, stateAfter); 1135 mergeOrClone(block, stateAfter);
1138 addToWorkList(block); 1136 addToWorkList(block);
1139 1137
1140 FixedNode result = null; 1138 FixedNode result = null;
1141 if (block.firstInstruction instanceof LoopBegin && isVisited(block)) { 1139 if (block.isLoopHeader && isVisited(block)) {
1142 result = ((LoopBegin) block.firstInstruction).loopEnd(); 1140 result = ((LoopBegin) block.firstInstruction.next()).loopEnd();
1143 } else { 1141 } else {
1144 result = block.firstInstruction; 1142 result = block.firstInstruction;
1145 } 1143 }
1146 1144
1147 assert result instanceof Merge || result instanceof Placeholder : result; 1145 assert result instanceof Merge || result instanceof Placeholder : result;
1175 } 1173 }
1176 1174
1177 if (!isVisited(block)) { 1175 if (!isVisited(block)) {
1178 markVisited(block); 1176 markVisited(block);
1179 // now parse the block 1177 // now parse the block
1180 frameState.initializeFrom(((StateSplit) block.firstInstruction).stateBefore()); 1178 if (block.isLoopHeader) {
1181 lastInstr = block.firstInstruction; 1179 lastInstr = (LoopBegin) block.firstInstruction.next();
1182 assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID; 1180 } else {
1181 lastInstr = block.firstInstruction;
1182 }
1183 frameState.initializeFrom(((StateSplit) lastInstr).stateBefore());
1184 assert lastInstr.next() == null : "instructions already appended at block " + block.blockID;
1183 1185
1184 if (block == returnBlock) { 1186 if (block == returnBlock) {
1185 createReturnBlock(block); 1187 createReturnBlock(block);
1186 } else if (block == unwindBlock) { 1188 } else if (block == unwindBlock) {
1187 createUnwindBlock(block); 1189 createUnwindBlock(block);
1194 } 1196 }
1195 } 1197 }
1196 } 1198 }
1197 for (Block b : blocksVisited) { 1199 for (Block b : blocksVisited) {
1198 if (b.isLoopHeader) { 1200 if (b.isLoopHeader) {
1199 LoopBegin begin = (LoopBegin) b.firstInstruction; 1201 Instruction loopHeaderInstr = b.firstInstruction;
1202 LoopBegin begin = (LoopBegin) loopHeaderInstr.next();
1200 LoopEnd end = begin.loopEnd(); 1203 LoopEnd end = begin.loopEnd();
1201 1204
1202 // This can happen with degenerated loops like this one: 1205 // This can happen with degenerated loops like this one:
1203 // for (;;) { 1206 // for (;;) {
1204 // try { 1207 // try {
1205 // break; 1208 // break;
1206 // } catch (UnresolvedException iioe) { 1209 // } catch (UnresolvedException iioe) {
1207 // } 1210 // }
1208 // } 1211 // }
1209 if (end.stateBefore() != null) { 1212 if (end.stateBefore() != null) {
1213 //loopHeaderMerge.stateBefore().merge(begin, end.stateBefore());
1214 //assert loopHeaderMerge.equals(end.stateBefore());
1210 begin.stateBefore().merge(begin, end.stateBefore()); 1215 begin.stateBefore().merge(begin, end.stateBefore());
1211 } else { 1216 } else {
1212 end.delete(); 1217 end.delete();
1213 Merge merge = new Merge(graph); 1218 Merge merge = new Merge(graph);
1214 merge.setNext(begin.next()); 1219 merge.setNext(begin.next());