comparison graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java @ 2521:2f271a85d104

Removed intrinsic-related instructions
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 16:40:09 +0200
parents f6125fb5bfbc
children 58c05e4c51e2
comparison
equal deleted inserted replaced
2520:99307021e3f5 2521:2f271a85d104
36 import com.sun.c1x.asm.*; 36 import com.sun.c1x.asm.*;
37 import com.sun.c1x.debug.*; 37 import com.sun.c1x.debug.*;
38 import com.sun.c1x.globalstub.*; 38 import com.sun.c1x.globalstub.*;
39 import com.sun.c1x.graph.*; 39 import com.sun.c1x.graph.*;
40 import com.sun.c1x.ir.*; 40 import com.sun.c1x.ir.*;
41 import com.sun.c1x.ir.Value.Flag;
42 import com.sun.c1x.lir.*; 41 import com.sun.c1x.lir.*;
43 import com.sun.c1x.opt.*; 42 import com.sun.c1x.opt.*;
44 import com.sun.c1x.util.*; 43 import com.sun.c1x.util.*;
45 import com.sun.c1x.value.*; 44 import com.sun.c1x.value.*;
46 import com.sun.c1x.value.FrameState.PhiProcedure; 45 import com.sun.c1x.value.FrameState.PhiProcedure;
221 public DeoptimizationStub(FrameState state) { 220 public DeoptimizationStub(FrameState state) {
222 info = new LIRDebugInfo(state, null); 221 info = new LIRDebugInfo(state, null);
223 } 222 }
224 } 223 }
225 224
226 public final void emitGuard(Guard x) {
227 FrameState state = x.stateBefore();
228 assert state != null : "deoptimize instruction always needs a state";
229
230 if (deoptimizationStubs == null) {
231 deoptimizationStubs = new ArrayList<DeoptimizationStub>();
232 }
233
234 // (tw) TODO: Try to reuse an existing stub if possible.
235 // It is only allowed if there are no LIR instructions in between that can modify registers.
236
237 DeoptimizationStub stub = new DeoptimizationStub(state);
238 deoptimizationStubs.add(stub);
239 lir.branch(x.condition.negate(), stub.label, stub.info);
240 }
241
242 public void doBlock(BlockBegin block) { 225 public void doBlock(BlockBegin block) {
243 blockDoProlog(block); 226 blockDoProlog(block);
244 this.currentBlock = block; 227 this.currentBlock = block;
245 228
246 for (Instruction instr = block; instr != null; instr = instr.next()) { 229 for (Instruction instr = block; instr != null; instr = instr.next()) {
429 412
430 @Override 413 @Override
431 public void visitGoto(Goto x) { 414 public void visitGoto(Goto x) {
432 setNoResult(x); 415 setNoResult(x);
433 416
434 if (currentBlock.next() instanceof OsrEntry) {
435 // need to free up storage used for OSR entry point
436 CiValue osrBuffer = currentBlock.next().operand();
437 callRuntime(CiRuntimeCall.OSRMigrationEnd, null, osrBuffer);
438 emitXir(xir.genSafepoint(site(x)), x, stateFor(x, x.stateAfter()), null, false);
439 }
440
441 // emit phi-instruction moves after safepoint since this simplifies 417 // emit phi-instruction moves after safepoint since this simplifies
442 // describing the state at the safepoint. 418 // describing the state at the safepoint.
443 moveToPhi(x.stateAfter()); 419 moveToPhi(x.stateAfter());
444 420
445 lir.jump(x.defaultSuccessor()); 421 lir.jump(x.defaultSuccessor());
646 if (x.canTrap()) { 622 if (x.canTrap()) {
647 LIRDebugInfo info = stateFor(x); 623 LIRDebugInfo info = stateFor(x);
648 lir.nullCheck(value, info); 624 lir.nullCheck(value, info);
649 } 625 }
650 x.setOperand(value); 626 x.setOperand(value);
651 }
652
653 @Override
654 public void visitOsrEntry(OsrEntry x) {
655 // construct our frame and model the production of incoming pointer
656 // to the OSR buffer.
657 lir.osrEntry(osrBufferPointer());
658 CiValue result = createResultVariable(x);
659 lir.move(osrBufferPointer(), result);
660 } 627 }
661 628
662 @Override 629 @Override
663 public void visitPhi(Phi i) { 630 public void visitPhi(Phi i) {
664 Util.shouldNotReachHere(); 631 Util.shouldNotReachHere();
955 if (unwind) { 922 if (unwind) {
956 lir.unwindException(exceptionPcOpr(), exceptionOpr, info); 923 lir.unwindException(exceptionPcOpr(), exceptionOpr, info);
957 } else { 924 } else {
958 lir.throwException(exceptionPcOpr(), argumentOperand, info); 925 lir.throwException(exceptionPcOpr(), argumentOperand, info);
959 } 926 }
960 }
961
962 @Override
963 public void visitUnsafeGetObject(UnsafeGetObject x) {
964 CiKind kind = x.unsafeOpKind;
965
966 CiValue off = load(x.offset());
967 CiValue src = load(x.object());
968
969 CiValue reg = createResultVariable(x);
970
971 if (x.isVolatile()) {
972 vma.preVolatileRead();
973 }
974 genGetObjectUnsafe(reg, src, off, kind, x.isVolatile());
975 if (x.isVolatile()) {
976 vma.postVolatileRead();
977 }
978 }
979
980 @Override
981 public void visitUnsafeGetRaw(UnsafeGetRaw x) {
982 LIRItem idx = new LIRItem(this);
983 CiValue base = load(x.base());
984 if (x.hasIndex()) {
985 idx.setInstruction(x.index());
986 idx.loadNonconstant();
987 }
988
989 CiValue reg = createResultVariable(x);
990
991 int log2scale = 0;
992 if (x.hasIndex()) {
993 assert x.index().kind.isInt() : "should not find non-int index";
994 log2scale = x.log2Scale();
995 }
996
997 assert !x.hasIndex() || idx.instruction == x.index() : "should match";
998
999 CiKind dstKind = x.unsafeOpKind;
1000 CiValue indexOp = idx.result();
1001
1002 CiAddress addr = null;
1003 if (indexOp.isConstant()) {
1004 assert log2scale == 0 : "must not have a scale";
1005 CiConstant constantIndexOp = (CiConstant) indexOp;
1006 addr = new CiAddress(dstKind, base, constantIndexOp.asInt());
1007 } else {
1008
1009 if (compilation.target.arch.isX86()) {
1010 addr = new CiAddress(dstKind, base, indexOp, CiAddress.Scale.fromInt(2 ^ log2scale), 0);
1011
1012 } else if (compilation.target.arch.isSPARC()) {
1013 if (indexOp.isIllegal() || log2scale == 0) {
1014 addr = new CiAddress(dstKind, base, indexOp);
1015 } else {
1016 CiValue tmp = newVariable(CiKind.Int);
1017 lir.shiftLeft(indexOp, log2scale, tmp);
1018 addr = new CiAddress(dstKind, base, tmp);
1019 }
1020
1021 } else {
1022 Util.shouldNotReachHere();
1023 }
1024 }
1025
1026 if (x.mayBeUnaligned() && (dstKind == CiKind.Long || dstKind == CiKind.Double)) {
1027 lir.unalignedMove(addr, reg);
1028 } else {
1029 lir.move(addr, reg);
1030 }
1031 }
1032
1033 @Override
1034 public void visitUnsafePrefetchRead(UnsafePrefetchRead x) {
1035 visitUnsafePrefetch(x, false);
1036 }
1037
1038 @Override
1039 public void visitUnsafePrefetchWrite(UnsafePrefetchWrite x) {
1040 visitUnsafePrefetch(x, true);
1041 }
1042
1043 @Override
1044 public void visitUnsafePutObject(UnsafePutObject x) {
1045 CiKind kind = x.unsafeOpKind;
1046 LIRItem data = new LIRItem(x.value(), this);
1047
1048 CiValue src = load(x.object());
1049 data.loadItem(kind);
1050 CiValue off = load(x.offset());
1051
1052 setNoResult(x);
1053
1054 if (x.isVolatile()) {
1055 vma.preVolatileWrite();
1056 }
1057 genPutObjectUnsafe(src, off, data.result(), kind, x.isVolatile());
1058 if (x.isVolatile()) {
1059 vma.postVolatileWrite();
1060 }
1061 }
1062
1063 @Override
1064 public void visitUnsafePutRaw(UnsafePutRaw x) {
1065 int log2scale = 0;
1066 CiKind kind = x.unsafeOpKind;
1067
1068 if (x.hasIndex()) {
1069 assert x.index().kind.isInt() : "should not find non-int index";
1070 log2scale = x.log2scale();
1071 }
1072
1073 LIRItem value = new LIRItem(x.value(), this);
1074 LIRItem idx = new LIRItem(this);
1075
1076 CiValue base = load(x.base());
1077 if (x.hasIndex()) {
1078 idx.setInstruction(x.index());
1079 idx.loadItem();
1080 }
1081
1082 value.loadItem(kind);
1083
1084 setNoResult(x);
1085
1086 CiValue indexOp = idx.result();
1087 if (log2scale != 0) {
1088 // temporary fix (platform dependent code without shift on Intel would be better)
1089 indexOp = newVariable(CiKind.Int);
1090 lir.move(idx.result(), indexOp);
1091 lir.shiftLeft(indexOp, log2scale, indexOp);
1092 }
1093
1094 CiValue addr = new CiAddress(x.unsafeOpKind, base, indexOp);
1095 lir.move(value.result(), addr);
1096 } 927 }
1097 928
1098 private void blockDoEpilog(BlockBegin block) { 929 private void blockDoEpilog(BlockBegin block) {
1099 if (C1XOptions.PrintIRWithLIR) { 930 if (C1XOptions.PrintIRWithLIR) {
1100 TTY.println(); 931 TTY.println();
1213 lir.branch(Condition.LE, CiKind.Int, dest); 1044 lir.branch(Condition.LE, CiKind.Int, dest);
1214 lir.branchDestination(l); 1045 lir.branchDestination(l);
1215 } 1046 }
1216 } 1047 }
1217 lir.jump(defaultSux); 1048 lir.jump(defaultSux);
1218 }
1219
1220 private void visitUnsafePrefetch(UnsafePrefetch x, boolean isStore) {
1221 LIRItem src = new LIRItem(x.object(), this);
1222 LIRItem off = new LIRItem(x.offset(), this);
1223
1224 src.loadItem();
1225 if (!(off.result().isConstant() && canInlineAsConstant(x.offset()))) {
1226 off.loadItem();
1227 }
1228
1229 setNoResult(x);
1230
1231 CiAddress addr = genAddress(src.result(), off.result(), 0, 0, CiKind.Byte);
1232 lir.prefetch(addr, isStore);
1233 } 1049 }
1234 1050
1235 protected void arithmeticOpFpu(int code, CiValue result, CiValue left, CiValue right, CiValue tmp) { 1051 protected void arithmeticOpFpu(int code, CiValue result, CiValue left, CiValue right, CiValue tmp) {
1236 CiValue leftOp = left; 1052 CiValue leftOp = left;
1237 1053
1848 return "XirSupport<" + current + ">"; 1664 return "XirSupport<" + current + ">";
1849 } 1665 }
1850 1666
1851 } 1667 }
1852 1668
1853 public void arrayCopy(RiType type, ArrayCopy arrayCopy, XirSnippet snippet) {
1854 emitXir(snippet, arrayCopy, stateFor(arrayCopy), null, false);
1855 }
1856
1857 @Override
1858 public void visitArrayCopy(ArrayCopy arrayCopy) {
1859 Value src = arrayCopy.src();
1860 Value dest = arrayCopy.dest();
1861 Value srcPos = arrayCopy.srcPos();
1862 Value destPos = arrayCopy.destPos();
1863 Value length = arrayCopy.length();
1864 RiType srcType = src.declaredType();
1865 RiType destType = dest.declaredType();
1866 if ((srcType != null && srcType.isArrayClass()) || (destType != null && destType.isArrayClass())) {
1867 RiType type = (srcType == null) ? destType : srcType;
1868 if ((srcType == null || destType == null || srcType.kind() != destType.kind()) && type.kind() != CiKind.Object) {
1869 TypeEqualityCheck typeCheck = new TypeEqualityCheck(src, dest, arrayCopy.stateBefore(), Condition.EQ);
1870 visitTypeEqualityCheck(typeCheck);
1871 }
1872 boolean inputsSame = (src == dest);
1873 boolean inputsDifferent = !inputsSame && (src.checkFlag(Flag.ResultIsUnique) || dest.checkFlag(Flag.ResultIsUnique));
1874 boolean needsStoreCheck = type.componentType().kind() == CiKind.Object && destType != srcType;
1875 if (!needsStoreCheck) {
1876 arrayCopy.setFlag(Flag.NoStoreCheck);
1877 }
1878 XirSnippet snippet = xir.genArrayCopy(site(arrayCopy), toXirArgument(src), toXirArgument(srcPos), toXirArgument(dest), toXirArgument(destPos), toXirArgument(length), type.componentType(), inputsSame, inputsDifferent);
1879 arrayCopy(type, arrayCopy, snippet);
1880 return;
1881 }
1882 arrayCopySlow(arrayCopy);
1883 }
1884
1885 private void arrayCopySlow(ArrayCopy arrayCopy) {
1886 emitInvokeKnown(arrayCopy.arrayCopyMethod, arrayCopy.stateBefore(), arrayCopy.src(), arrayCopy.srcPos(), arrayCopy.dest(), arrayCopy.destPos(), arrayCopy.length());
1887 }
1888
1889 private CiValue emitInvokeKnown(RiMethod method, FrameState stateBefore, Value... args) { 1669 private CiValue emitInvokeKnown(RiMethod method, FrameState stateBefore, Value... args) {
1890 boolean isStatic = Modifier.isStatic(method.accessFlags()); 1670 boolean isStatic = Modifier.isStatic(method.accessFlags());
1891 Invoke invoke = new Invoke(isStatic ? Bytecodes.INVOKESTATIC : Bytecodes.INVOKESPECIAL, method.signature().returnKind(), args, isStatic, method, null, stateBefore); 1671 Invoke invoke = new Invoke(isStatic ? Bytecodes.INVOKESTATIC : Bytecodes.INVOKESPECIAL, method.signature().returnKind(), args, isStatic, method, null, stateBefore);
1892 visitInvoke(invoke); 1672 visitInvoke(invoke);
1893 return invoke.operand(); 1673 return invoke.operand();
1894 } 1674 }
1895
1896 @Override
1897 public void visitTypeEqualityCheck(TypeEqualityCheck typeEqualityCheck) {
1898 Value x = typeEqualityCheck.left();
1899 Value y = typeEqualityCheck.right();
1900
1901 CiValue leftValue = emitXir(xir.genGetClass(site(typeEqualityCheck), toXirArgument(x)), typeEqualityCheck, stateFor(typeEqualityCheck), null, false);
1902 CiValue rightValue = emitXir(xir.genGetClass(site(typeEqualityCheck), toXirArgument(y)), typeEqualityCheck, stateFor(typeEqualityCheck), null, false);
1903 lir.cmp(typeEqualityCheck.condition.negate(), leftValue, rightValue);
1904 emitGuard(typeEqualityCheck);
1905 }
1906 } 1675 }