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 | |
jvoung (off chromium)
2014/09/18 23:43:53
funtion -> function
Karl
2014/09/19 20:29:52
Done.
| |
1877 // is just an address. For CALL, we can infer the return type by | |
1878 // looking up the type signature associated with the funtion | |
jvoung (off chromium)
2014/09/18 23:43:53
funtion -> function
Karl
2014/09/19 20:29:52
Done.
| |
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; | |
jvoung (off chromium)
2014/09/18 23:43:53
PNaCL -> PNaCl
Karl
2014/09/19 20:29:52
Done.
| |
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, | |
jvoung (off chromium)
2014/09/18 23:43:53
"Values.size() - ParamsStartIndex" is the same as
Karl
2014/09/19 20:29:52
Done.
| |
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 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2243 | 2411 |
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 } | 2418 } |
2251 | 2419 |
2252 } // end of namespace Ice | 2420 } // end of namespace Ice |
OLD | NEW |