Mercurial > hg > truffle
comparison graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java @ 2515:4fdef1464592
Removed extended bytecodes and related HIR instructions.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Apr 2011 15:36:29 +0200 |
parents | 16b9a8b5ad39 |
children | f6125fb5bfbc |
comparison
equal
deleted
inserted
replaced
2514:34b5eea9b001 | 2515:4fdef1464592 |
---|---|
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; | 41 import com.sun.c1x.ir.Value.Flag; |
42 import com.sun.c1x.lir.FrameMap.StackBlock; | |
43 import com.sun.c1x.lir.*; | 42 import com.sun.c1x.lir.*; |
44 import com.sun.c1x.opt.*; | 43 import com.sun.c1x.opt.*; |
45 import com.sun.c1x.util.*; | 44 import com.sun.c1x.util.*; |
46 import com.sun.c1x.value.*; | 45 import com.sun.c1x.value.*; |
47 import com.sun.c1x.value.FrameState.PhiProcedure; | 46 import com.sun.c1x.value.FrameState.PhiProcedure; |
48 import com.sun.cri.bytecode.*; | 47 import com.sun.cri.bytecode.*; |
49 import com.sun.cri.bytecode.Bytecodes.MemoryBarriers; | 48 import com.sun.cri.bytecode.Bytecodes.MemoryBarriers; |
50 import com.sun.cri.ci.*; | 49 import com.sun.cri.ci.*; |
51 import com.sun.cri.ci.CiAddress.Scale; | |
52 import com.sun.cri.ri.*; | 50 import com.sun.cri.ri.*; |
53 import com.sun.cri.xir.CiXirAssembler.XirConstant; | 51 import com.sun.cri.xir.CiXirAssembler.XirConstant; |
54 import com.sun.cri.xir.CiXirAssembler.XirInstruction; | 52 import com.sun.cri.xir.CiXirAssembler.XirInstruction; |
55 import com.sun.cri.xir.CiXirAssembler.XirOperand; | 53 import com.sun.cri.xir.CiXirAssembler.XirOperand; |
56 import com.sun.cri.xir.CiXirAssembler.XirParameter; | 54 import com.sun.cri.xir.CiXirAssembler.XirParameter; |
616 lir.move(resultOperand, result); | 614 lir.move(resultOperand, result); |
617 } | 615 } |
618 } | 616 } |
619 | 617 |
620 @Override | 618 @Override |
621 public void visitNativeCall(NativeCall x) { | |
622 LIRDebugInfo info = stateFor(x, x.stateBefore()); | |
623 CiValue resultOperand = resultOperandFor(x.kind); | |
624 CiValue callAddress = load(x.address()); | |
625 CiKind[] signature = Util.signatureToKinds(x.signature, null); | |
626 CiCallingConvention cc = compilation.frameMap().getCallingConvention(signature, NativeCall); | |
627 List<CiValue> argList = visitInvokeArguments(cc, x.arguments, null); | |
628 argList.add(callAddress); | |
629 lir.callNative(x.nativeMethod.jniSymbol(), resultOperand, argList, info, null); | |
630 if (resultOperand.isLegal()) { | |
631 CiValue result = createResultVariable(x); | |
632 lir.move(resultOperand, result); | |
633 } | |
634 } | |
635 | |
636 @Override | |
637 public void visitTemplateCall(TemplateCall x) { | 619 public void visitTemplateCall(TemplateCall x) { |
638 CiValue resultOperand = resultOperandFor(x.kind); | 620 CiValue resultOperand = resultOperandFor(x.kind); |
639 List<CiValue> argList; | 621 List<CiValue> argList; |
640 if (x.receiver() != null) { | 622 if (x.receiver() != null) { |
641 CiCallingConvention cc = compilation.frameMap().getCallingConvention(new CiKind[] {CiKind.Object}, JavaCall); | 623 CiCallingConvention cc = compilation.frameMap().getCallingConvention(new CiKind[] {CiKind.Object}, JavaCall); |
654 lir.move(resultOperand, result); | 636 lir.move(resultOperand, result); |
655 } | 637 } |
656 } | 638 } |
657 | 639 |
658 @Override | 640 @Override |
659 public void visitLoadRegister(LoadRegister x) { | |
660 x.setOperand(x.register.asValue(x.kind)); | |
661 } | |
662 | |
663 @Override | |
664 public void visitPause(Pause i) { | |
665 lir.pause(); | |
666 } | |
667 | |
668 @Override | |
669 public void visitBreakpointTrap(BreakpointTrap i) { | |
670 lir.breakpoint(); | |
671 } | |
672 | |
673 protected CiAddress getAddressForPointerOp(PointerOp x, CiKind kind, CiValue pointer) { | |
674 CiAddress addr; | |
675 Value offset = x.offset(); | |
676 Value index = x.index(); | |
677 if (x.displacement() == null) { | |
678 // address is [pointer + offset] | |
679 if (offset.isConstant() && offset.kind.isInt()) { | |
680 int displacement = x.offset().asConstant().asInt(); | |
681 addr = new CiAddress(kind, pointer, displacement); | |
682 } else { | |
683 addr = new CiAddress(kind, pointer, load(offset)); | |
684 } | |
685 } else { | |
686 // address is [pointer + disp + (index * scale)] | |
687 assert (x.opcode & 0xff) == PGET || (x.opcode & 0xff) == PSET; | |
688 if (!x.displacement().isConstant()) { | |
689 CiVariable tmp = newVariable(CiKind.Word); | |
690 arithmeticOpLong(Bytecodes.LADD, tmp, pointer, load(x.displacement()), null); | |
691 int kindSize = compilation.target.sizeInBytes(kind); | |
692 Scale scale = Scale.fromInt(kindSize); | |
693 if (index.isConstant()) { | |
694 addr = new CiAddress(kind, tmp, index.asConstant().asInt() * kindSize); | |
695 } else { | |
696 addr = new CiAddress(kind, tmp, load(index), scale, 0); | |
697 } | |
698 } else { | |
699 int displacement = x.displacement().asConstant().asInt(); | |
700 int kindSize = compilation.target.sizeInBytes(kind); | |
701 Scale scale = Scale.fromInt(kindSize); | |
702 if (index.isConstant()) { | |
703 displacement += index.asConstant().asInt() * kindSize; | |
704 addr = new CiAddress(kind, pointer, displacement); | |
705 } else { | |
706 addr = new CiAddress(kind, pointer, load(index), scale, displacement); | |
707 } | |
708 } | |
709 } | |
710 return addr; | |
711 } | |
712 | |
713 @Override | |
714 public void visitAllocateStackHandle(StackHandle x) { | |
715 CiValue value = load(x.value()); | |
716 CiValue src = forceToSpill(value, x.value().kind, true); | |
717 CiValue dst = createResultVariable(x); | |
718 | |
719 CiConstant constant = x.value().isConstant() ? x.value().asConstant() : null; | |
720 if (constant == null) { | |
721 CiConstant zero = CiConstant.defaultValue(x.value().kind); | |
722 lir.cmp(Condition.EQ, src, zero); | |
723 } | |
724 lir.lea(src, dst); | |
725 if (constant != null) { | |
726 if (constant.isDefaultValue()) { | |
727 lir.move(value, dst); | |
728 } | |
729 } else { | |
730 lir.cmove(Condition.EQ, CiConstant.ZERO, dst, dst); | |
731 } | |
732 } | |
733 | |
734 @Override | |
735 public void visitLoadPointer(LoadPointer x) { | |
736 LIRDebugInfo info = maybeStateFor(x); | |
737 CiValue pointer = load(x.pointer()); | |
738 CiValue dst = createResultVariable(x); | |
739 CiAddress src = getAddressForPointerOp(x, x.dataKind, pointer); | |
740 lir.load(src, dst, info); | |
741 } | |
742 | |
743 @Override | |
744 public void visitStorePointer(StorePointer x) { | |
745 LIRDebugInfo info = maybeStateFor(x); | |
746 LIRItem value = new LIRItem(x.value(), this); | |
747 CiValue pointer = load(x.pointer()); | |
748 value.loadItem(x.dataKind); | |
749 CiAddress dst = getAddressForPointerOp(x, x.dataKind, pointer); | |
750 lir.store(value.result(), dst, info); | |
751 } | |
752 | |
753 @Override | |
754 public void visitInfopoint(Infopoint x) { | |
755 LIRDebugInfo info = stateFor(x); | |
756 if (x.opcode == SAFEPOINT) { | |
757 emitXir(xir.genSafepoint(site(x)), x, info, null, false); | |
758 return; | |
759 } | |
760 assert x.opcode == HERE || x.opcode == INFO; | |
761 CiValue result = x.kind.isVoid() ? CiValue.IllegalValue : createResultVariable(x); | |
762 LIROpcode opcode = x.opcode == HERE ? LIROpcode.Here : LIROpcode.Info; | |
763 lir.infopoint(opcode, result, info); | |
764 } | |
765 | |
766 @Override | |
767 public void visitStackAllocate(StackAllocate x) { | |
768 CiValue result = createResultVariable(x); | |
769 assert x.size().isConstant() : "ALLOCA bytecode 'size' operand is not a constant: " + x.size(); | |
770 StackBlock stackBlock = compilation.frameMap().reserveStackBlock(x.size().asConstant().asInt()); | |
771 lir.alloca(stackBlock, result); | |
772 } | |
773 | |
774 @Override | |
775 public void visitMonitorAddress(MonitorAddress x) { | 641 public void visitMonitorAddress(MonitorAddress x) { |
776 CiValue result = createResultVariable(x); | 642 CiValue result = createResultVariable(x); |
777 lir.monitorAddress(x.monitor(), result); | 643 lir.monitorAddress(x.monitor(), result); |
778 } | |
779 | |
780 @Override | |
781 public void visitMemoryBarrier(MemoryBarrier x) { | |
782 if (x.barriers != 0) { | |
783 lir.membar(x.barriers); | |
784 } | |
785 } | |
786 | |
787 @Override | |
788 public void visitUnsafeCast(UnsafeCast i) { | |
789 assert !i.redundant : "redundant UnsafeCasts must be eliminated by the front end"; | |
790 CiValue src = load(i.value()); | |
791 CiValue dst = createResultVariable(i); | |
792 lir.move(src, dst); | |
793 } | 644 } |
794 | 645 |
795 /** | 646 /** |
796 * For note on volatile fields, see {@link #visitStoreField(StoreField)}. | 647 * For note on volatile fields, see {@link #visitStoreField(StoreField)}. |
797 */ | 648 */ |
1086 (operands[resultOperand.index] == IllegalValue) ? -1 : resultOperand.index, | 937 (operands[resultOperand.index] == IllegalValue) ? -1 : resultOperand.index, |
1087 info, infoAfter, method, pointerSlots); | 938 info, infoAfter, method, pointerSlots); |
1088 } | 939 } |
1089 | 940 |
1090 return operands[resultOperand.index]; | 941 return operands[resultOperand.index]; |
1091 } | |
1092 | |
1093 @Override | |
1094 public void visitIncrementRegister(IncrementRegister x) { | |
1095 CiValue reg = x.register.asValue(CiKind.Word); | |
1096 if (x.delta().isConstant()) { | |
1097 int delta = x.delta().asConstant().asInt(); | |
1098 if (delta < 0) { | |
1099 lir.sub(reg, CiConstant.forInt(-delta), reg); | |
1100 } else { | |
1101 lir.add(reg, CiConstant.forInt(delta), reg); | |
1102 } | |
1103 } else { | |
1104 lir.add(reg, makeOperand(x.delta()), reg); | |
1105 } | |
1106 } | |
1107 | |
1108 @Override | |
1109 public void visitStoreRegister(StoreRegister x) { | |
1110 CiValue reg = x.register.asValue(x.kind); | |
1111 lir.move(makeOperand(x.value()), reg); | |
1112 } | 942 } |
1113 | 943 |
1114 @Override | 944 @Override |
1115 public void visitStoreField(StoreField x) { | 945 public void visitStoreField(StoreField x) { |
1116 RiField field = x.field(); | 946 RiField field = x.field(); |
1709 instr.accept(this); | 1539 instr.accept(this); |
1710 if (C1XOptions.TraceLIRVisit) { | 1540 if (C1XOptions.TraceLIRVisit) { |
1711 TTY.println("Operand for " + instr + " = " + instr.operand()); | 1541 TTY.println("Operand for " + instr + " = " + instr.operand()); |
1712 } | 1542 } |
1713 | 1543 |
1714 assert (instr.operand().isLegal()) || !isUsedForValue(instr) || instr.isConstant() || instr instanceof UnsafeCast : "operand was not set for live instruction"; | 1544 assert (instr.operand().isLegal()) || !isUsedForValue(instr) || instr.isConstant() : "operand was not set for live instruction"; |
1715 } | 1545 } |
1716 | 1546 |
1717 private boolean isUsedForValue(Instruction instr) { | 1547 private boolean isUsedForValue(Instruction instr) { |
1718 return instr.checkFlag(Value.Flag.LiveValue); | 1548 return instr.checkFlag(Value.Flag.LiveValue); |
1719 } | 1549 } |
1919 assert !value.hasSubst() : "missed substitution"; | 1749 assert !value.hasSubst() : "missed substitution"; |
1920 assert value.isLive() : "value must be marked live in frame state"; | 1750 assert value.isLive() : "value must be marked live in frame state"; |
1921 if (value instanceof Phi && !value.isIllegal()) { | 1751 if (value instanceof Phi && !value.isIllegal()) { |
1922 // phi's are special | 1752 // phi's are special |
1923 operandForPhi((Phi) value); | 1753 operandForPhi((Phi) value); |
1924 } else if (value.operand().isIllegal() && !(value instanceof UnsafeCast)) { | 1754 } else if (value.operand().isIllegal()) { |
1925 // instruction doesn't have an operand yet | 1755 // instruction doesn't have an operand yet |
1926 CiValue operand = makeOperand(value); | 1756 CiValue operand = makeOperand(value); |
1927 assert operand.isLegal() : "must be evaluated now"; | 1757 assert operand.isLegal() : "must be evaluated now"; |
1928 } | 1758 } |
1929 } | 1759 } |