Mercurial > hg > truffle
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2519:f6125fb5bfbc
Removed intrinsics.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Apr 2011 16:25:32 +0200 |
parents | a384fac3fd34 |
children | 2f271a85d104 |
comparison
equal
deleted
inserted
replaced
2516:a384fac3fd34 | 2519:f6125fb5bfbc |
---|---|
151 } else { | 151 } else { |
152 // 4B.1 simply finish the start block | 152 // 4B.1 simply finish the start block |
153 finishStartBlock(startBlock, stdEntry); | 153 finishStartBlock(startBlock, stdEntry); |
154 } | 154 } |
155 | 155 |
156 // 5. | 156 // 5. SKIPPED: look for intrinsics |
157 C1XIntrinsic intrinsic = C1XOptions.OptIntrinsify ? C1XIntrinsic.getIntrinsic(rootMethod) : null; | 157 |
158 if (intrinsic != null) { | 158 // 6B.1 do the normal parsing |
159 lastInstr = stdEntry; | 159 scopeData.addToWorkList(stdEntry); |
160 // 6A.1 the root method is an intrinsic; load the parameters onto the stack and try to inline it | 160 iterateAllBlocks(); |
161 if (C1XOptions.OptIntrinsify) { | |
162 // try to inline an Intrinsic node | |
163 boolean isStatic = Modifier.isStatic(rootMethod.accessFlags()); | |
164 int argsSize = rootMethod.signature().argumentSlots(!isStatic); | |
165 Value[] args = new Value[argsSize]; | |
166 for (int i = 0; i < args.length; i++) { | |
167 args[i] = curState.localAt(i); | |
168 } | |
169 if (tryInlineIntrinsic(rootMethod, args, isStatic, intrinsic)) { | |
170 // intrinsic inlining succeeded, add the return node | |
171 CiKind rt = returnKind(rootMethod).stackKind(); | |
172 Value result = null; | |
173 if (rt != CiKind.Void) { | |
174 result = pop(rt); | |
175 } | |
176 genReturn(result); | |
177 BlockEnd end = (BlockEnd) lastInstr; | |
178 stdEntry.setEnd(end); | |
179 end.setStateAfter(curState.immutableCopy(bci())); | |
180 } else { | |
181 // try intrinsic failed; do the normal parsing | |
182 scopeData.addToWorkList(stdEntry); | |
183 iterateAllBlocks(); | |
184 } | |
185 } else { | |
186 // 6B.1 do the normal parsing | |
187 scopeData.addToWorkList(stdEntry); | |
188 iterateAllBlocks(); | |
189 } | |
190 } else { | |
191 // 6B.1 do the normal parsing | |
192 scopeData.addToWorkList(stdEntry); | |
193 iterateAllBlocks(); | |
194 } | |
195 | 161 |
196 if (syncHandler != null && syncHandler.stateBefore() != null) { | 162 if (syncHandler != null && syncHandler.stateBefore() != null) { |
197 // generate unlocking code if the exception handler is reachable | 163 // generate unlocking code if the exception handler is reachable |
198 fillSyncHandler(rootMethodSynchronizedObject, syncHandler, false); | 164 fillSyncHandler(rootMethodSynchronizedObject, syncHandler, false); |
199 } | 165 } |
1077 } | 1043 } |
1078 } | 1044 } |
1079 } | 1045 } |
1080 | 1046 |
1081 if (needsCheck) { | 1047 if (needsCheck) { |
1082 // append a call to the registration intrinsic | 1048 // append a call to the finalizer registration |
1083 loadLocal(0, CiKind.Object); | 1049 append(new RegisterFinalizer(curState.loadLocal(0), curState.immutableCopy(bci()))); |
1084 FrameState stateBefore = curState.immutableCopy(bci()); | |
1085 append(new Intrinsic(CiKind.Void, C1XIntrinsic.java_lang_Object$init, | |
1086 null, curState.popArguments(1), false, stateBefore, true, true)); | |
1087 C1XMetrics.InlinedFinalizerChecks++; | 1050 C1XMetrics.InlinedFinalizerChecks++; |
1088 } | 1051 } |
1089 } | 1052 } |
1090 | 1053 |
1091 void genReturn(Value x) { | 1054 void genReturn(Value x) { |
1092 if (C1XIntrinsic.getIntrinsic(method()) == C1XIntrinsic.java_lang_Object$init) { | 1055 if (method().isConstructor() && method().holder().superType() == null) { |
1093 callRegisterFinalizer(); | 1056 callRegisterFinalizer(); |
1094 } | 1057 } |
1095 | 1058 |
1096 // If inlining, then returns become gotos to the continuation point. | 1059 // If inlining, then returns become gotos to the continuation point. |
1097 if (scopeData.continuation() != null) { | 1060 if (scopeData.continuation() != null) { |
1322 } | 1285 } |
1323 | 1286 |
1324 assert x.next() == null : "instruction should not have been appended yet"; | 1287 assert x.next() == null : "instruction should not have been appended yet"; |
1325 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; | 1288 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; |
1326 if (lastInstr instanceof Base) { | 1289 if (lastInstr instanceof Base) { |
1327 assert x instanceof Intrinsic : "may only happen when inlining intrinsics"; | 1290 assert false : "may only happen when inlining intrinsics"; |
1328 Instruction prev = lastInstr.prev(lastInstr.block()); | |
1329 prev.setNext(x, bci); | |
1330 x.setNext(lastInstr, bci); | |
1331 } else { | 1291 } else { |
1332 lastInstr = lastInstr.setNext(x, bci); | 1292 lastInstr = lastInstr.setNext(x, bci); |
1333 } | 1293 } |
1334 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { | 1294 if (++stats.nodeCount >= C1XOptions.MaximumInstructionCount) { |
1335 // bailout if we've exceeded the maximum inlining size | 1295 // bailout if we've exceeded the maximum inlining size |
1355 | 1315 |
1356 return x; | 1316 return x; |
1357 } | 1317 } |
1358 | 1318 |
1359 private boolean hasUncontrollableSideEffects(Value x) { | 1319 private boolean hasUncontrollableSideEffects(Value x) { |
1360 return x instanceof Invoke || x instanceof Intrinsic && !((Intrinsic) x).preservesState() || x instanceof ResolveClass; | 1320 return x instanceof Invoke || x instanceof ResolveClass; |
1361 } | 1321 } |
1362 | 1322 |
1363 private BlockBegin blockAtOrNull(int bci) { | 1323 private BlockBegin blockAtOrNull(int bci) { |
1364 return scopeData.blockAt(bci); | 1324 return scopeData.blockAt(bci); |
1365 } | 1325 } |
1464 return state; | 1424 return state; |
1465 } | 1425 } |
1466 | 1426 |
1467 boolean tryRemoveCall(RiMethod target, Value[] args, boolean isStatic) { | 1427 boolean tryRemoveCall(RiMethod target, Value[] args, boolean isStatic) { |
1468 if (target.isResolved()) { | 1428 if (target.isResolved()) { |
1469 if (C1XOptions.OptIntrinsify) { | |
1470 // try to create an intrinsic node instead of a call | |
1471 C1XIntrinsic intrinsic = C1XIntrinsic.getIntrinsic(target); | |
1472 if (intrinsic != null && tryInlineIntrinsic(target, args, isStatic, intrinsic)) { | |
1473 // this method is not an intrinsic | |
1474 return true; | |
1475 } | |
1476 } | |
1477 if (C1XOptions.CanonicalizeFoldableMethods) { | 1429 if (C1XOptions.CanonicalizeFoldableMethods) { |
1478 // next try to fold the method call | 1430 // next try to fold the method call |
1479 if (tryFoldable(target, args)) { | 1431 if (tryFoldable(target, args)) { |
1480 return true; | 1432 return true; |
1481 } | 1433 } |
1482 } | 1434 } |
1483 } | 1435 } |
1484 return false; | 1436 return false; |
1485 } | |
1486 | |
1487 private boolean tryInlineIntrinsic(RiMethod target, Value[] args, boolean isStatic, C1XIntrinsic intrinsic) { | |
1488 boolean preservesState = true; | |
1489 boolean canTrap = false; | |
1490 | |
1491 Instruction result = null; | |
1492 | |
1493 // handle intrinsics differently | |
1494 switch (intrinsic) { | |
1495 | |
1496 case java_lang_System$arraycopy: | |
1497 if (compilation.runtime.supportsArrayIntrinsics()) { | |
1498 break; | |
1499 } else { | |
1500 return false; | |
1501 } | |
1502 case java_lang_Object$getClass: | |
1503 canTrap = true; | |
1504 break; | |
1505 case java_lang_Thread$currentThread: | |
1506 break; | |
1507 case java_util_Arrays$copyOf: | |
1508 if (args[0].declaredType() != null && args[0].declaredType().isArrayClass() && compilation.runtime.supportsArrayIntrinsics()) { | |
1509 break; | |
1510 } else { | |
1511 return false; | |
1512 } | |
1513 case java_lang_Object$init: // fall through | |
1514 case java_lang_String$equals: // fall through | |
1515 case java_lang_String$compareTo: // fall through | |
1516 case java_lang_String$indexOf: // fall through | |
1517 case java_lang_Math$max: // fall through | |
1518 case java_lang_Math$min: // fall through | |
1519 case java_lang_Math$atan2: // fall through | |
1520 case java_lang_Math$pow: // fall through | |
1521 case java_lang_Math$exp: // fall through | |
1522 case java_nio_Buffer$checkIndex: // fall through | |
1523 case java_lang_System$identityHashCode: // fall through | |
1524 case java_lang_System$currentTimeMillis: // fall through | |
1525 case java_lang_System$nanoTime: // fall through | |
1526 case java_lang_Object$hashCode: // fall through | |
1527 case java_lang_Class$isAssignableFrom: // fall through | |
1528 case java_lang_Class$isInstance: // fall through | |
1529 case java_lang_Class$getModifiers: // fall through | |
1530 case java_lang_Class$isInterface: // fall through | |
1531 case java_lang_Class$isArray: // fall through | |
1532 case java_lang_Class$isPrimitive: // fall through | |
1533 case java_lang_Class$getSuperclass: // fall through | |
1534 case java_lang_Class$getComponentType: // fall through | |
1535 case java_lang_reflect_Array$getLength: // fall through | |
1536 case java_lang_reflect_Array$newArray: // fall through | |
1537 case java_lang_Double$doubleToLongBits: // fall through | |
1538 case java_lang_Float$floatToIntBits: // fall through | |
1539 case java_lang_Math$sin: // fall through | |
1540 case java_lang_Math$cos: // fall through | |
1541 case java_lang_Math$tan: // fall through | |
1542 case java_lang_Math$log: // fall through | |
1543 case java_lang_Math$log10: // fall through | |
1544 case java_lang_Integer$bitCount: // fall through | |
1545 case java_lang_Integer$reverseBytes: // fall through | |
1546 case java_lang_Long$bitCount: // fall through | |
1547 case java_lang_Long$reverseBytes: // fall through | |
1548 case java_lang_Object$clone: return false; | |
1549 // TODO: preservesState and canTrap for complex intrinsics | |
1550 } | |
1551 | |
1552 | |
1553 | |
1554 // get the arguments for the intrinsic | |
1555 CiKind resultType = returnKind(target); | |
1556 | |
1557 if (C1XOptions.PrintInlinedIntrinsics) { | |
1558 TTY.println("Inlining intrinsic: " + intrinsic); | |
1559 } | |
1560 | |
1561 // Create state before intrinsic. | |
1562 for (int i = 0; i < args.length; ++i) { | |
1563 if (args[i] != null) { | |
1564 curState.push(args[i].kind.stackKind(), args[i]); | |
1565 } | |
1566 } | |
1567 | |
1568 // Create the intrinsic node. | |
1569 if (intrinsic == C1XIntrinsic.java_lang_System$arraycopy) { | |
1570 result = genArrayCopy(target, args); | |
1571 } else if (intrinsic == C1XIntrinsic.java_util_Arrays$copyOf) { | |
1572 result = genArrayClone(target, args); | |
1573 } else { | |
1574 result = new Intrinsic(resultType.stackKind(), intrinsic, target, args, isStatic, curState.immutableCopy(bci()), preservesState, canTrap); | |
1575 } | |
1576 | |
1577 // Pop arguments. | |
1578 curState.popArguments(args.length); | |
1579 | |
1580 pushReturn(resultType, append(result)); | |
1581 stats.intrinsicCount++; | |
1582 return true; | |
1583 } | 1437 } |
1584 | 1438 |
1585 private Instruction genArrayClone(RiMethod target, Value[] args) { | 1439 private Instruction genArrayClone(RiMethod target, Value[] args) { |
1586 FrameState state = curState.immutableCopy(bci()); | 1440 FrameState state = curState.immutableCopy(bci()); |
1587 Value array = args[0]; | 1441 Value array = args[0]; |