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