Mercurial > hg > graal-compiler
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2622:91d3952f7eb7
Framestate work : using stateAFter and reducting the number of nodes with framestates. Intermediate state (does not pass tests)
author | Gilles Duboscq <gilles.duboscq@oracle.com> |
---|---|
date | Tue, 10 May 2011 12:37:46 +0200 |
parents | dd115f80acf8 |
children | 569228710be8 |
comparison
equal
deleted
inserted
replaced
2621:dd115f80acf8 | 2622:91d3952f7eb7 |
---|---|
116 private BlockBegin curBlock; // the current block | 116 private BlockBegin curBlock; // the current block |
117 private FrameStateBuilder frameState; // the current execution state | 117 private FrameStateBuilder frameState; // the current execution state |
118 private Instruction lastInstr; // the last instruction added | 118 private Instruction lastInstr; // the last instruction added |
119 private final LogStream log; | 119 private final LogStream log; |
120 | 120 |
121 private boolean skipBlock; // skip processing of the rest of this block | |
122 private Value rootMethodSynchronizedObject; | 121 private Value rootMethodSynchronizedObject; |
123 | 122 |
124 private final Graph graph; | 123 private final Graph graph; |
125 | 124 |
126 /** | 125 /** |
260 if (!hasHandler()) { | 259 if (!hasHandler()) { |
261 return Util.uncheckedCast(Collections.EMPTY_LIST); | 260 return Util.uncheckedCast(Collections.EMPTY_LIST); |
262 } | 261 } |
263 | 262 |
264 ArrayList<ExceptionHandler> exceptionHandlers = new ArrayList<ExceptionHandler>(); | 263 ArrayList<ExceptionHandler> exceptionHandlers = new ArrayList<ExceptionHandler>(); |
265 FrameState stateBefore = x.stateBefore(); | 264 |
266 | 265 FrameState state = frameState.create(bci); |
267 assert stateBefore != null : "exception handler state must be available for " + x; | |
268 FrameState state = stateBefore; | |
269 assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; | 266 assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; |
270 | 267 |
271 // join with all potential exception handlers | 268 // join with all potential exception handlers |
272 if (this.exceptionHandlers != null) { | 269 if (this.exceptionHandlers != null) { |
273 for (ExceptionHandler handler : this.exceptionHandlers) { | 270 for (ExceptionHandler handler : this.exceptionHandlers) { |
467 } | 464 } |
468 | 465 |
469 } | 466 } |
470 | 467 |
471 void genArithmeticOp(CiKind kind, int opcode) { | 468 void genArithmeticOp(CiKind kind, int opcode) { |
472 genArithmeticOp(kind, opcode, null); | 469 genArithmeticOp(kind, opcode, false); |
473 } | 470 } |
474 | 471 |
475 void genArithmeticOp(CiKind kind, int opcode, FrameState state) { | 472 void genArithmeticOp(CiKind kind, int opcode, boolean canTrap) { |
476 genArithmeticOp(kind, opcode, kind, kind, state); | 473 genArithmeticOp(kind, opcode, kind, kind, canTrap); |
477 } | 474 } |
478 | 475 |
479 void genArithmeticOp(CiKind result, int opcode, CiKind x, CiKind y, FrameState state) { | 476 void genArithmeticOp(CiKind result, int opcode, CiKind x, CiKind y, boolean canTrap) { |
480 Value yValue = frameState.pop(y); | 477 Value yValue = frameState.pop(y); |
481 Value xValue = frameState.pop(x); | 478 Value xValue = frameState.pop(x); |
482 Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), state, graph)); | 479 Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), canTrap, graph)); |
483 frameState.push(result, result1); | 480 frameState.push(result, result1); |
484 } | 481 } |
485 | 482 |
486 void genNegateOp(CiKind kind) { | 483 void genNegateOp(CiKind kind) { |
487 frameState.push(kind, append(new NegateOp(frameState.pop(kind), graph))); | 484 frameState.push(kind, append(new NegateOp(frameState.pop(kind), graph))); |
517 void genIncrement() { | 514 void genIncrement() { |
518 int index = stream().readLocalIndex(); | 515 int index = stream().readLocalIndex(); |
519 int delta = stream().readIncrement(); | 516 int delta = stream().readIncrement(); |
520 Value x = frameState.localAt(index); | 517 Value x = frameState.localAt(index); |
521 Value y = append(Constant.forInt(delta, graph)); | 518 Value y = append(Constant.forInt(delta, graph)); |
522 frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null, graph))); | 519 frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), false, graph))); |
523 } | 520 } |
524 | 521 |
525 void genGoto(int fromBCI, int toBCI) { | 522 void genGoto(int fromBCI, int toBCI) { |
526 boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI; | 523 boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI; |
527 append(new Goto(blockAt(toBCI), null, isSafepoint, graph)); | 524 append(new Goto(blockAt(toBCI), null, isSafepoint, graph)); |
529 | 526 |
530 void ifNode(Value x, Condition cond, Value y, FrameState stateBefore) { | 527 void ifNode(Value x, Condition cond, Value y, FrameState stateBefore) { |
531 BlockBegin tsucc = blockAt(stream().readBranchDest()); | 528 BlockBegin tsucc = blockAt(stream().readBranchDest()); |
532 BlockBegin fsucc = blockAt(stream().nextBCI()); | 529 BlockBegin fsucc = blockAt(stream().nextBCI()); |
533 int bci = stream().currentBCI(); | 530 int bci = stream().currentBCI(); |
534 boolean isSafepoint = !noSafepoints() && tsucc.bci() <= bci || fsucc.bci() <= bci; | 531 boolean isSafepoint = !noSafepoints() && (tsucc.bci() <= bci || fsucc.bci() <= bci); |
535 append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint, graph)); | 532 append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint, graph)); |
536 } | 533 } |
537 | 534 |
538 void genIfZero(Condition cond) { | 535 void genIfZero(Condition cond) { |
539 Value y = appendConstant(CiConstant.INT_0); | 536 Value y = appendConstant(CiConstant.INT_0); |
555 Value x = frameState.pop(kind); | 552 Value x = frameState.pop(kind); |
556 ifNode(x, cond, y, stateBefore); | 553 ifNode(x, cond, y, stateBefore); |
557 } | 554 } |
558 | 555 |
559 void genThrow(int bci) { | 556 void genThrow(int bci) { |
560 FrameState stateBefore = frameState.create(bci()); | 557 Throw t = new Throw(frameState.apop(), !noSafepoints(), graph); |
561 Throw t = new Throw(frameState.apop(), stateBefore, !noSafepoints(), graph); | |
562 appendWithoutOptimization(t, bci); | 558 appendWithoutOptimization(t, bci); |
563 } | 559 } |
564 | 560 |
565 void genCheckCast() { | 561 void genCheckCast() { |
566 int cpi = stream().readCPI(); | 562 int cpi = stream().readCPI(); |
567 RiType type = constantPool().lookupType(cpi, CHECKCAST); | 563 RiType type = constantPool().lookupType(cpi, CHECKCAST); |
568 boolean isInitialized = !C1XOptions.TestPatching && type.isResolved() && type.isInitialized(); | 564 boolean isInitialized = !C1XOptions.TestPatching && type.isResolved() && type.isInitialized(); |
569 Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); | 565 Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); |
570 CheckCast c = new CheckCast(type, typeInstruction, frameState.apop(), null, graph); | 566 CheckCast c = new CheckCast(type, typeInstruction, frameState.apop(), graph); |
571 frameState.apush(append(c)); | 567 frameState.apush(append(c)); |
572 checkForDirectCompare(c); | 568 checkForDirectCompare(c); |
573 } | 569 } |
574 | 570 |
575 void genInstanceOf() { | 571 void genInstanceOf() { |
576 int cpi = stream().readCPI(); | 572 int cpi = stream().readCPI(); |
577 RiType type = constantPool().lookupType(cpi, INSTANCEOF); | 573 RiType type = constantPool().lookupType(cpi, INSTANCEOF); |
578 boolean isInitialized = !C1XOptions.TestPatching && type.isResolved() && type.isInitialized(); | 574 boolean isInitialized = !C1XOptions.TestPatching && type.isResolved() && type.isInitialized(); |
579 Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); | 575 Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); |
580 InstanceOf i = new InstanceOf(type, typeInstruction, frameState.apop(), null, graph); | 576 InstanceOf i = new InstanceOf(type, typeInstruction, frameState.apop(), graph); |
581 frameState.ipush(append(i)); | 577 frameState.ipush(append(i)); |
582 checkForDirectCompare(i); | 578 checkForDirectCompare(i); |
583 } | 579 } |
584 | 580 |
585 private void checkForDirectCompare(TypeCheck check) { | 581 private void checkForDirectCompare(TypeCheck check) { |
588 return; | 584 return; |
589 } | 585 } |
590 } | 586 } |
591 | 587 |
592 void genNewInstance(int cpi) { | 588 void genNewInstance(int cpi) { |
593 FrameState stateBefore = frameState.create(bci()); | |
594 RiType type = constantPool().lookupType(cpi, NEW); | 589 RiType type = constantPool().lookupType(cpi, NEW); |
595 NewInstance n = new NewInstance(type, cpi, constantPool(), stateBefore, graph); | 590 NewInstance n = new NewInstance(type, cpi, constantPool(), graph); |
596 if (memoryMap != null) { | 591 if (memoryMap != null) { |
597 memoryMap.newInstance(n); | 592 memoryMap.newInstance(n); |
598 } | 593 } |
599 frameState.apush(append(n)); | 594 frameState.apush(append(n)); |
600 } | 595 } |
601 | 596 |
602 void genNewTypeArray(int typeCode) { | 597 void genNewTypeArray(int typeCode) { |
603 FrameState stateBefore = frameState.create(bci()); | |
604 CiKind kind = CiKind.fromArrayTypeCode(typeCode); | 598 CiKind kind = CiKind.fromArrayTypeCode(typeCode); |
605 RiType elementType = compilation.runtime.asRiType(kind); | 599 RiType elementType = compilation.runtime.asRiType(kind); |
606 frameState.apush(append(new NewTypeArray(frameState.ipop(), elementType, stateBefore, graph))); | 600 frameState.apush(append(new NewTypeArray(frameState.ipop(), elementType, graph))); |
607 } | 601 } |
608 | 602 |
609 void genNewObjectArray(int cpi) { | 603 void genNewObjectArray(int cpi) { |
610 RiType type = constantPool().lookupType(cpi, ANEWARRAY); | 604 RiType type = constantPool().lookupType(cpi, ANEWARRAY); |
611 FrameState stateBefore = frameState.create(bci()); | 605 NewArray n = new NewObjectArray(type, frameState.ipop(), graph); |
612 NewArray n = new NewObjectArray(type, frameState.ipop(), stateBefore, graph); | |
613 frameState.apush(append(n)); | 606 frameState.apush(append(n)); |
614 } | 607 } |
615 | 608 |
616 void genNewMultiArray(int cpi) { | 609 void genNewMultiArray(int cpi) { |
617 RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY); | 610 RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY); |
618 FrameState stateBefore = frameState.create(bci()); | |
619 int rank = stream().readUByte(bci() + 3); | 611 int rank = stream().readUByte(bci() + 3); |
620 Value[] dims = new Value[rank]; | 612 Value[] dims = new Value[rank]; |
621 for (int i = rank - 1; i >= 0; i--) { | 613 for (int i = rank - 1; i >= 0; i--) { |
622 dims[i] = frameState.ipop(); | 614 dims[i] = frameState.ipop(); |
623 } | 615 } |
624 NewArray n = new NewMultiArray(type, dims, stateBefore, cpi, constantPool(), graph); | 616 NewArray n = new NewMultiArray(type, dims, cpi, constantPool(), graph); |
625 frameState.apush(append(n)); | 617 frameState.apush(append(n)); |
626 } | 618 } |
627 | 619 |
628 void genGetField(int cpi, RiField field) { | 620 void genGetField(int cpi, RiField field) { |
629 // Must copy the state here, because the field holder must still be on the stack. | 621 // Must copy the state here, because the field holder must still be on the stack. |
1096 } | 1088 } |
1097 } | 1089 } |
1098 | 1090 |
1099 assert x.next() == null : "instruction should not have been appended yet"; | 1091 assert x.next() == null : "instruction should not have been appended yet"; |
1100 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; | 1092 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; |
1093 | |
1094 if (lastInstr instanceof StateSplit) { | |
1095 StateSplit stateSplit = (StateSplit) lastInstr; | |
1096 if (stateSplit.stateAfter() == null) { | |
1097 stateSplit.setStateAfter(frameState.create(bci)); | |
1098 } | |
1099 } | |
1100 | |
1101 if (lastInstr instanceof Base) { | 1101 if (lastInstr instanceof Base) { |
1102 assert false : "may only happen when inlining intrinsics"; | 1102 assert false : "may only happen when inlining intrinsics"; |
1103 } else { | 1103 } else { |
1104 lastInstr = lastInstr.appendNext(x, bci); | 1104 lastInstr = lastInstr.appendNext(x, bci); |
1105 } | 1105 } |
1109 } | 1109 } |
1110 | 1110 |
1111 if (memoryMap != null && hasUncontrollableSideEffects(x)) { | 1111 if (memoryMap != null && hasUncontrollableSideEffects(x)) { |
1112 // conservatively kill all memory if there are unknown side effects | 1112 // conservatively kill all memory if there are unknown side effects |
1113 memoryMap.kill(); | 1113 memoryMap.kill(); |
1114 } | |
1115 | |
1116 if (x instanceof StateSplit) { | |
1117 StateSplit stateSplit = (StateSplit) x; | |
1118 if (stateSplit.stateBefore() == null) { | |
1119 stateSplit.setStateBefore(frameState.create(bci)); | |
1120 } | |
1121 } | 1114 } |
1122 | 1115 |
1123 if (x.canTrap()) { | 1116 if (x.canTrap()) { |
1124 // connect the instruction to any exception handlers | 1117 // connect the instruction to any exception handlers |
1125 x.setExceptionHandlers(handleException(x, bci)); | 1118 x.setExceptionHandlers(handleException(x, bci)); |
1162 lastInstr = lastInstr.next(); | 1155 lastInstr = lastInstr.next(); |
1163 } | 1156 } |
1164 frameState.initializeFrom(syncHandler.stateBefore()); | 1157 frameState.initializeFrom(syncHandler.stateBefore()); |
1165 | 1158 |
1166 int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI; | 1159 int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI; |
1167 Value exception = appendWithoutOptimization(new ExceptionObject(frameState.create(bci), graph), bci); | 1160 Value exception = appendWithoutOptimization(new ExceptionObject(graph), bci); |
1168 | 1161 |
1169 assert lock != null; | 1162 assert lock != null; |
1170 assert frameState.locksSize() > 0 && frameState.lockAt(locksSize() - 1) == lock; | 1163 assert frameState.locksSize() > 0 && frameState.lockAt(locksSize() - 1) == lock; |
1171 if (lock instanceof Instruction) { | 1164 if (lock instanceof Instruction) { |
1172 Instruction l = (Instruction) lock; | 1165 Instruction l = (Instruction) lock; |
1205 } | 1198 } |
1206 } | 1199 } |
1207 } | 1200 } |
1208 | 1201 |
1209 private BlockEnd iterateBytecodesForBlock(int bci, boolean inliningIntoCurrentBlock) { | 1202 private BlockEnd iterateBytecodesForBlock(int bci, boolean inliningIntoCurrentBlock) { |
1210 skipBlock = false; | |
1211 assert frameState != null; | 1203 assert frameState != null; |
1212 stream.setBCI(bci); | 1204 stream.setBCI(bci); |
1213 | 1205 |
1214 BlockBegin block = curBlock; | 1206 BlockBegin block = curBlock; |
1215 BlockEnd end = null; | 1207 BlockEnd end = null; |
1237 // read the opcode | 1229 // read the opcode |
1238 int opcode = stream.currentBC(); | 1230 int opcode = stream.currentBC(); |
1239 | 1231 |
1240 // push an exception object onto the stack if we are parsing an exception handler | 1232 // push an exception object onto the stack if we are parsing an exception handler |
1241 if (pushException) { | 1233 if (pushException) { |
1242 FrameState stateBefore = frameState.create(bci()); | 1234 frameState.apush(append(new ExceptionObject(graph))); |
1243 frameState.apush(append(new ExceptionObject(stateBefore, graph))); | |
1244 pushException = false; | 1235 pushException = false; |
1245 } | 1236 } |
1246 | 1237 |
1247 traceState(); | 1238 traceState(); |
1248 traceInstruction(bci, stream, opcode, blockStart); | 1239 traceInstruction(bci, stream, opcode, blockStart); |
1257 stream.next(); | 1248 stream.next(); |
1258 bci = stream.currentBCI(); | 1249 bci = stream.currentBCI(); |
1259 blockStart = false; | 1250 blockStart = false; |
1260 } | 1251 } |
1261 | 1252 |
1262 // stop processing of this block | |
1263 if (skipBlock) { | |
1264 skipBlock = false; | |
1265 return (BlockEnd) lastInstr; | |
1266 } | |
1267 | |
1268 // if the method terminates, we don't need the stack anymore | 1253 // if the method terminates, we don't need the stack anymore |
1269 if (end instanceof Return || end instanceof Throw) { | 1254 if (end instanceof Return || end instanceof Throw) { |
1270 frameState.clearStack(); | 1255 frameState.clearStack(); |
1271 } | 1256 } |
1272 | 1257 |
1273 // connect to begin and set state | 1258 // connect to begin and set state |
1274 // NOTE that inlining may have changed the block we are parsing | 1259 // NOTE that inlining may have changed the block we are parsing |
1275 assert end != null : "end should exist after iterating over bytecodes"; | 1260 assert end != null : "end should exist after iterating over bytecodes"; |
1276 end.setStateAfter(frameState.create(bci())); | 1261 FrameState stateAtEnd = frameState.create(bci()); |
1262 end.setStateAfter(stateAtEnd); | |
1277 curBlock.setEnd(end); | 1263 curBlock.setEnd(end); |
1278 // propagate the state | 1264 // propagate the state |
1279 for (BlockBegin succ : end.blockSuccessors()) { | 1265 for (BlockBegin succ : end.blockSuccessors()) { |
1280 assert succ.blockPredecessors().contains(curBlock); | 1266 assert succ.blockPredecessors().contains(curBlock); |
1281 succ.mergeOrClone(end.stateAfter(), method()); | 1267 succ.mergeOrClone(stateAtEnd, method()); |
1282 addToWorkList(succ); | 1268 addToWorkList(succ); |
1283 } | 1269 } |
1284 return end; | 1270 return end; |
1285 } | 1271 } |
1286 | 1272 |
1405 case SWAP : stackOp(opcode); break; | 1391 case SWAP : stackOp(opcode); break; |
1406 case IADD : // fall through | 1392 case IADD : // fall through |
1407 case ISUB : // fall through | 1393 case ISUB : // fall through |
1408 case IMUL : genArithmeticOp(CiKind.Int, opcode); break; | 1394 case IMUL : genArithmeticOp(CiKind.Int, opcode); break; |
1409 case IDIV : // fall through | 1395 case IDIV : // fall through |
1410 case IREM : genArithmeticOp(CiKind.Int, opcode, frameState.create(bci())); break; | 1396 case IREM : genArithmeticOp(CiKind.Int, opcode, true); break; |
1411 case LADD : // fall through | 1397 case LADD : // fall through |
1412 case LSUB : // fall through | 1398 case LSUB : // fall through |
1413 case LMUL : genArithmeticOp(CiKind.Long, opcode); break; | 1399 case LMUL : genArithmeticOp(CiKind.Long, opcode); break; |
1414 case LDIV : // fall through | 1400 case LDIV : // fall through |
1415 case LREM : genArithmeticOp(CiKind.Long, opcode, frameState.create(bci())); break; | 1401 case LREM : genArithmeticOp(CiKind.Long, opcode, true); break; |
1416 case FADD : // fall through | 1402 case FADD : // fall through |
1417 case FSUB : // fall through | 1403 case FSUB : // fall through |
1418 case FMUL : // fall through | 1404 case FMUL : // fall through |
1419 case FDIV : // fall through | 1405 case FDIV : // fall through |
1420 case FREM : genArithmeticOp(CiKind.Float, opcode); break; | 1406 case FREM : genArithmeticOp(CiKind.Float, opcode); break; |