Mercurial > hg > graal-compiler
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2820:2b8ef0a06391
Clean up in the graph builder.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Mon, 30 May 2011 16:24:22 +0200 |
parents | c3f64b66fc78 |
children | 244921d7cf50 |
comparison
equal
deleted
inserted
replaced
2819:774d2bc06148 | 2820:2b8ef0a06391 |
---|---|
57 * The minimum value to which {@link C1XOptions#TraceBytecodeParserLevel} must be set to trace | 57 * The minimum value to which {@link C1XOptions#TraceBytecodeParserLevel} must be set to trace |
58 * the frame state before each bytecode instruction as it is parsed. | 58 * the frame state before each bytecode instruction as it is parsed. |
59 */ | 59 */ |
60 public static final int TRACELEVEL_STATE = 2; | 60 public static final int TRACELEVEL_STATE = 2; |
61 | 61 |
62 /** | |
63 * An enumeration of flags describing scope attributes. | |
64 */ | |
65 public enum Flag { | |
66 /** | |
67 * Scope is protected by an exception handler. | |
68 * This attribute is inherited by nested scopes. | |
69 */ | |
70 HasHandler, | |
71 | |
72 /** | |
73 * Code in scope cannot contain safepoints. | |
74 * This attribute is inherited by nested scopes. | |
75 */ | |
76 NoSafepoints; | |
77 | |
78 public final int mask = 1 << ordinal(); | |
79 } | |
80 | |
81 private final IR ir; | 62 private final IR ir; |
82 private final C1XCompilation compilation; | 63 private final C1XCompilation compilation; |
83 private final CiStatistics stats; | 64 private final CiStatistics stats; |
84 | 65 |
85 private final BytecodeStream stream; // the bytecode stream | 66 private final BytecodeStream stream; // the bytecode stream |
95 public int compare(Block o1, Block o2) { | 76 public int compare(Block o1, Block o2) { |
96 return o1.blockID - o2.blockID; | 77 return o1.blockID - o2.blockID; |
97 } | 78 } |
98 }); | 79 }); |
99 | 80 |
100 /** | |
101 * Mask of {@link Flag} values. | |
102 */ | |
103 private int flags; | |
104 | |
105 // Exception handler list | 81 // Exception handler list |
106 private List<ExceptionHandler> exceptionHandlers; | 82 private List<ExceptionHandler> exceptionHandlers; |
107 | 83 |
108 private FrameStateBuilder frameState; // the current execution state | 84 private FrameStateBuilder frameState; // the current execution state |
109 private Instruction lastInstr; // the last instruction added | 85 private Instruction lastInstr; // the last instruction added |
111 private final LogStream log; | 87 private final LogStream log; |
112 | 88 |
113 private Value rootMethodSynchronizedObject; | 89 private Value rootMethodSynchronizedObject; |
114 | 90 |
115 private final Graph graph; | 91 private final Graph graph; |
116 | |
117 private Merge unwindBlock; | |
118 | 92 |
119 /** | 93 /** |
120 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. | 94 * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation. |
121 * | 95 * |
122 * @param compilation the compilation | 96 * @param compilation the compilation |
144 if (log != null) { | 118 if (log != null) { |
145 log.println(); | 119 log.println(); |
146 log.println("Compiling " + compilation.method); | 120 log.println("Compiling " + compilation.method); |
147 } | 121 } |
148 | 122 |
149 if (rootMethod.noSafepoints()) { | |
150 flags |= Flag.NoSafepoints.mask; | |
151 } | |
152 | |
153 // 2. compute the block map, setup exception handlers and get the entrypoint(s) | 123 // 2. compute the block map, setup exception handlers and get the entrypoint(s) |
154 BlockMap blockMap = compilation.getBlockMap(rootMethod); | 124 BlockMap blockMap = compilation.getBlockMap(rootMethod); |
155 | 125 |
156 blockList = new ArrayList<Block>(blockMap.blocks); | 126 blockList = new ArrayList<Block>(blockMap.blocks); |
157 blockFromBci = new Block[rootMethod.code().length]; | 127 blockFromBci = new Block[rootMethod.code().length]; |
175 ExceptionHandler h = new ExceptionHandler(ch); | 145 ExceptionHandler h = new ExceptionHandler(ch); |
176 h.setEntryBlock(entry); | 146 h.setEntryBlock(entry); |
177 exceptionHandlers.add(h); | 147 exceptionHandlers.add(h); |
178 } | 148 } |
179 } | 149 } |
180 flags |= Flag.HasHandler.mask; | |
181 | |
182 } | 150 } |
183 | 151 |
184 // 1. create the start block | 152 // 1. create the start block |
185 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); | 153 Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); |
186 markOnWorkList(startBlock); | 154 markOnWorkList(startBlock); |
295 int bci = target.startBci; | 263 int bci = target.startBci; |
296 | 264 |
297 FrameState existingState = ((StateSplit) first).stateBefore(); | 265 FrameState existingState = ((StateSplit) first).stateBefore(); |
298 | 266 |
299 if (existingState == null) { | 267 if (existingState == null) { |
300 // assert first instanceof Merge ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader; | |
301 | |
302 // copy state because it is modified | 268 // copy state because it is modified |
303 FrameState duplicate = newState.duplicate(bci); | 269 FrameState duplicate = newState.duplicate(bci); |
304 | 270 |
305 // if the block is a loop header, insert all necessary phis | 271 // if the block is a loop header, insert all necessary phis |
306 if (first instanceof LoopBegin && target.isLoopHeader) { | 272 if (first instanceof LoopBegin && target.isLoopHeader) { |
420 FrameState entryState = frameState.duplicateWithEmptyStack(bci); | 386 FrameState entryState = frameState.duplicateWithEmptyStack(bci); |
421 | 387 |
422 StateSplit entry = new Placeholder(graph); | 388 StateSplit entry = new Placeholder(graph); |
423 entry.setStateBefore(entryState); | 389 entry.setStateBefore(entryState); |
424 ExceptionObject exception = new ExceptionObject(graph); | 390 ExceptionObject exception = new ExceptionObject(graph); |
425 entry.appendNext(exception); | 391 entry.setNext(exception); |
426 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); | 392 FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); |
427 | 393 |
428 Instruction successor = createTarget(dispatchBlock, stateWithException); | 394 Instruction successor = createTarget(dispatchBlock, stateWithException); |
429 BlockEnd end = new Anchor(successor, graph); | 395 BlockEnd end = new Anchor(successor, graph); |
430 exception.appendNext(end); | 396 exception.setNext(end); |
431 | |
432 if (x instanceof Invoke) { | 397 if (x instanceof Invoke) { |
433 ((Invoke) x).setExceptionEdge(entry); | 398 ((Invoke) x).setExceptionEdge(entry); |
434 } else { | 399 } else { |
435 ((Throw) x).setExceptionEdge(entry); | 400 ((Throw) x).setExceptionEdge(entry); |
436 } | 401 } |
1041 private Value append(Value v) { | 1006 private Value append(Value v) { |
1042 return v; | 1007 return v; |
1043 } | 1008 } |
1044 | 1009 |
1045 private Value appendWithBCI(Instruction x) { | 1010 private Value appendWithBCI(Instruction x) { |
1046 if (x.isAppended()) { | 1011 assert x.next() == null && x.predecessors().size() == 0 : "instruction should not have been appended yet"; |
1047 // the instruction has already been added | |
1048 return x; | |
1049 } | |
1050 | |
1051 assert x.next() == null : "instruction should not have been appended yet"; | |
1052 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; | 1012 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; |
1053 | 1013 lastInstr.setNext(x); |
1054 lastInstr = lastInstr.appendNext(x); | 1014 |
1015 lastInstr = x; | |
1055 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { | 1016 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { |
1056 // bailout if we've exceeded the maximum inlining size | 1017 // bailout if we've exceeded the maximum inlining size |
1057 throw new CiBailout("Method and/or inlining is too large"); | 1018 throw new CiBailout("Method and/or inlining is too large"); |
1058 } | 1019 } |
1059 | 1020 |
1112 | 1073 |
1113 frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore()); | 1074 frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore()); |
1114 | 1075 |
1115 assert lock != null; | 1076 assert lock != null; |
1116 assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock; | 1077 assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock; |
1117 if (lock instanceof Instruction) { | 1078 |
1118 Instruction l = (Instruction) lock; | |
1119 if (!l.isAppended()) { | |
1120 lock = appendWithBCI(l); | |
1121 } | |
1122 } | |
1123 // Exit the monitor and unwind the stack. | 1079 // Exit the monitor and unwind the stack. |
1124 genMonitorExit(lock); | 1080 genMonitorExit(lock); |
1125 append(new Unwind(frameState.apop(), graph)); | 1081 append(new Unwind(frameState.apop(), graph)); |
1126 | 1082 |
1127 // The sync handler is always the last thing to add => we can clear the frameState. | 1083 // The sync handler is always the last thing to add => we can clear the frameState. |
1208 } | 1164 } |
1209 } | 1165 } |
1210 } | 1166 } |
1211 | 1167 |
1212 private void appendGoto(Instruction target) { | 1168 private void appendGoto(Instruction target) { |
1213 //if (target instanceof BlockBegin && !((BlockBegin)target).isLoopHeader) { | 1169 lastInstr.setNext(target); |
1214 // System.out.println("NOTOMITTED"); | |
1215 //append(new Goto(target, graph)); | |
1216 //} else { | |
1217 // System.out.println("omitted"); | |
1218 lastInstr.appendNext(target); | |
1219 //} | |
1220 } | 1170 } |
1221 | 1171 |
1222 private void iterateBytecodesForBlock(Block block) { | 1172 private void iterateBytecodesForBlock(Block block) { |
1223 assert frameState != null; | 1173 assert frameState != null; |
1224 | 1174 |
1523 private void addExceptionHandler(ExceptionHandler handler) { | 1473 private void addExceptionHandler(ExceptionHandler handler) { |
1524 if (exceptionHandlers == null) { | 1474 if (exceptionHandlers == null) { |
1525 exceptionHandlers = new ArrayList<ExceptionHandler>(); | 1475 exceptionHandlers = new ArrayList<ExceptionHandler>(); |
1526 } | 1476 } |
1527 exceptionHandlers.add(handler); | 1477 exceptionHandlers.add(handler); |
1528 flags |= Flag.HasHandler.mask; | |
1529 } | 1478 } |
1530 | 1479 |
1531 /** | 1480 /** |
1532 * Adds a block to the worklist, if it is not already in the worklist. | 1481 * Adds a block to the worklist, if it is not already in the worklist. |
1533 * This method will keep the worklist topologically stored (i.e. the lower | 1482 * This method will keep the worklist topologically stored (i.e. the lower |
1558 /** | 1507 /** |
1559 * Checks whether this graph has any handlers. | 1508 * Checks whether this graph has any handlers. |
1560 * @return {@code true} if there are any exception handlers | 1509 * @return {@code true} if there are any exception handlers |
1561 */ | 1510 */ |
1562 private boolean hasHandler() { | 1511 private boolean hasHandler() { |
1563 return (flags & Flag.HasHandler.mask) != 0; | 1512 return Modifier.isSynchronized(compilation.method.accessFlags()) || (compilation.method.exceptionHandlers() != null && compilation.method.exceptionHandlers().length > 0); |
1564 } | |
1565 | |
1566 /** | |
1567 * Checks whether this graph can contain safepoints. | |
1568 */ | |
1569 private boolean noSafepoints() { | |
1570 return (flags & Flag.NoSafepoints.mask) != 0; | |
1571 } | 1513 } |
1572 } | 1514 } |