OLD | NEW |
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the PNaCl bitcode file to Ice, to machine code | 10 // This file implements the PNaCl bitcode file to Ice, to machine code |
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION; | 807 FunctionParser &operator=(const FunctionParser &) LLVM_DELETED_FUNCTION; |
808 friend class FunctionValuesymtabParser; | 808 friend class FunctionValuesymtabParser; |
809 | 809 |
810 public: | 810 public: |
811 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) | 811 FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
812 : BlockParserBaseClass(BlockID, EnclosingParser), | 812 : BlockParserBaseClass(BlockID, EnclosingParser), |
813 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), | 813 Func(new Ice::Cfg(getTranslator().getContext())), CurrentBbIndex(0), |
814 FcnId(Context->getNextFunctionBlockValueID()), | 814 FcnId(Context->getNextFunctionBlockValueID()), |
815 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))), | 815 LLVMFunc(cast<Function>(Context->getGlobalValueByID(FcnId))), |
816 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()), | 816 CachedNumGlobalValueIDs(Context->getNumGlobalValueIDs()), |
| 817 NextLocalInstIndex(Context->getNumGlobalValueIDs()), |
817 InstIsTerminating(false) { | 818 InstIsTerminating(false) { |
818 Func->setFunctionName(LLVMFunc->getName()); | 819 Func->setFunctionName(LLVMFunc->getName()); |
819 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); | 820 Func->setReturnType(Context->convertToIceType(LLVMFunc->getReturnType())); |
820 Func->setInternal(LLVMFunc->hasInternalLinkage()); | 821 Func->setInternal(LLVMFunc->hasInternalLinkage()); |
821 CurrentNode = InstallNextBasicBlock(); | 822 CurrentNode = InstallNextBasicBlock(); |
822 Func->setEntryNode(CurrentNode); | 823 Func->setEntryNode(CurrentNode); |
823 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), | 824 for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), |
824 ArgE = LLVMFunc->arg_end(); | 825 ArgE = LLVMFunc->arg_end(); |
825 ArgI != ArgE; ++ArgI) { | 826 ArgI != ArgE; ++ArgI) { |
826 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType()))); | 827 Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType()))); |
827 } | 828 } |
828 } | 829 } |
829 | 830 |
830 ~FunctionParser() LLVM_OVERRIDE; | 831 ~FunctionParser() LLVM_OVERRIDE; |
831 | 832 |
832 // Set the next constant ID to the given constant C. | 833 // Set the next constant ID to the given constant C. |
833 void setNextConstantID(Ice::Constant *C) { LocalOperands.push_back(C); } | 834 void setNextConstantID(Ice::Constant *C) { |
| 835 setOperand(NextLocalInstIndex++, C); |
| 836 } |
834 | 837 |
835 private: | 838 private: |
836 // Timer for reading function bitcode and converting to ICE. | 839 // Timer for reading function bitcode and converting to ICE. |
837 Ice::Timer TConvert; | 840 Ice::Timer TConvert; |
838 // The corresponding ICE function defined by the function block. | 841 // The corresponding ICE function defined by the function block. |
839 Ice::Cfg *Func; | 842 Ice::Cfg *Func; |
840 // The index to the current basic block being built. | 843 // The index to the current basic block being built. |
841 uint32_t CurrentBbIndex; | 844 uint32_t CurrentBbIndex; |
842 // The basic block being built. | 845 // The basic block being built. |
843 Ice::CfgNode *CurrentNode; | 846 Ice::CfgNode *CurrentNode; |
844 // The ID for the function. | 847 // The ID for the function. |
845 unsigned FcnId; | 848 unsigned FcnId; |
846 // The corresponding LLVM function. | 849 // The corresponding LLVM function. |
847 Function *LLVMFunc; | 850 Function *LLVMFunc; |
| 851 // Holds the dividing point between local and global absolute value indices. |
| 852 uint32_t CachedNumGlobalValueIDs; |
848 // Holds operands local to the function block, based on indices | 853 // Holds operands local to the function block, based on indices |
849 // defined in the bitcode file. | 854 // defined in the bitcode file. |
850 std::vector<Ice::Operand *> LocalOperands; | 855 std::vector<Ice::Operand *> LocalOperands; |
851 // Holds the dividing point between local and global absolute value indices. | 856 // Holds the index within LocalOperands corresponding to the next |
852 uint32_t CachedNumGlobalValueIDs; | 857 // instruction that generates a value. |
| 858 uint32_t NextLocalInstIndex; |
853 // True if the last processed instruction was a terminating | 859 // True if the last processed instruction was a terminating |
854 // instruction. | 860 // instruction. |
855 bool InstIsTerminating; | 861 bool InstIsTerminating; |
856 // Upper limit of alignment power allowed by LLVM | 862 // Upper limit of alignment power allowed by LLVM |
857 static const uint64_t AlignPowerLimit = 29; | 863 static const uint64_t AlignPowerLimit = 29; |
858 | 864 |
859 // Extracts the corresponding Alignment to use, given the AlignPower | 865 // Extracts the corresponding Alignment to use, given the AlignPower |
860 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the | 866 // (i.e. 2**AlignPower, or 0 if AlignPower == 0). InstName is the |
861 // name of the instruction the alignment appears in. | 867 // name of the instruction the alignment appears in. |
862 void extractAlignment(const char *InstName, uint64_t AlignPower, | 868 void extractAlignment(const char *InstName, uint64_t AlignPower, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 // the branch references the entry block, it also generates a | 909 // the branch references the entry block, it also generates a |
904 // corresponding error. | 910 // corresponding error. |
905 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { | 911 Ice::CfgNode *getBranchBasicBlock(uint32_t Index) { |
906 if (Index == 0) { | 912 if (Index == 0) { |
907 Error("Branch to entry block not allowed"); | 913 Error("Branch to entry block not allowed"); |
908 // TODO(kschimpf) Remove error recovery once implementation complete. | 914 // TODO(kschimpf) Remove error recovery once implementation complete. |
909 } | 915 } |
910 return getBasicBlock(Index); | 916 return getBasicBlock(Index); |
911 } | 917 } |
912 | 918 |
913 // Generates the next available local variable using the given type. | 919 // Generate an instruction variable with type Ty. |
914 Ice::Variable *getNextInstVar(Ice::Type Ty) { | 920 Ice::Variable *createInstVar(Ice::Type Ty) { |
915 if (Ty == Ice::IceType_void) { | 921 if (Ty == Ice::IceType_void) { |
916 Error("Can't define instruction value using type void"); | 922 Error("Can't define instruction value using type void"); |
917 // Recover since we can't throw an exception. | 923 // Recover since we can't throw an exception. |
918 Ty = Ice::IceType_i32; | 924 Ty = Ice::IceType_i32; |
919 } | 925 } |
920 Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode); | 926 return Func->makeVariable(Ty, CurrentNode); |
921 LocalOperands.push_back(Var); | 927 } |
| 928 |
| 929 // Generates the next available local variable using the given type. |
| 930 Ice::Variable *getNextInstVar(Ice::Type Ty) { |
| 931 assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); |
| 932 // Before creating one, see if a forwardtyperef has already defined it. |
| 933 uint32_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; |
| 934 if (LocalIndex < LocalOperands.size()) { |
| 935 Ice::Operand *Op = LocalOperands[LocalIndex]; |
| 936 if (Op != NULL) { |
| 937 if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) { |
| 938 if (Var->getType() == Ty) { |
| 939 ++NextLocalInstIndex; |
| 940 return Var; |
| 941 } |
| 942 } |
| 943 std::string Buffer; |
| 944 raw_string_ostream StrBuf(Buffer); |
| 945 StrBuf << "Illegal forward referenced instruction (" |
| 946 << NextLocalInstIndex << "): " << *Op; |
| 947 Error(StrBuf.str()); |
| 948 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 949 ++NextLocalInstIndex; |
| 950 return createInstVar(Ty); |
| 951 } |
| 952 } |
| 953 Ice::Variable *Var = createInstVar(Ty); |
| 954 setOperand(NextLocalInstIndex++, Var); |
922 return Var; | 955 return Var; |
923 } | 956 } |
924 | 957 |
925 // Converts a relative index (wrt to BaseIndex) to an absolute value | 958 // Converts a relative index (wrt to BaseIndex) to an absolute value |
926 // index. | 959 // index. |
927 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) { | 960 uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) { |
928 if (BaseIndex < Id) { | 961 if (BaseIndex < Id) { |
929 std::string Buffer; | 962 std::string Buffer; |
930 raw_string_ostream StrBuf(Buffer); | 963 raw_string_ostream StrBuf(Buffer); |
931 StrBuf << "Invalid relative value id: " << Id | 964 StrBuf << "Invalid relative value id: " << Id |
932 << " (must be <= " << BaseIndex << ")"; | 965 << " (must be <= " << BaseIndex << ")"; |
933 Error(StrBuf.str()); | 966 Error(StrBuf.str()); |
934 // TODO(kschimpf) Remove error recovery once implementation complete. | 967 // TODO(kschimpf) Remove error recovery once implementation complete. |
935 return 0; | 968 return 0; |
936 } | 969 } |
937 return BaseIndex - Id; | 970 return BaseIndex - Id; |
938 } | 971 } |
939 | 972 |
940 // Returns the value referenced by the given value Index. | 973 // Returns the value referenced by the given value Index. |
941 Ice::Operand *getOperand(uint32_t Index) { | 974 Ice::Operand *getOperand(uint32_t Index) { |
942 if (Index < CachedNumGlobalValueIDs) { | 975 if (Index < CachedNumGlobalValueIDs) { |
943 // TODO(kschimpf): Define implementation. | 976 // TODO(kschimpf): Define implementation. |
944 report_fatal_error("getOperand of global addresses not implemented"); | 977 report_fatal_error("getOperand of global addresses not implemented"); |
945 } | 978 } |
946 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 979 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
947 if (LocalIndex >= LocalOperands.size()) { | 980 if (LocalIndex >= LocalOperands.size()) { |
948 std::string Buffer; | 981 std::string Buffer; |
949 raw_string_ostream StrBuf(Buffer); | 982 raw_string_ostream StrBuf(Buffer); |
950 StrBuf << "Value index " << Index << " out of range. Must be less than " | 983 StrBuf << "Value index " << Index << " not defined!"; |
951 << (LocalOperands.size() + CachedNumGlobalValueIDs); | |
952 Error(StrBuf.str()); | 984 Error(StrBuf.str()); |
953 report_fatal_error("Unable to continue"); | 985 report_fatal_error("Unable to continue"); |
954 } | 986 } |
955 return LocalOperands[LocalIndex]; | 987 Ice::Operand *Op = LocalOperands[LocalIndex]; |
| 988 if (Op == NULL) { |
| 989 std::string Buffer; |
| 990 raw_string_ostream StrBuf(Buffer); |
| 991 StrBuf << "Value index " << Index << " not defined!"; |
| 992 Error(StrBuf.str()); |
| 993 report_fatal_error("Unable to continue"); |
| 994 } |
| 995 return Op; |
| 996 } |
| 997 |
| 998 // Sets element Index (in the local operands list) to Op. |
| 999 void setOperand(uint32_t Index, Ice::Operand *Op) { |
| 1000 assert(Op); |
| 1001 // Check if simple push works. |
| 1002 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
| 1003 if (LocalIndex == LocalOperands.size()) { |
| 1004 LocalOperands.push_back(Op); |
| 1005 return; |
| 1006 } |
| 1007 |
| 1008 // Must be forward reference, expand vector to accommodate. |
| 1009 if (LocalIndex >= LocalOperands.size()) |
| 1010 LocalOperands.resize(LocalIndex+1); |
| 1011 |
| 1012 // If element not defined, set it. |
| 1013 Ice::Operand *OldOp = LocalOperands[LocalIndex]; |
| 1014 if (OldOp == NULL) { |
| 1015 LocalOperands[LocalIndex] = Op; |
| 1016 return; |
| 1017 } |
| 1018 |
| 1019 // See if forward reference matches. |
| 1020 if (OldOp == Op) |
| 1021 return; |
| 1022 |
| 1023 // Error has occurred. |
| 1024 std::string Buffer; |
| 1025 raw_string_ostream StrBuf(Buffer); |
| 1026 StrBuf << "Multiple definitions for index " << Index |
| 1027 << ": " << *Op << " and " << *OldOp; |
| 1028 Error(StrBuf.str()); |
| 1029 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1030 LocalOperands[LocalIndex] = Op; |
956 } | 1031 } |
957 | 1032 |
958 // Returns the relative operand (wrt to BaseIndex) referenced by | 1033 // Returns the relative operand (wrt to BaseIndex) referenced by |
959 // the given value Index. | 1034 // the given value Index. |
960 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { | 1035 Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) { |
961 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); | 1036 return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); |
962 } | 1037 } |
963 | 1038 |
964 // Returns the absolute index of the next value generating instruction. | 1039 // Returns the absolute index of the next value generating instruction. |
965 uint32_t getNextInstIndex() const { | 1040 uint32_t getNextInstIndex() const { |
966 return CachedNumGlobalValueIDs + LocalOperands.size(); | 1041 return NextLocalInstIndex; |
967 } | 1042 } |
968 | 1043 |
969 // Generates type error message for binary operator Op | 1044 // Generates type error message for binary operator Op |
970 // operating on Type OpTy. | 1045 // operating on Type OpTy. |
971 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); | 1046 void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); |
972 | 1047 |
973 // Validates if integer logical Op, for type OpTy, is valid. | 1048 // Validates if integer logical Op, for type OpTy, is valid. |
974 // Returns true if valid. Otherwise generates error message and | 1049 // Returns true if valid. Otherwise generates error message and |
975 // returns false. | 1050 // returns false. |
976 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { | 1051 bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 return; | 1770 return; |
1696 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 1771 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
1697 unsigned Alignment; | 1772 unsigned Alignment; |
1698 extractAlignment("Store", Values[2], Alignment); | 1773 extractAlignment("Store", Values[2], Alignment); |
1699 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 1774 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
1700 return; | 1775 return; |
1701 CurrentNode->appendInst( | 1776 CurrentNode->appendInst( |
1702 Ice::InstStore::create(Func, Value, Address, Alignment)); | 1777 Ice::InstStore::create(Func, Value, Address, Alignment)); |
1703 break; | 1778 break; |
1704 } | 1779 } |
| 1780 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
| 1781 // FORWARDTYPEREF: [opval, ty] |
| 1782 if (!isValidRecordSize(2, "function block forward type ref")) |
| 1783 return; |
| 1784 setOperand(Values[0], createInstVar( |
| 1785 Context->convertToIceType(Context->getTypeByID(Values[1])))); |
| 1786 break; |
| 1787 } |
1705 case naclbitc::FUNC_CODE_INST_SWITCH: | 1788 case naclbitc::FUNC_CODE_INST_SWITCH: |
1706 case naclbitc::FUNC_CODE_INST_CALL: | 1789 case naclbitc::FUNC_CODE_INST_CALL: |
1707 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: | 1790 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: |
1708 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: | |
1709 default: | 1791 default: |
1710 // Generate error message! | 1792 // Generate error message! |
1711 BlockParserBaseClass::ProcessRecord(); | 1793 BlockParserBaseClass::ProcessRecord(); |
1712 break; | 1794 break; |
1713 } | 1795 } |
1714 } | 1796 } |
1715 | 1797 |
1716 /// Parses constants within a function block. | 1798 /// Parses constants within a function block. |
1717 class ConstantsParser : public BlockParserBaseClass { | 1799 class ConstantsParser : public BlockParserBaseClass { |
1718 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; | 1800 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 if (TopLevelBlocks != 1) { | 2185 if (TopLevelBlocks != 1) { |
2104 errs() << IRFilename | 2186 errs() << IRFilename |
2105 << ": Contains more than one module. Found: " << TopLevelBlocks | 2187 << ": Contains more than one module. Found: " << TopLevelBlocks |
2106 << "\n"; | 2188 << "\n"; |
2107 ErrorStatus = true; | 2189 ErrorStatus = true; |
2108 } | 2190 } |
2109 return; | 2191 return; |
2110 } | 2192 } |
2111 | 2193 |
2112 } // end of namespace Ice | 2194 } // end of namespace Ice |
OLD | NEW |