Mercurial > hg > graal-jvmci-8
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2602:0c6564c254af
new node layout: BlockBegin, BlockEnd
-Dc1x.dot=regex for pdf output
escape dot graph labels (<, >, &)
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Fri, 06 May 2011 10:25:37 +0200 |
parents | f1bc67c2d453 |
children | 01c5c0443158 |
comparison
equal
deleted
inserted
replaced
2601:224e8b4007bd | 2602:0c6564c254af |
---|---|
122 final LogStream log; | 122 final LogStream log; |
123 | 123 |
124 boolean skipBlock; // skip processing of the rest of this block | 124 boolean skipBlock; // skip processing of the rest of this block |
125 private Value rootMethodSynchronizedObject; | 125 private Value rootMethodSynchronizedObject; |
126 | 126 |
127 | 127 private final Graph graph; |
128 | |
129 private Graph graph = new Graph(); | |
130 | |
131 | 128 |
132 /** | 129 /** |
133 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. | 130 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. |
134 * | 131 * |
135 * @param compilation the compilation | 132 * @param compilation the compilation |
136 * @param ir the IR to build the graph into | 133 * @param ir the IR to build the graph into |
137 */ | 134 * @param graph |
138 public GraphBuilder(C1XCompilation compilation, IR ir) { | 135 */ |
136 public GraphBuilder(C1XCompilation compilation, IR ir, Graph graph) { | |
139 this.compilation = compilation; | 137 this.compilation = compilation; |
140 this.ir = ir; | 138 this.ir = ir; |
141 this.stats = compilation.stats; | 139 this.stats = compilation.stats; |
142 this.memoryMap = C1XOptions.OptLocalLoadElimination ? new MemoryMap() : null; | 140 this.memoryMap = C1XOptions.OptLocalLoadElimination ? new MemoryMap() : null; |
143 this.localValueMap = C1XOptions.OptLocalValueNumbering ? new ValueMap() : null; | 141 this.localValueMap = C1XOptions.OptLocalValueNumbering ? new ValueMap() : null; |
144 log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; | 142 log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; |
145 stream = new BytecodeStream(compilation.method.code()); | 143 stream = new BytecodeStream(compilation.method.code()); |
146 constantPool = compilation.runtime.getConstantPool(compilation.method); | 144 constantPool = compilation.runtime.getConstantPool(compilation.method); |
145 this.graph = graph; | |
147 } | 146 } |
148 | 147 |
149 /** | 148 /** |
150 * Builds the graph for a the specified {@code IRScope}. | 149 * Builds the graph for a the specified {@code IRScope}. |
151 * @param scope the top IRScope | 150 * @param scope the top IRScope |
161 if (rootMethod.noSafepoints()) { | 160 if (rootMethod.noSafepoints()) { |
162 flags |= Flag.NoSafepoints.mask; | 161 flags |= Flag.NoSafepoints.mask; |
163 } | 162 } |
164 | 163 |
165 // 1. create the start block | 164 // 1. create the start block |
166 ir.startBlock = new BlockBegin(0, ir.nextBlockNumber()); | 165 ir.startBlock = new BlockBegin(0, ir.nextBlockNumber(), graph); |
167 BlockBegin startBlock = ir.startBlock; | 166 BlockBegin startBlock = ir.startBlock; |
168 | 167 |
169 // 2. compute the block map, setup exception handlers and get the entrypoint(s) | 168 // 2. compute the block map, setup exception handlers and get the entrypoint(s) |
170 blockMap = compilation.getBlockMap(rootMethod); | 169 blockMap = compilation.getBlockMap(rootMethod); |
171 BlockBegin stdEntry = blockMap.get(0); | 170 BlockBegin stdEntry = blockMap.get(0); |
198 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); | 197 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); |
199 // 4A.2 finish the start block | 198 // 4A.2 finish the start block |
200 finishStartBlock(startBlock, stdEntry); | 199 finishStartBlock(startBlock, stdEntry); |
201 | 200 |
202 // 4A.3 setup an exception handler to unlock the root method synchronized object | 201 // 4A.3 setup an exception handler to unlock the root method synchronized object |
203 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, ir.nextBlockNumber()); | 202 syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, ir.nextBlockNumber(), graph); |
204 syncHandler.setExceptionEntry(); | 203 syncHandler.setExceptionEntry(); |
205 syncHandler.setBlockFlag(BlockBegin.BlockFlag.IsOnWorkList); | 204 syncHandler.setBlockFlag(BlockBegin.BlockFlag.IsOnWorkList); |
206 syncHandler.setBlockFlag(BlockBegin.BlockFlag.DefaultExceptionHandler); | 205 syncHandler.setBlockFlag(BlockBegin.BlockFlag.DefaultExceptionHandler); |
207 | 206 |
208 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); | 207 ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); |
225 } | 224 } |
226 } | 225 } |
227 | 226 |
228 private void finishStartBlock(BlockBegin startBlock, BlockBegin stdEntry) { | 227 private void finishStartBlock(BlockBegin startBlock, BlockBegin stdEntry) { |
229 assert curBlock == startBlock; | 228 assert curBlock == startBlock; |
230 Base base = new Base(stdEntry); | 229 Base base = new Base(stdEntry, graph); |
231 appendWithoutOptimization(base, 0); | 230 appendWithoutOptimization(base, 0); |
232 FrameState stateAfter = curState.immutableCopy(bci()); | 231 FrameState stateAfter = curState.immutableCopy(bci()); |
233 base.setStateAfter(stateAfter); | 232 base.setStateAfter(stateAfter); |
234 startBlock.setEnd(base); | 233 startBlock.setEnd(base); |
235 assert stdEntry.stateBefore() == null; | 234 assert stdEntry.stateBefore() == null; |
598 curState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null, graph))); | 597 curState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null, graph))); |
599 } | 598 } |
600 | 599 |
601 void genGoto(int fromBCI, int toBCI) { | 600 void genGoto(int fromBCI, int toBCI) { |
602 boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI; | 601 boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI; |
603 append(new Goto(blockAt(toBCI), null, isSafepoint)); | 602 append(new Goto(blockAt(toBCI), null, isSafepoint, graph)); |
604 } | 603 } |
605 | 604 |
606 void ifNode(Value x, Condition cond, Value y, FrameState stateBefore) { | 605 void ifNode(Value x, Condition cond, Value y, FrameState stateBefore) { |
607 BlockBegin tsucc = blockAt(stream().readBranchDest()); | 606 BlockBegin tsucc = blockAt(stream().readBranchDest()); |
608 BlockBegin fsucc = blockAt(stream().nextBCI()); | 607 BlockBegin fsucc = blockAt(stream().nextBCI()); |
609 int bci = stream().currentBCI(); | 608 int bci = stream().currentBCI(); |
610 boolean isSafepoint = !noSafepoints() && tsucc.bci() <= bci || fsucc.bci() <= bci; | 609 boolean isSafepoint = !noSafepoints() && tsucc.bci() <= bci || fsucc.bci() <= bci; |
611 append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint)); | 610 append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint, graph)); |
612 } | 611 } |
613 | 612 |
614 void genIfZero(Condition cond) { | 613 void genIfZero(Condition cond) { |
615 Value y = appendConstant(CiConstant.INT_0); | 614 Value y = appendConstant(CiConstant.INT_0); |
616 FrameState stateBefore = curState.immutableCopy(bci()); | 615 FrameState stateBefore = curState.immutableCopy(bci()); |
632 ifNode(x, cond, y, stateBefore); | 631 ifNode(x, cond, y, stateBefore); |
633 } | 632 } |
634 | 633 |
635 void genThrow(int bci) { | 634 void genThrow(int bci) { |
636 FrameState stateBefore = curState.immutableCopy(bci()); | 635 FrameState stateBefore = curState.immutableCopy(bci()); |
637 Throw t = new Throw(apop(), stateBefore, !noSafepoints()); | 636 Throw t = new Throw(apop(), stateBefore, !noSafepoints(), graph); |
638 appendWithoutOptimization(t, bci); | 637 appendWithoutOptimization(t, bci); |
639 } | 638 } |
640 | 639 |
641 void genCheckCast() { | 640 void genCheckCast() { |
642 int cpi = stream().readCPI(); | 641 int cpi = stream().readCPI(); |
1016 FrameState stateBefore = curState.immutableCopy(bci()); | 1015 FrameState stateBefore = curState.immutableCopy(bci()); |
1017 // unlock before exiting the method | 1016 // unlock before exiting the method |
1018 int lockNumber = curState.locksSize() - 1; | 1017 int lockNumber = curState.locksSize() - 1; |
1019 MonitorAddress lockAddress = null; | 1018 MonitorAddress lockAddress = null; |
1020 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { | 1019 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { |
1021 lockAddress = new MonitorAddress(lockNumber); | 1020 lockAddress = new MonitorAddress(lockNumber, graph); |
1022 append(lockAddress); | 1021 append(lockAddress); |
1023 } | 1022 } |
1024 append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, stateBefore, graph)); | 1023 append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, stateBefore, graph)); |
1025 curState.unlock(); | 1024 curState.unlock(); |
1026 } | 1025 } |
1027 append(new Return(x, !noSafepoints())); | 1026 append(new Return(x, !noSafepoints(), graph)); |
1028 } | 1027 } |
1029 | 1028 |
1030 /** | 1029 /** |
1031 * Gets the number of locks held. | 1030 * Gets the number of locks held. |
1032 */ | 1031 */ |
1036 | 1035 |
1037 void genMonitorEnter(Value x, int bci) { | 1036 void genMonitorEnter(Value x, int bci) { |
1038 int lockNumber = locksSize(); | 1037 int lockNumber = locksSize(); |
1039 MonitorAddress lockAddress = null; | 1038 MonitorAddress lockAddress = null; |
1040 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { | 1039 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { |
1041 lockAddress = new MonitorAddress(lockNumber); | 1040 lockAddress = new MonitorAddress(lockNumber, graph); |
1042 append(lockAddress); | 1041 append(lockAddress); |
1043 } | 1042 } |
1044 MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph); | 1043 MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph); |
1045 appendWithoutOptimization(monitorEnter, bci); | 1044 appendWithoutOptimization(monitorEnter, bci); |
1046 curState.lock(ir, x, lockNumber + 1); | 1045 curState.lock(ir, x, lockNumber + 1); |
1053 if (lockNumber < 0) { | 1052 if (lockNumber < 0) { |
1054 throw new CiBailout("monitor stack underflow"); | 1053 throw new CiBailout("monitor stack underflow"); |
1055 } | 1054 } |
1056 MonitorAddress lockAddress = null; | 1055 MonitorAddress lockAddress = null; |
1057 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { | 1056 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { |
1058 lockAddress = new MonitorAddress(lockNumber); | 1057 lockAddress = new MonitorAddress(lockNumber, graph); |
1059 append(lockAddress); | 1058 append(lockAddress); |
1060 } | 1059 } |
1061 appendWithoutOptimization(new MonitorExit(x, lockAddress, lockNumber, null, graph), bci); | 1060 appendWithoutOptimization(new MonitorExit(x, lockAddress, lockNumber, null, graph), bci); |
1062 curState.unlock(); | 1061 curState.unlock(); |
1063 killMemoryMap(); // prevent any optimizations across synchronization | 1062 killMemoryMap(); // prevent any optimizations across synchronization |
1086 int offset = ts.defaultOffset(); | 1085 int offset = ts.defaultOffset(); |
1087 isBackwards |= offset < 0; // if the default successor is backwards | 1086 isBackwards |= offset < 0; // if the default successor is backwards |
1088 list.add(blockAt(bci + offset)); | 1087 list.add(blockAt(bci + offset)); |
1089 boolean isSafepoint = isBackwards && !noSafepoints(); | 1088 boolean isSafepoint = isBackwards && !noSafepoints(); |
1090 FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null; | 1089 FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null; |
1091 append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint)); | 1090 append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint, graph)); |
1092 } | 1091 } |
1093 | 1092 |
1094 void genLookupswitch() { | 1093 void genLookupswitch() { |
1095 int bci = bci(); | 1094 int bci = bci(); |
1096 BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci); | 1095 BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci); |
1108 int offset = ls.defaultOffset(); | 1107 int offset = ls.defaultOffset(); |
1109 isBackwards |= offset < 0; // if the default successor is backwards | 1108 isBackwards |= offset < 0; // if the default successor is backwards |
1110 list.add(blockAt(bci + offset)); | 1109 list.add(blockAt(bci + offset)); |
1111 boolean isSafepoint = isBackwards && !noSafepoints(); | 1110 boolean isSafepoint = isBackwards && !noSafepoints(); |
1112 FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null; | 1111 FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null; |
1113 append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint)); | 1112 append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint, graph)); |
1114 } | 1113 } |
1115 | 1114 |
1116 /** | 1115 /** |
1117 * Determines whether the length of an array should be extracted out as a separate instruction | 1116 * Determines whether the length of an array should be extracted out as a separate instruction |
1118 * before an array indexing instruction. This exposes it to CSE. | 1117 * before an array indexing instruction. This exposes it to CSE. |
1260 lastInstr = lastInstr.next(); | 1259 lastInstr = lastInstr.next(); |
1261 } | 1260 } |
1262 curState = syncHandler.stateBefore().copy(); | 1261 curState = syncHandler.stateBefore().copy(); |
1263 | 1262 |
1264 int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI; | 1263 int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI; |
1265 Value exception = appendWithoutOptimization(new ExceptionObject(curState.immutableCopy(bci)), bci); | 1264 Value exception = appendWithoutOptimization(new ExceptionObject(curState.immutableCopy(bci), graph), bci); |
1266 | 1265 |
1267 assert lock != null; | 1266 assert lock != null; |
1268 assert curState.locksSize() > 0 && curState.lockAt(locksSize() - 1) == lock; | 1267 assert curState.locksSize() > 0 && curState.lockAt(locksSize() - 1) == lock; |
1269 if (lock instanceof Instruction) { | 1268 if (lock instanceof Instruction) { |
1270 Instruction l = (Instruction) lock; | 1269 Instruction l = (Instruction) lock; |
1325 blockStart = false; | 1324 blockStart = false; |
1326 } | 1325 } |
1327 } | 1326 } |
1328 if (nextBlock != null && nextBlock != block) { | 1327 if (nextBlock != null && nextBlock != block) { |
1329 // we fell through to the next block, add a goto and break | 1328 // we fell through to the next block, add a goto and break |
1330 end = new Goto(nextBlock, null, false); | 1329 end = new Goto(nextBlock, null, false, graph); |
1331 lastInstr = lastInstr.appendNext(end, prevBCI); | 1330 lastInstr = lastInstr.appendNext(end, prevBCI); |
1332 break; | 1331 break; |
1333 } | 1332 } |
1334 // read the opcode | 1333 // read the opcode |
1335 int opcode = stream.currentBC(); | 1334 int opcode = stream.currentBC(); |
1336 | 1335 |
1337 // push an exception object onto the stack if we are parsing an exception handler | 1336 // push an exception object onto the stack if we are parsing an exception handler |
1338 if (pushException) { | 1337 if (pushException) { |
1339 FrameState stateBefore = curState.immutableCopy(bci()); | 1338 FrameState stateBefore = curState.immutableCopy(bci()); |
1340 apush(append(new ExceptionObject(stateBefore))); | 1339 apush(append(new ExceptionObject(stateBefore, graph))); |
1341 pushException = false; | 1340 pushException = false; |
1342 } | 1341 } |
1343 | 1342 |
1344 traceState(); | 1343 traceState(); |
1345 traceInstruction(bci, stream, opcode, blockStart); | 1344 traceInstruction(bci, stream, opcode, blockStart); |