| 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 |