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;