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