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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 TopLevelParser(Ice::Translator &Translator, const std::string &InputName, | 56 TopLevelParser(Ice::Translator &Translator, const std::string &InputName, |
57 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor, | 57 NaClBitcodeHeader &Header, NaClBitstreamCursor &Cursor, |
58 bool &ErrorStatus) | 58 bool &ErrorStatus) |
59 : NaClBitcodeParser(Cursor), Translator(Translator), | 59 : NaClBitcodeParser(Cursor), Translator(Translator), |
60 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout), | 60 Mod(new Module(InputName, getGlobalContext())), DL(PNaClDataLayout), |
61 Header(Header), TypeConverter(getLLVMContext()), | 61 Header(Header), TypeConverter(getLLVMContext()), |
62 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0), | 62 ErrorStatus(ErrorStatus), NumErrors(0), NumFunctionIds(0), |
63 NumFunctionBlocks(0), | 63 NumFunctionBlocks(0), |
64 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) { | 64 GlobalVarPlaceHolderType(convertToLLVMType(Ice::IceType_i8)) { |
65 Mod->setDataLayout(PNaClDataLayout); | 65 Mod->setDataLayout(PNaClDataLayout); |
| 66 setErrStream(Translator.getContext()->getStrDump()); |
66 } | 67 } |
67 | 68 |
68 virtual ~TopLevelParser() {} | 69 virtual ~TopLevelParser() {} |
69 LLVM_OVERRIDE; | 70 LLVM_OVERRIDE; |
70 | 71 |
71 Ice::Translator &getTranslator() { return Translator; } | 72 Ice::Translator &getTranslator() { return Translator; } |
72 | 73 |
73 // Generates error with given Message. Always returns true. | 74 // Generates error with given Message. Always returns true. |
74 virtual bool Error(const std::string &Message) LLVM_OVERRIDE { | 75 virtual bool Error(const std::string &Message) LLVM_OVERRIDE { |
75 ErrorStatus = true; | 76 ErrorStatus = true; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 return DefiningFunctionsList[NumFunctionBlocks++]; | 140 return DefiningFunctionsList[NumFunctionBlocks++]; |
140 } | 141 } |
141 | 142 |
142 /// Returns the LLVM IR value associatd with the global value ID. | 143 /// Returns the LLVM IR value associatd with the global value ID. |
143 Value *getGlobalValueByID(unsigned ID) const { | 144 Value *getGlobalValueByID(unsigned ID) const { |
144 if (ID >= ValueIDValues.size()) | 145 if (ID >= ValueIDValues.size()) |
145 return NULL; | 146 return NULL; |
146 return ValueIDValues[ID]; | 147 return ValueIDValues[ID]; |
147 } | 148 } |
148 | 149 |
| 150 /// Returns the corresponding constant associated with a global value |
| 151 /// (i.e. relocatable). |
| 152 Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) { |
| 153 // TODO(kschimpf): Can this be built when creating global initializers? |
| 154 if (ID >= ValueIDConstants.size()) { |
| 155 if (ID >= ValueIDValues.size()) |
| 156 return NULL; |
| 157 ValueIDConstants.resize(ValueIDValues.size()); |
| 158 } |
| 159 Ice::Constant *C = ValueIDConstants[ID]; |
| 160 if (C != NULL) |
| 161 return C; |
| 162 Value *V = ValueIDValues[ID]; |
| 163 assert(isa<GlobalValue>(V)); |
| 164 C = getTranslator().getContext()->getConstantSym(getIcePointerType(), 0, |
| 165 V->getName()); |
| 166 ValueIDConstants[ID] = C; |
| 167 return C; |
| 168 } |
| 169 |
149 /// Returns the number of function addresses (i.e. ID's) defined in | 170 /// Returns the number of function addresses (i.e. ID's) defined in |
150 /// the bitcode file. | 171 /// the bitcode file. |
151 unsigned getNumFunctionIDs() const { return NumFunctionIds; } | 172 unsigned getNumFunctionIDs() const { return NumFunctionIds; } |
152 | 173 |
153 /// Returns the number of global values defined in the bitcode | 174 /// Returns the number of global values defined in the bitcode |
154 /// file. | 175 /// file. |
155 unsigned getNumGlobalValueIDs() const { return ValueIDValues.size(); } | 176 unsigned getNumGlobalValueIDs() const { return ValueIDValues.size(); } |
156 | 177 |
157 /// Resizes the list of value IDs to include Count global variable | 178 /// Resizes the list of value IDs to include Count global variable |
158 /// IDs. | 179 /// IDs. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // Converter between LLVM and ICE types. | 261 // Converter between LLVM and ICE types. |
241 Ice::TypeConverter TypeConverter; | 262 Ice::TypeConverter TypeConverter; |
242 // The exit status that should be set to true if an error occurs. | 263 // The exit status that should be set to true if an error occurs. |
243 bool &ErrorStatus; | 264 bool &ErrorStatus; |
244 // The number of errors reported. | 265 // The number of errors reported. |
245 unsigned NumErrors; | 266 unsigned NumErrors; |
246 // The types associated with each type ID. | 267 // The types associated with each type ID. |
247 std::vector<Type *> TypeIDValues; | 268 std::vector<Type *> TypeIDValues; |
248 // The (global) value IDs. | 269 // The (global) value IDs. |
249 std::vector<WeakVH> ValueIDValues; | 270 std::vector<WeakVH> ValueIDValues; |
| 271 // Relocatable constants associated with ValueIDValues. |
| 272 std::vector<Ice::Constant *> ValueIDConstants; |
250 // The number of function IDs. | 273 // The number of function IDs. |
251 unsigned NumFunctionIds; | 274 unsigned NumFunctionIds; |
252 // The number of function blocks (processed so far). | 275 // The number of function blocks (processed so far). |
253 unsigned NumFunctionBlocks; | 276 unsigned NumFunctionBlocks; |
254 // The list of value IDs (in the order found) of defining function | 277 // The list of value IDs (in the order found) of defining function |
255 // addresses. | 278 // addresses. |
256 std::vector<unsigned> DefiningFunctionsList; | 279 std::vector<unsigned> DefiningFunctionsList; |
257 // Cached global variable placeholder type. Used for all forward | 280 // Cached global variable placeholder type. Used for all forward |
258 // references to global variable addresses. | 281 // references to global variable addresses. |
259 Type *GlobalVarPlaceHolderType; | 282 Type *GlobalVarPlaceHolderType; |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 Error(StrBuf.str()); | 989 Error(StrBuf.str()); |
967 // TODO(kschimpf) Remove error recovery once implementation complete. | 990 // TODO(kschimpf) Remove error recovery once implementation complete. |
968 return 0; | 991 return 0; |
969 } | 992 } |
970 return BaseIndex - Id; | 993 return BaseIndex - Id; |
971 } | 994 } |
972 | 995 |
973 // Returns the value referenced by the given value Index. | 996 // Returns the value referenced by the given value Index. |
974 Ice::Operand *getOperand(uint32_t Index) { | 997 Ice::Operand *getOperand(uint32_t Index) { |
975 if (Index < CachedNumGlobalValueIDs) { | 998 if (Index < CachedNumGlobalValueIDs) { |
976 // TODO(kschimpf): Define implementation. | 999 return Context->getOrCreateGlobalConstantByID(Index); |
977 report_fatal_error("getOperand of global addresses not implemented"); | |
978 } | 1000 } |
979 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; | 1001 uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
980 if (LocalIndex >= LocalOperands.size()) { | 1002 if (LocalIndex >= LocalOperands.size()) { |
981 std::string Buffer; | 1003 std::string Buffer; |
982 raw_string_ostream StrBuf(Buffer); | 1004 raw_string_ostream StrBuf(Buffer); |
983 StrBuf << "Value index " << Index << " not defined!"; | 1005 StrBuf << "Value index " << Index << " not defined!"; |
984 Error(StrBuf.str()); | 1006 Error(StrBuf.str()); |
985 report_fatal_error("Unable to continue"); | 1007 report_fatal_error("Unable to continue"); |
986 } | 1008 } |
987 Ice::Operand *Op = LocalOperands[LocalIndex]; | 1009 Ice::Operand *Op = LocalOperands[LocalIndex]; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " | 1138 StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " |
1117 << Alignment; | 1139 << Alignment; |
1118 Error(StrBuf.str()); | 1140 Error(StrBuf.str()); |
1119 return false; | 1141 return false; |
1120 } | 1142 } |
1121 | 1143 |
1122 // Reports that the given binary Opcode, for the given type Ty, | 1144 // Reports that the given binary Opcode, for the given type Ty, |
1123 // is not understood. | 1145 // is not understood. |
1124 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); | 1146 void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty); |
1125 | 1147 |
| 1148 // Returns true if the Str begins with Prefix. |
| 1149 bool isStringPrefix(Ice::IceString &Str, Ice::IceString &Prefix) { |
| 1150 const size_t PrefixSize = Prefix.size(); |
| 1151 if (Str.size() < PrefixSize) |
| 1152 return false; |
| 1153 for (size_t i = 0; i < PrefixSize; ++i) { |
| 1154 if (Str[i] != Prefix[i]) |
| 1155 return false; |
| 1156 } |
| 1157 return true; |
| 1158 } |
| 1159 |
1126 // Takes the PNaCl bitcode binary operator Opcode, and the opcode | 1160 // Takes the PNaCl bitcode binary operator Opcode, and the opcode |
1127 // type Ty, and sets Op to the corresponding ICE binary | 1161 // type Ty, and sets Op to the corresponding ICE binary |
1128 // opcode. Returns true if able to convert, false otherwise. | 1162 // opcode. Returns true if able to convert, false otherwise. |
1129 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, | 1163 bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, |
1130 Ice::InstArithmetic::OpKind &Op) { | 1164 Ice::InstArithmetic::OpKind &Op) { |
1131 Instruction::BinaryOps LLVMOpcode; | 1165 Instruction::BinaryOps LLVMOpcode; |
1132 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty), | 1166 if (!naclbitc::DecodeBinaryOpcode(Opcode, Context->convertToLLVMType(Ty), |
1133 LLVMOpcode)) { | 1167 LLVMOpcode)) { |
1134 ReportInvalidBinopOpcode(Opcode, Ty); | 1168 ReportInvalidBinopOpcode(Opcode, Ty); |
1135 // TODO(kschimpf) Remove error recovery once implementation complete. | 1169 // TODO(kschimpf) Remove error recovery once implementation complete. |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1827 return; | 1861 return; |
1828 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); | 1862 Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); |
1829 unsigned Alignment; | 1863 unsigned Alignment; |
1830 extractAlignment("Store", Values[2], Alignment); | 1864 extractAlignment("Store", Values[2], Alignment); |
1831 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) | 1865 if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
1832 return; | 1866 return; |
1833 CurrentNode->appendInst( | 1867 CurrentNode->appendInst( |
1834 Ice::InstStore::create(Func, Value, Address, Alignment)); | 1868 Ice::InstStore::create(Func, Value, Address, Alignment)); |
1835 break; | 1869 break; |
1836 } | 1870 } |
| 1871 case naclbitc::FUNC_CODE_INST_CALL: |
| 1872 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { |
| 1873 // CALL: [cc, fnid, arg0, arg1...] |
| 1874 // CALL_INDIRECT: [cc, fn, returnty, args...] |
| 1875 // |
| 1876 // Note: The difference between CALL and CALL_INDIRECT is that |
| 1877 // CALL has an explicit function address, while the CALL_INDIRECT |
| 1878 // is just an address. For CALL, we can infer the return type by |
| 1879 // looking up the type signature associated with the function |
| 1880 // address. For CALL_INDIRECT we can only infer the type signature |
| 1881 // via argument types, and the corresponding return type stored in |
| 1882 // CALL_INDIRECT record. |
| 1883 Ice::SizeT ParamsStartIndex = 2; |
| 1884 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
| 1885 if (!isValidRecordSizeAtLeast(2, "function block call")) |
| 1886 return; |
| 1887 } else { |
| 1888 if (!isValidRecordSizeAtLeast(3, "function block call indirect")) |
| 1889 return; |
| 1890 ParamsStartIndex = 3; |
| 1891 } |
| 1892 |
| 1893 // Extract call information. |
| 1894 uint64_t CCInfo = Values[0]; |
| 1895 CallingConv::ID CallingConv; |
| 1896 if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { |
| 1897 std::string Buffer; |
| 1898 raw_string_ostream StrBuf(Buffer); |
| 1899 StrBuf << "Function call calling convention value " << (CCInfo >> 1) |
| 1900 << " not understood."; |
| 1901 Error(StrBuf.str()); |
| 1902 return; |
| 1903 } |
| 1904 bool IsTailCall = static_cast<bool>(CCInfo & 1); |
| 1905 |
| 1906 // Extract out the called function and its return type. |
| 1907 uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); |
| 1908 Ice::Operand *Callee = getOperand(CalleeIndex); |
| 1909 Ice::Type ReturnType = Ice::IceType_void; |
| 1910 const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = NULL; |
| 1911 if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { |
| 1912 Function *Fcn = |
| 1913 dyn_cast<Function>(Context->getGlobalValueByID(CalleeIndex)); |
| 1914 if (Fcn == NULL) { |
| 1915 std::string Buffer; |
| 1916 raw_string_ostream StrBuf(Buffer); |
| 1917 StrBuf << "Function call to non-function: " << *Callee; |
| 1918 Error(StrBuf.str()); |
| 1919 return; |
| 1920 } |
| 1921 |
| 1922 FunctionType *FcnTy = Fcn->getFunctionType(); |
| 1923 ReturnType = Context->convertToIceType(FcnTy->getReturnType()); |
| 1924 |
| 1925 // Check if this direct call is to an Intrinsic (starts with "llvm.") |
| 1926 static Ice::IceString LLVMPrefix("llvm."); |
| 1927 Ice::IceString Name = Fcn->getName(); |
| 1928 if (isStringPrefix(Name, LLVMPrefix)) { |
| 1929 Ice::IceString Suffix = Name.substr(LLVMPrefix.size()); |
| 1930 IntrinsicInfo = |
| 1931 getTranslator().getContext()->getIntrinsicsInfo().find(Suffix); |
| 1932 if (!IntrinsicInfo) { |
| 1933 std::string Buffer; |
| 1934 raw_string_ostream StrBuf(Buffer); |
| 1935 StrBuf << "Invalid PNaCl intrinsic call to " << Name; |
| 1936 Error(StrBuf.str()); |
| 1937 return; |
| 1938 } |
| 1939 } |
| 1940 } else { |
| 1941 ReturnType = Context->convertToIceType(Context->getTypeByID(Values[2])); |
| 1942 } |
| 1943 |
| 1944 // Create the call instruction. |
| 1945 Ice::Variable *Dest = |
| 1946 (ReturnType == Ice::IceType_void) ? NULL : getNextInstVar(ReturnType); |
| 1947 Ice::SizeT NumParams = Values.size() - ParamsStartIndex; |
| 1948 Ice::InstCall *Inst = NULL; |
| 1949 if (IntrinsicInfo) { |
| 1950 Inst = |
| 1951 Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee, |
| 1952 IntrinsicInfo->Info); |
| 1953 } else { |
| 1954 Inst = Ice::InstCall::create(Func, NumParams, Dest, Callee, IsTailCall); |
| 1955 } |
| 1956 |
| 1957 // Add parameters. |
| 1958 for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { |
| 1959 Inst->addArg( |
| 1960 getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex)); |
| 1961 } |
| 1962 |
| 1963 // If intrinsic call, validate call signature. |
| 1964 if (IntrinsicInfo) { |
| 1965 Ice::SizeT ArgIndex = 0; |
| 1966 switch (IntrinsicInfo->validateCall(Inst, ArgIndex)) { |
| 1967 default: |
| 1968 Error("Unknown validation error for intrinsic call"); |
| 1969 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1970 break; |
| 1971 case Ice::Intrinsics::IsValidCall: |
| 1972 break; |
| 1973 case Ice::Intrinsics::BadReturnType: { |
| 1974 std::string Buffer; |
| 1975 raw_string_ostream StrBuf(Buffer); |
| 1976 StrBuf << "Intrinsic call expects return type " |
| 1977 << IntrinsicInfo->getReturnType() |
| 1978 << ". Found: " << Inst->getReturnType(); |
| 1979 Error(StrBuf.str()); |
| 1980 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1981 break; |
| 1982 } |
| 1983 case Ice::Intrinsics::WrongNumOfArgs: { |
| 1984 std::string Buffer; |
| 1985 raw_string_ostream StrBuf(Buffer); |
| 1986 StrBuf << "Intrinsic call expects " << IntrinsicInfo->getNumArgs() |
| 1987 << ". Found: " << Inst->getNumArgs(); |
| 1988 Error(StrBuf.str()); |
| 1989 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1990 break; |
| 1991 } |
| 1992 case Ice::Intrinsics::WrongCallArgType: { |
| 1993 std::string Buffer; |
| 1994 raw_string_ostream StrBuf(Buffer); |
| 1995 StrBuf << "Intrinsic call argument " << ArgIndex << " expects type " |
| 1996 << IntrinsicInfo->getArgType(ArgIndex) |
| 1997 << ". Found: " << Inst->getArg(ArgIndex)->getType(); |
| 1998 Error(StrBuf.str()); |
| 1999 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 2000 break; |
| 2001 } |
| 2002 } |
| 2003 } |
| 2004 |
| 2005 CurrentNode->appendInst(Inst); |
| 2006 return; |
| 2007 } |
1837 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { | 2008 case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { |
1838 // FORWARDTYPEREF: [opval, ty] | 2009 // FORWARDTYPEREF: [opval, ty] |
1839 if (!isValidRecordSize(2, "function block forward type ref")) | 2010 if (!isValidRecordSize(2, "function block forward type ref")) |
1840 return; | 2011 return; |
1841 setOperand(Values[0], createInstVar(Context->convertToIceType( | 2012 setOperand(Values[0], createInstVar(Context->convertToIceType( |
1842 Context->getTypeByID(Values[1])))); | 2013 Context->getTypeByID(Values[1])))); |
1843 break; | 2014 break; |
1844 } | 2015 } |
1845 case naclbitc::FUNC_CODE_INST_CALL: | |
1846 case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: | |
1847 default: | 2016 default: |
1848 // Generate error message! | 2017 // Generate error message! |
1849 BlockParserBaseClass::ProcessRecord(); | 2018 BlockParserBaseClass::ProcessRecord(); |
1850 break; | 2019 break; |
1851 } | 2020 } |
1852 } | 2021 } |
1853 | 2022 |
1854 /// Parses constants within a function block. | 2023 /// Parses constants within a function block. |
1855 class ConstantsParser : public BlockParserBaseClass { | 2024 class ConstantsParser : public BlockParserBaseClass { |
1856 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; | 2025 ConstantsParser(const ConstantsParser &) LLVM_DELETED_FUNCTION; |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2243 | 2412 |
2244 if (TopLevelBlocks != 1) { | 2413 if (TopLevelBlocks != 1) { |
2245 errs() << IRFilename | 2414 errs() << IRFilename |
2246 << ": Contains more than one module. Found: " << TopLevelBlocks | 2415 << ": Contains more than one module. Found: " << TopLevelBlocks |
2247 << "\n"; | 2416 << "\n"; |
2248 ErrorStatus = true; | 2417 ErrorStatus = true; |
2249 } | 2418 } |
2250 } | 2419 } |
2251 | 2420 |
2252 } // end of namespace Ice | 2421 } // end of namespace Ice |
OLD | NEW |